Docker Cheatsheet
Контейнеры
docker run -d --name web -p 8080:80 nginx:1.27
docker run -it --rm ubuntu:24.04 bash # интерактивно + удалить после
docker run -e KEY=value image
docker run -v $(pwd):/app image # bind mount
docker run --restart=always image # auto-restart
docker ps # активные
docker ps -a # все
docker logs -f --tail 100 web
docker exec -it web sh # войти внутрь
docker stats # real-time метрики
docker inspect web # все детали
docker top web # процессы
docker stop web
docker start web
docker restart web
docker rm web
docker rm -f web # force
Образы
docker images
docker pull alpine:3.20
docker pull alpine@sha256:abc123... # по digest
docker tag old:1 new:1
docker push ghcr.io/me/app:1.0
docker rmi image:tag
docker history image # слои
Сборка
docker build -t myapp:1.0 .
docker build --no-cache -t myapp:1.0 .
docker build --target builder -t myapp:build . # multi-stage stop
# BuildKit (включён по умолчанию)
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:1.0 --push .
# С secrets
docker build --secret id=npm,src=$HOME/.npmrc -t myapp .
Volumes
docker volume create mydata
docker volume ls
docker volume inspect mydata
docker volume rm mydata
docker volume prune # удалить unused
# Bind mount
docker run -v $(pwd)/data:/data image
# Named volume
docker run -v mydata:/data image
# Read-only
docker run -v mydata:/data:ro image
# tmpfs
docker run --tmpfs /tmp image
Сети
docker network ls
docker network create mynet
docker network create --subnet 172.20.0.0/16 mynet
docker network inspect bridge
docker network connect mynet container
docker network disconnect mynet container
docker network rm mynet
Очистка
docker system df # использование диска
docker system prune # неиспользуемое
docker system prune -a --volumes # ★ всё ненужное
Эталонный Dockerfile
# syntax=docker/dockerfile:1.7
FROM python:3.12-slim AS builder
WORKDIR /app
RUN pip install --no-cache-dir uv
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev
FROM python:3.12-slim AS runtime
RUN useradd -r -u 10001 app
WORKDIR /app
COPY --from=builder --chown=app:app /app/.venv /app/.venv
COPY --chown=app:app src/ ./src/
USER 10001
ENV PATH="/app/.venv/bin:$PATH"
HEALTHCHECK --interval=30s CMD wget -qO- http://localhost:8000/health || exit 1
EXPOSE 8000
ENTRYPOINT ["python", "-m", "src.main"]
Главные инструкции Dockerfile
| Инструкция | Зачем |
FROM image:tag | Базовый образ. ВСЕГДА pin версию |
WORKDIR /app | Рабочая директория |
RUN cmd | Выполнить при build |
COPY src dst | Копировать (предпочтительнее ADD) |
ENV KEY=value | Env переменная |
ARG NAME | Build-time переменная |
EXPOSE 8000 | Документация порта |
USER 10001 | Non-root user |
HEALTHCHECK | Проверка здоровья |
ENTRYPOINT [...] | Команда контейнера (exec form!) |
CMD [...] | Default args для ENTRYPOINT |
LABEL key=value | Метаданные |
.dockerignore
.git
.github
.venv
__pycache__
*.pyc
node_modules
.env
.env.*
*.log
.DS_Store
docs/
tests/
.terraform/
*.md
Docker Compose
# compose.yaml
services:
api:
build: .
ports: ["8000:8000"]
environment:
DATABASE_URL: postgres://app:secret@db:5432/app
depends_on:
db:
condition: service_healthy
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: secret
volumes: [db_data:/var/lib/postgresql/data]
healthcheck:
test: ["CMD-SHELL", "pg_isready"]
interval: 5s
volumes:
db_data:
docker compose up -d # запустить
docker compose logs -f api # логи сервиса
docker compose ps
docker compose exec api sh # войти
docker compose restart api
docker compose down # остановить
docker compose down -v # + удалить volumes
Безопасность
trivy image myapp:1.0
grype myapp:1.0
syft myapp:1.0 -o spdx-json > sbom.json
# Подпись (Cosign)
cosign sign --yes ghcr.io/me/app:1.0
cosign verify --certificate-identity=... \
--certificate-oidc-issuer=... ghcr.io/me/app:1.0
# Линт Dockerfile
hadolint Dockerfile
# Анализ слоёв
dive myapp:1.0