FROM node:latest
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
docker build -t myapp:1.0 .
. at the end specifies current directory
-t or --tag option allows us to name and tag the image in name:tag format
Note, that if you don't provide a tag it will be defaulted to latest, which might be something we don't want
To see all local images, run:
docker image ls
docker run --name web myapp:1.0
Note how you can label containers using --name or -n option.
# Stop container with SIGTERM
docker stop web
# Stop container with SIGKILL
docker kill web
docker stop $(docker ps -q)
docker ps command will list all running containers and -q option will only show the IDs for those containers
# docker rmi is an alias of docker image rm
docker rmi myapp:1.0
version: '3.18'
services:
app:
image: myapp:1.0
env_file:
- .env
ports:
- 80:3000
Note that port configuration in docker-compose.yml will overwrite one in Dockerfile
Make sure you have .env and node_modules in .dockerignore file.
To run the app, use:
docker-compose up -d app
-d option will run container in detached mode
To see running containers:
docker ps
To see logs from apps within container:
docker logs -f web
-f or --follow option will follow all incomming logs
To see the list of last 100 logs:
docker logs --tail 100 web
Docker containers should be ready to be terminated and re-built any moment. Data we're saving to file system within image will be lost in the case of such reload. To fix this issue we need to setup persistent volumes. To add volumes, we need to modify docker-compose.yml
version: '3.18'
services:
app:
build: .
env_file:
- .env
ports:
- 80:3000
volumes:
- appdata: /appdata
volumes:
appdata:
Under app, we need to specify what directory inside image will be served as persistent volume and under volumes we need to declare our volumes. All the data saved in /appdata will persist even in the case of image reload.
There are three ways to expose ports with Docker:
- From
Dockerfileusing EXPOSE<hostport> - From
docker-compose.ymlunder-ports - While running container:
docker run -p <hostport>:<dockerport> <image>
Note the host port comes first - that's the port we're going to access app from the host machine. So if our Node/Express app is listening to port 3000 and we're binding ports with 80:3000, we can access the app from http://localhost.
In stand-alone container:
docker run --restart always --name my_container image_tag
In docker-compose.yml:
version: '3.18'
services:
webapp:
image: image_name
restart: always
version: '3.18'
services:
webapp:
image: image_name
restart: always
env_file:
- .env
Do not forget to add .env file to both .gitignore and .dockerignore files.
In Dockerfile:
RUN ln -sf /dev/stdout ./logs/debug.log
This command will create a symlink (symbolic link -s) from our debug.log file we write logs to to stdout. Note that this will NOT write logs to a file which will not use disk space.