Docker compose fail to start container in monorepo environment - docker

I have a PNPM workspace environment. I try to build one of my package using docker compose.
To do so, I have the following script in package.json file (in root folder):
"cluster:start": "pnpm exec ./docker/scripts/start-cluster.sh"
This is the ./docker/scripts/start-cluster.sh file:
#!/bin/bash
docker-compose up -d
This is my docker-compose.yaml file:
version: '3.8'
services:
frontend:
container_name: frontend
build:
context: ./docker
dockerfile: Dockerfile.frontend-dev
env_file:
- ./apps/frontend/.env.development
ports:
- 8080:8080
restart: always
networks:
- dashboard_network
networks:
dashboard_network:
driver: bridge
And this is my ./docker/Dockerfile.frontend-dev file:
FROM node:16
RUN curl -f https://get.pnpm.io/v6.16.js | node - add --global pnpm
WORKDIR /dashboard
COPY ../package.json ./
COPY ../apps/frontend/package.json ./apps/frontend/
RUN pnpm install
COPY ../ ./
CMD ["pnpm", "--filter", "frontend", "start"]
So when I run on root folder pnpm cluster:start I get an error:
=> ERROR [dashboard-frontend 4/7] COPY ../package.json ./ 0.0s
=> ERROR [dashboard-frontend 5/7] COPY ../apps/frontend/package.json ./apps/frontend/ 0.0s
------
> [dashboard-frontend 4/7] COPY ../package.json ./:
------
------
> [dashboard-frontend 5/7] COPY ../apps/frontend/package.json ./apps/frontend/:
------
failed to solve: failed to compute cache key: "/apps/frontend/package.json" not found: not found
Could anyone tell why?
This is the path to this error file: ROOT_FOLDER/apps/frontend/package.json

Short answer to "why": docker context.
This command is wrong:
COPY ../package.json ./
You cannot get "out" of the docker build context.
In your docker-compose.yml you define a context. That is a folder. When the build starts, the contents of that folder (with exceptions defined in .dockerignore) are sent to the docker daemon. And that is the set of file that your COPY commands can see. Nothing else. So the COPY does not work in your current folder, but on a copy of that folder that was sent to the docker daemon.

Related

Dockerfile permission for volume

FROM --platform=$BUILDPLATFORM maven:3.8.5-eclipse-temurin-17 AS builder
WORKDIR /server
COPY pom.xml /server/pom.xml
RUN mvn dependency:go-offline
COPY src /server/src
RUN mvn install
# install Docker tools (cli, buildx, compose)
COPY --from=gloursdocker/docker / /
CMD ["mvn", "spring-boot:run"]
FROM builder as prepare-production
RUN mkdir -p target/dependency
WORKDIR /server/target/dependency
RUN jar -xf ../*.jar
FROM eclipse-temurin:17-jre-focal
EXPOSE 8080
VOLUME /app
ARG DEPENDENCY=/server/target/dependency
COPY --from=prepare-production ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=prepare-production ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=prepare-production ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.server.backend.BackendApplicaiton"]
and I need to save the files in /app to the /opt/containers/backend directory (absolute). Code bellow is my docker compose file.
version: "3.9"
services:
backend:
container_name: "backend"
build: backend
environment:
- ${MSSQL_PASSWORD}
ports:
- 3000:8080
volumes:
- /opt/containers/backend:/app
networks:
- backend
networks:
backend:
name: backend
driver: bridge
internal: false
if I run this and create volume in docker, everything works, files are saved inside docker volume, but when I set absolute path as in the docker compose file, directory is empty and app does not run. I am sure the error is in permissions, but I cant figured it out where and I could not find any solutions :(
Thank you for all your replies and help.

Docker: Shared volume when build

I have this files:
docker-compose.yml (shortened):
version: '3.7'
services:
php-fpm:
build:
context: .
dockerfile: docker/php/Dockerfile
target: dev
volumes:
- .:/app
frontend:
build:
context: .
dockerfile: docker/php/Dockerfile
target: frontend
volumes:
- .:/app
docker/php/Dockerfile (shortened):
FROM alpine:3.13 AS frontend
WORKDIR /app
COPY . .
RUN apk add npm
RUN npm install
RUN npx webpack -p --color --progress
FROM php:7.4-fpm AS dev
ENTRYPOINT ["docker-php-entrypoint"]
WORKDIR /app
COPY ./docker/php/www-dev.conf /usr/local/etc/php-fpm.d/www.conf
CMD ["php-fpm"]
I want to use all what building in frontend (as I understood at the stage build at this time volumes are not available) in php-fpm container, but I get something like this: file_get_contents(/app/static/frontend.version): failed to open stream.
How I can do this? I don't understand very well in Docker and the only solution I have is to move build script to php-fpm container.
You need to delete the volumes: in your docker-compose.yml file. They replace the entire contents of the image's /app directory with content from the host, which means everything that gets done in the Dockerfile gets completely ignored.
The Dockerfile you show uses a setup called a multi-stage build. The important thing you can do with this is build the first part of your image using Node, then COPY --from=frontend the static files into the second part. You do not need to declare a second container in docker-compose.yml to run the first stage, the build sequence runs this automatically. This at a minimum looks like
COPY --from=frontend /app/build ./static
You will also need to COPY the rest of your application code into the image.
If you move the Dockerfile up to the top of your project's source tree, then the docker-compose.yml file becomes as simple as
version: '3.8'
services:
php-fpm:
build: . # default Dockerfile, default target (last stage)
# do not overwrite application code with volumes:
# no separate frontend: container
But you've put a little bit more logic in the Dockerfile. I might write:
FROM node:lts AS frontend # use a prebuilt Node image
WORKDIR /app
COPY package*.json . # install dependencies first to save time on rebuild
RUN npm install
COPY . . # (or a more specific subdirectory?)
RUN npx webpack -p --color --progress
FROM php:7.4-fpm AS dev
WORKDIR /app
COPY . . # (or a more specific subdirectory?)
COPY --from=frontend /app/build ./static
COPY ./docker/php/www-dev.conf /usr/local/etc/php-fpm.d/www.conf
# don't need to repeat unmodified ENTRYPOINT/CMD from base image

Docker error can't copy a file after build it

I'm trying to copy my ./dist after building my angular app.
here is my Dockerfile
# Create image based off of the official Node 10 image
FROM node:12-alpine
RUN apk update && apk add --no-cache make git
RUN mkdir -p /home/project/frontend
# Change directory so that our commands run inside this new directory
WORKDIR /home/project/frontend
# Copy dependency definitions
COPY package*.json ./
RUN npm cache verify
## installing packages
RUN npm install
COPY ./ ./
RUN npm run build --output-path=./dist
COPY /dist /var/www/front
but when I run docker-compose build dashboard I get this error
Service 'dashboard' failed to build: COPY failed: stat /var/lib/docker/tmp/docker-builderxxx/dist: no such file or directory
I don't know why is there something wrong?
if you need to check also docker-compose file
...
dashboard:
container_name: dashboard
build: ./frontend
image: dashboard
container_name: dashboard
restart: unless-stopped
networks:
- app-network
...
The Dockerfile COPY directive copies content from the build context (the host-system directory in the build: line) into the image. If you're just trying to move around content within the image, you can RUN cp or RUN mv to use the ordinary Linux shell commands instead.
RUN npm run build --output-path=./dist \
&& cp -a dist /var/www/front

Docker Compose build command using Cache and not picking up changed files while copying to docker

I have a docker-compose.yml file comprising of two services (both based on a DockerFile). I have build the images once (using command: docker-compose build) and they were up and running once I ran this command (docker-compose up).
I had to change the source code used for one of the services, however, when I rebuilt the images (docker-compose build), the code changes were not reflected once I ran the services (docker-compose up).
docker-compose.yml
version: '2'
services:
serviceOne:
build:
context: ./ServerOne
args:
PORT: 4000
ports:
- "4000:4000"
env_file:
- ./ServerOne/.env
environment:
- PORT=4000
serviceTwo:
build:
context: ./serviceTwo
args:
PORT: 3000
ports:
- "3000:3000"
env_file:
- ./serviceTwo/.env
environment:
- PORT=3000
- serviceOne_URL=http://serviceOne:4000/
depends_on:
- serviceOne
serviceOne/DockerFile
FROM node:8.10.0
RUN mkdir -p /app
WORKDIR /app
ADD package.json package-lock.json /app/
RUN npm install
COPY . /app/
RUN npm build
EXPOSE ${ACC_PORT}
CMD [ "npm", "start" ]
serviceTwo/DockerFile
FROM node:8.10.0
RUN mkdir -p /app
WORKDIR /app
ADD package.json package-lock.json /app/
RUN npm install
COPY . /app/
RUN npm build
EXPOSE ${ACC_PORT}
CMD [ "npm", "start" ]
Following is the output of the docker-compose when it is ran for the second time.
It is some how using the cached images again when COPY and npm build command are ran.
How could the DockerFile or docker-compose file be changed so that the new source code is deployed?
You can force the build to ignore the cache by adding on the --no-cache option to the docker-compose build

"No Go files in..." error when i use go with docker compose

I installed Go on Ubuntu 16.04. This is my GOPATH=/home/{username}/work.
I created a project into /home/{username}/work/src.
This is my project folder hierarchy.
project-name
services
configuration
api
main.go
Dockerfile
bff
api
main.go
Dockerfile
docker-compose.yml
favicon.ico
README.md
I can build and run with my dockerfile but I can't build and up with docker-compose.
I couldn't find any solution.
Configuration service dockerfile:
FROM golang:1.11.1-alpine3.8 as builder
RUN apk update && apk add git && go get gopkg.in/natefinch/lumberjack.v2
RUN mkdir -p /go/src/project-name/services/configuration
RUN CGO_ENABLED=0
RUN GOOS=linux
ADD . /go/src/project-name/services/configuration
ENV GOPATH /go
WORKDIR /go/src/project-name/services/configuration/api
RUN go get
RUN go build
FROM alpine
RUN apk update
RUN apk add curl
RUN mkdir -p /app
COPY --from=builder /go/src/project-name/services/configuration/api/ /app/
RUN chmod +x /app/api
WORKDIR /app
EXPOSE 5001
ENTRYPOINT ["/app/api"]
It works with dockerfile.
This is my docker-compose file:
version: '3.4'
services:
bff:
image: project-name/bff:${TAG:-latest}
build:
context: .
dockerfile: services/bff/Dockerfile
ports:
- "5000:5000"
container_name: bff
depends_on:
- configuration
configuration:
image: project-name/configuration:${TAG:-latest}
build:
context: .
dockerfile: services/configuration/Dockerfile
ports:
- "5001:5001"
container_name: configuration
It didn't work.
When the “run go get” command runs, it gives an error, the error is:
can't load package: package project-name/services/configuration/api: no Go files in /go/src/project-name/services/configuration/api
ERROR: Service 'configuration' failed to build: The command '/bin/sh -c go get' returned a non-zero code: 1
In your Dockerfile, you say
ADD . /go/src/project-name/services/configuration
which expects the build context directory on the host to contain the source files. But your docker-compose.yml file says
build:
context: .
dockerfile: services/configuration/Dockerfile
where the context directory is the root of your source control tree, not the specific Go source directory you're trying to build. If you change this to
build:
context: services/configuration
# Default value of "dockerfile: Dockerfile" will be right
it will likely work better.
In plain Docker commands, your current docker-compose.yml file says the equivalent of
cd $GOPATH/src/project-name
docker build -f services/configuration/Dockerfile .
But you're probably actually running
cd $GOPATH/src/project-name/services/configuration
docker build .
and what directory is the current directory matters.

Resources