I have got main docker-compose file like that:
services:
main:
container_name: main
build:
dockerfile: Dockerfile
context: './backend/'
ports:
- '${APP_PORT}:3000'
volumes:
- './backend/src:/backend/src'
depends_on:
- mongo
mongo:
container_name: mongodb
image: mongo
ports:
- '27017:27017'
environment:
...
volumes:
- mongo-data:/data/db
volumes:
mongo-data:
/backend/Dockerfile (root NestJS folder):
FROM node:14
WORKDIR /backend
COPY package*.json ./
RUN npm install
COPY src/ tsconfig*.json ./
CMD ["npm", "run", "start:dev"]
As you can see, there is only src folder in my container, which is good and intended. However, I would like to create a separate container only for testing my application, so instead of just the "src" folder I have to include the "tests" folder as well (or only tests folder and use src folder of this container?). Apart from that, I would also like to run the "jest" command to run unit tests contained in folders in the src folder.
I have no idea how to do this. Can I share folders through multiple containers or something like that?
One way would be to change you Dockerfile to a multi-stage build with a testing stage.
Here I have added a prod and a testing stage as well as your original (dev) build stage.
FROM node:14 as dev
WORKDIR /backend
COPY package*.json ./
RUN npm install
COPY src/ tsconfig*.json ./
CMD ["npm", "run", "start:dev"]
FROM dev as testing
COPY tests ./
ENV CI=true
RUN ["npn", "run", "test"]
FROM dev as prod
LABEL version="1.0" "com.example.image"="My Image"
CMD ["npm", "run", "start"]
The you can specify the build target you want with a variable in your docker-compose-file.
services:
main:
container_name: main
build:
dockerfile: Dockerfile
context: './backend/'
target: ${TARGET:-prod}
ports:
...
TARGET can be set in an .env file or by environment variable. I've set a default value so target becomes prod if not specified.
Other possible solutions would be to have multiple Dockerfiles or use a docker-compose.override.yml file with testing commands specified and different build context included.
Related
I have 1 dockerfile, 1 stage of the build for the node server, serving some data, and the 2nd stage is a react app. I use a docker compose file to run the dockerfile.
I am able to access the react app via port 3000, but the 2nd stage server isn't running so I can't access the data.
Any idea how to solve it?
FROM node:12.6
WORKDIR /usr/src/app
COPY package.json .
COPY . .
EXPOSE 5500 // node server
CMD ["npm","run", "server"]
FROM node:12.6
WORKDIR /usr/src/app
COPY package.json .
RUN npm i
COPY . .
EXPOSE 3000 // react app
CMD ["npm","run", "dev"]
version: "3.9"
services:
testingapp:
container_name: testingApp
build: .
volumes:
- ./src:/app/src:delegated
ports:
- "3000:3000"
I have read various docs online.
You're trying to run the front- and back-ends in the same container. A container only runs one process, though; if you need two separate processes from the same code base then you can run two separate containers off the same image, overriding the command: on one of them.
So reduce the Dockerfile to copy the code base in, and declare one process or the other as the main container command:
FROM node:12.6
WORKDIR /usr/src/app
COPY package.json package-lock.json ./
RUN npm ci
COPY ./ ./
EXPOSE 3000
CMD ["npm", "run", "server"]
Now in your Compose file, declare two separate containers. For the second, override the command: with the alternate program to run. Both can build: the same image; the second build will come entirely from the Docker layer cache and be all but free. The code is built into the image and you don't need to replace it using volumes:.
version: '3.8'
services:
express:
build: .
ports: ['5500:3000']
react:
build: .
command: npm run dev
ports: ['3000:3000']
I'm trying to build a docker which consists of two containers. One for nginx, and another for storybook (UI docs).
My prod.yml file:
version: '3.7'
services:
storybook_container:
image: app_prod_storybook:latest
build:
context: ../
target: builder
dockerfile: Dockerfile
container_name: app_prod_storybook
ports:
- "8080:8080"
storybook_nginx:
image: app_prod_storybook_nginx:latest
build:
context: ../
target: production-build
dockerfile: Dockerfile
container_name: app_prod_storybook_nginx
restart: always
ports:
- "80:80"
depends_on:
- storybook_container
And my Dockerfile:
FROM node:lts-alpine as builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
CMD ["npm", "run", "build-storybook"]
FROM nginx:stable-alpine as production-build
COPY nginx/nginx.conf /etc/nginx/nginx.conf
RUN rm -rf /usr/share/nginx/html/*
COPY --from=builder /usr/src/app/storybook-static /usr/share/nginx/html/docs/storybook-static
EXPOSE 80
ENTRYPOINT ["nginx", "-g", "daemon off;"]
This build only works if I first execute two commands locally:
npm i
npm run storybook build
Otherwise, the /usr/src/app/storybook-static directory does not exist. Although the assembly container fulfills and turns off. Before turning it off, I see the storybook-static directory and it contains all the necessary files.
What am I doing wrong?
I want to build my next js project by docker tool, but I got some trouble like this:
Error: Could not find a production build in the '/var/app/.next' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id
Dockerfile:
FROM node:16-alpine
RUN mkdir -p /var/app
COPY ["./", "/var/app"]
WORKDIR /var/app
RUN npm i -g next
EXPOSE 3002
RUN npm run build
CMD ["npm", "run", "start"]
docker-compose.yml
version: '3.3'
services:
next-project:
container_name: next-project
build: ./
working_dir: /var/app
restart: 'unless-stopped'
volumes:
- ./:/var/app
env_file:
- .env
ports:
- "54000:3002"
I do run commands like this
docker-compose build && docker-compose up -d
the build was successful but when it run is failed, is there any missing configuration?
When you map your current directory to /var/app, all the files that are in that directory in the container become hidden and replaced with the files in the current directory.
Since you don't have a .next directory in the host directory, the container can't find the built files.
To get it to run, you need to remove the mapping of the current directory, so your docker-compose file becomes
version: '3.3'
services:
next-project:
container_name: next-project
build: ./
working_dir: /var/app
restart: 'unless-stopped'
env_file:
- .env
ports:
- "54000:3002"
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
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