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
Dockerfile
using EXPOSE<hostport>
- From
docker-compose.yml
under-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.