By utilizing container technology like Docker, we can have an identical environment for development and production. But, working in a development environment requires us to be able to change the source codes directly. We can define multi-stage procedures in the Dockerfile and specific commands to run the container. For example, we have a Node.js program that will be shipped using a container.
1. Create a Dockerfile with stages for development and production.
# syntax=docker/dockerfile:1
FROM node:14.17.1 as base
WORKDIR /app
COPY ["package.json", "package-lock.json", "./"]
FROM base as development
ENV NODE_ENV=development
RUN npm ci
COPY . .
CMD ["nodemon", "-L", "app.js"]
FROM base as production
ENV NODE_ENV=production
RUN npm ci --production
COPY . .
CMD ["node", "app.js"]
In this example, the program for development is run using nodemon therefore we need to install nodemon first by npm i -D nodemon
command in our development host and run it using legacy mode (-L) in the development container to prevent failure.
2. Create a .dockerignore
file for ignoring the node_modules
directory.
3. For development, run the following command.
docker build -t my-app:development --target development .
docker run -it -v "$(PWD):/app" --mount type=volume,dst=/app/node_modules my-app:development
For running the container, we specify volume-mounting for the node_modules
directory. It is required because the directory may contain files/binaries that are unique for different platforms. So, its contents shouldn't be synced with the host contents by bind-mounting. While the root directory of the project use bind-mounting that makes all changes in source code is directly applied in the container and captured by the nodemon instance.
4. For production, run the following command.
docker build -t my-app:production --target production .
docker login <yourRegistryHost>
docker tag my-app:production <yourRegistryHost>/my-app:production
docker push <yourRegistryHost>/my-app:production
Then, run the following command in the production host.
docker run -d <yourRegistryHost>/my-app:production
Comments
Post a Comment