Images, containers, volumes, networking, Compose & Dockerfile
DevOpsdocker images # list
docker pull nginx:latest
docker pull node:20-alpine
docker build -t myapp:v1 .
docker build -t myapp -f Dockerfile.prod .
docker build --no-cache -t myapp .
docker tag myapp:v1 myapp:latest
docker rmi nginx
docker image prune # remove unused
docker history myapp:v1 # show layersdocker run -d nginx # detached
docker run -d -p 8080:80 nginx # port map
docker run -d --name web nginx
docker run -it ubuntu bash # interactive
docker run --rm alpine echo hi
docker run -e KEY=val myapp
docker run --env-file .env myapp
docker ps # running
docker ps -a # all
docker stop web docker start web
docker rm -f web
docker exec -it web bash
docker logs -f --tail 100 web
docker stats
docker cp file.txt web:/app/
docker cp web:/app/log.txt .# Multi-stage Node.js
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
USER node
CMD ["node", "dist/index.js"]
# Key instructions
ARG VERSION=latest
ENV NODE_ENV=production
HEALTHCHECK CMD curl -f http://localhost:3000/health
ENTRYPOINT ["node"]
CMD ["server.js"]docker volume create mydata
docker run -v mydata:/app/data nginx
docker volume ls
docker volume inspect mydata
docker volume rm mydata
# Bind mount
docker run -v $(pwd):/app nginx
docker run -v ./config:/etc/nginx:ro
# tmpfs
docker run --tmpfs /tmp nginxdocker network create mynet
docker network ls
docker run -d --name db --network mynet postgres
docker run -d --name app --network mynet myapp
# app reaches db at hostname "db"
# Port mapping
-p 8080:80 # host:container
-p 127.0.0.1:8080:80 # localhost only
-P # map all EXPOSE ports# docker-compose.yml
version: "3.9"
services:
app:
build: .
ports: ["3000:3000"]
environment:
- DATABASE_URL=postgres://u:p@db/mydb
depends_on: [db]
volumes: [".:/app"]
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: u
POSTGRES_PASSWORD: p
volumes: ["pgdata:/var/lib/postgresql/data"]
volumes:
pgdata:
# Commands
docker compose up -d
docker compose down -v
docker compose logs -f app
docker compose exec app bash
docker compose build
docker compose psdocker login
docker tag myapp user/myapp:v1
docker push user/myapp:v1
docker save myapp -o myapp.tar
docker load -i myapp.tardocker container prune
docker image prune -a
docker volume prune
docker system prune -a --volumes
docker system df# .dockerignore
node_modules .git *.md .env dist
# Tips
# 1. Use specific tags (not :latest)
# 2. Multi-stage builds
# 3. Run as non-root (USER node)
# 4. COPY over ADD
# 5. Combine RUN to reduce layers
# 6. Put least-changing layers first
# 7. --no-cache-dir for pip
# 8. Add HEALTHCHECK
# 9. Alpine/Slim base images