Dockerfile is set of some instruction which helps to create custom image which Docker is going to run. To create a Dockerfile, write below 7 mentioned commands in Dockerfile.
-
Docker image of basic dependencies from docker-hub, here node@17 used to setup
FROM node:17
-
Working/project directory relative (or absolute) path inside container, will be created if it does not exist
WORKDIR /app
-
Will copy package.json to project directory, it can be "." or /app
COPY package.json /app
-
Run below command, it will install all dependencies mentioned in package.json
*Use only one of them as per requirement.
RUN npm install --only=production
--only=production
: used to avoid dev dependencies in production mode
- Or,
ARG NODE_ENV RUN if [ "$NODE_ENV" = "development" ]; \ then npm install; \ else npm install --only=production; \ fi
- Also define *ARG
NODE_ENV
in docker-compose.yml file build block as:
express-app build: context: . args: NODE_ENV: development
- Also define *ARG
-
Copy everything from local codebase project directory to container project directory
COPY . ./
*NOTE: Above mentioned all 5 steps mandotory to create each layer image in a container as final one
-
Set Enviroment variable
ENV PORT 5000
-
Exposing 5001 for external traffic by docker container to be used
EXPOSE 5001
-
Command to be run on CMD when container up (with space in a list), could be changed based on environment, its recommended to avoid running npm and only run node and app.js file in production
CMD ["npm", "run", "dev"]
docker build .
-> to build image from Dockerfile, where .
is location for Dockerfile
docker build -t image-name .
-> to build image with image-name
docker image ls
-> list all images
docker ps
-> list all running container
docker ps -a
-> list all stop/running container
docker logs container-name -f
-> to see server logs, -f
for tail mode
printenv
-> print ENV variable in container CLI
docker rm container-name -vf
-> to kill docker app container, -v for volumes also, -f for forcefully removal
docker exec -it container-name bash
-> login to container CLI with interactive mode with -it argument in bash
Run built image with docker
docker run -p 5000:5000 -d --name container-name container-image-name
-d
: used to detached execution from CLI-p
: used to specify external:internal port number for traffic handling--name
: to specify app/container name run with image-name--env-file
: path to env file, eg. for this ./.env
*Tips: In dev mode, Sync with local code into container in real-time with above command using
-v pathToFolderOnLocal:pathToFolderOnContainer
flag while running/starting image
$(pwd)
can be used for current directory shortcut of local machine, for eg.
docker run -v $(pwd):/app --env-file ./.env -p 5001:5000 -d --name express-app express-app-image
It builds image from Dockerfile and start container in one-go. Only docker-compose
command needed as mentioned above, &its little dumb too
To know more about docker-compose.yml variables for diferrent services, look into docker documentation.
docker-compose up -d --build
-> to build image and run, --build force to rebuild
docker-compose down -v
-> stop docker-compose container and also delete its volumes (don't use -v
incase of Database to keep data persistent)
docker inspect container-name
-> more detail information about container
docker network ls
-> List all network of containers
docker-compose up -d app_name
-> build and start container for specific app_name
- after 2nd image building, it cache steps
- By default it talks to external network. but closed to communicate with internal server
- 1st kill & restart container to reflect changes except above 1st 5 command values in dockerfile
.dockerignore
file works like.gitignore
- Find more details of container like state, NetworkSettings, etc with
inspect
command. - Mention
volumes
in docker-compose.yml to keep data/file consistent between local and container environment. - Different container can talk to each other with thier service_name also (or with ip address), for eg. mongo. It means communication between container can be done with their service_name as ip_address.