算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
devops-docker【设计与创意】Trigger: "Docker", "container", "docker run", "docker compose", "Dockerfile", "containerize", "docker build", "docker network", "docker volume", "registry", "docker swarm", "container runtime", "OCI", "container security". Covers: Docker Engine, Docker Compose, multi-stage builds, registries, networking, volumes, security, CI/CD integration, Swarm or…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Build, ship, and run containerized applications using Docker Engine, Compose, and ecosystem tools with security, optimization, and production-grade patterns.
Any user message referencing Docker, containerization, Dockerfiles, Compose, registries, container networking, or image building.
Dockerfile, .dockerignore, docker-compose.yml, registry config, CI integration.
Dockerfile, YAML, CLI commands. No preamble. No postamble.
Dockerfile -> docker build -> image -> docker push -> registry
|
docker pull
|
docker run -> container (running)
|
docker stop -> container (stopped)
|
docker rm -> container (removed)
Each Dockerfile instruction creates a layer. Layers are cached and reused. Order matters: copy dependency files first (rarely changes), source code last (frequently changes). Each layer is an immutable diff. Layers are shared across images — base images are downloaded once.
| Base Image | Size | Security | Use Case |
|---|---|---|---|
| alpine | ~5MB | Small surface, musl libc | Minimal runtime, Go/static binaries |
| slim (debian) | ~80MB | Reduced surface, glibc | Node, Python, Ruby |
| distroless | ~15MB | Minimal, no shell, no pkg mgr | Production, security-hardened |
| ubuntu/debian | ~200MB | Full surface | Development, complex deps |
| scratch | 0MB | Empty image | Static Go binaries |
| windows | ~5GB | Large surface | Windows containers |
| Runtime | Description | Best For |
|---|---|---|
| Docker Engine | Single host, full features | Dev, test, single-node prod |
| Docker Compose | Multi-container on single host | Dev environments, small deployments |
| Docker Swarm | Built-in orchestration, simple | Small/medium production, simple scheduling |
| Kubernetes | Full orchestration, complex | Large-scale, HA, complex scheduling |
| Registry | Features | Best For |
|---|---|---|
| Docker Hub | Public/private, automated builds | Open source, small teams |
| GitHub Container Registry | Integrated with GH packages, free for public | GitHub-centric workflows |
| Amazon ECR | IAM integration, image scanning | AWS deployments |
| Google Artifact Registry | Cloud Build integration, vulnerability scanning | GCP deployments |
| Azure Container Registry | ACR tasks, Helm repo | Azure deployments |
| Self-hosted (Harbor) | Air-gapped, compliance, RBAC, replication | Regulated industries, on-prem |
# Stage 1: Build
FROM node:22-alpine AS builder
WORKDIR /app
RUN apk add --no-cache python3 make g++
COPY package*.json ./
RUN npm ci
COPY tsconfig.json ./
COPY src/ ./src/
RUN npm run build && npm prune --production
# Stage 2: Production
FROM node:22-alpine AS runner
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER appuser
EXPOSE 3000
ENV NODE_ENV=production
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/main.js"]
node_modules
.git
.gitignore
.env
.env.*
*.md
Dockerfile
.dockerignore
.gitlab-ci.yml
.github
dist
.cache
coverage
test-results
*.log
npm-debug.log*
.vscode
.idea
services:
app:
build:
context: .
target: runner
args:
NODE_ENV: ${NODE_ENV:-production}
image: myapp:${TAG:-latest}
ports:
- "${PORT:-3000}:3000"
environment:
- NODE_ENV=${NODE_ENV:-production}
- DATABASE_URL=postgres://user:pass@db:5432/app
env_file:
- .env
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
deploy:
resources:
limits:
cpus: '1.0'
memory: 512M
reservations:
cpus: '0.25'
memory: 128M
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
db:
image: postgres:16-alpine
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: ${DB_PASSWORD:?error}
POSTGRES_DB: app
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d app"]
interval: 5s
timeout: 5s
retries: 5
deploy:
resources:
limits:
memory: 1G
restart: unless-stopped
redis:
image: redis:7-alpine
volumes:
- redisdata:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 5
deploy:
resources:
limits:
memory: 256M
volumes:
pgdata:
redisdata:
# docker-compose.override.yml
services:
app:
build:
target: builder
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
command: npm run dev
# .github/workflows/docker.yml
name: Build and Push Docker Image
on:
push:
branches: [main]
tags: ['v*.*.*']
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/metadata-action@v5
id: meta
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=sha,format=long
- uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
services:
app:
networks:
- frontend
- backend
db:
networks:
- backend
redis:
networks:
- backend
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true # No external access
services:
app:
secrets:
- db_password
- api_key
secrets:
db_password:
file: ./secrets/db_password.txt
api_key:
environment: API_KEY
version: '3.8'
services:
app:
image: myapp:latest
ports:
- target: 3000
published: 3000
deploy:
mode: replicated
replicas: 3
update_config:
parallelism: 1
delay: 10s
order: start-first
rollback_config:
parallelism: 0
order: stop-first
restart_policy:
condition: any
delay: 5s
max_attempts: 3
placement:
constraints:
- node.role == worker
- node.labels.zone == app
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/health"]
interval: 15s
timeout: 3s
retries: 3
start_period: 40s
secrets:
- db_password
networks:
- overlay-net
secrets:
db_password:
external: true
networks:
overlay-net:
driver: overlay
attachable: true
| Feature | Docker | Podman | containerd | nerdctl |
|---|---|---|---|---|
| Daemon | Docker Engine | Daemonless (rootless) | Via CRI | Via containerd |
| Rootless | Experimental | Native | Via K8s | Via containerd |
| K8s CRI | Via cri-dockerd | Via CRI-O | Native CRI | Native CRI |
| Compose | docker compose | podman-compose | -- | nerdctl compose |
| Build | BuildKit | Buildah | Via nerdctl | BuildKit |
| Swarm | Built-in | -- | -- | -- |
| macOS/Windows | Docker Desktop | Podman Machine | -- | -- |
| Systemd integration | Manual | Native socket activation | Native | Native |
| Tool | Description | Build Strategy |
|---|---|---|
| docker build | Standard, BuildKit mode | Layer caching, inline cache |
| docker buildx | Multi-arch, multiple builders | QEMU emulation, cross-compile |
| kaniko | Rootless, in-cluster builds | No daemon needed, K8s native |
| buildah | Daemonless OCI builds | Rootless, scriptable |
| packer | VM + Docker images | HashiCorp ecosystem |
Running containers as root creates a privilege escalation path. If the container is compromised, the attacker gains root access to the host kernel namespace. Always create and use a non-root user. Distroless images run as non-root by default.
Including compilers, package managers, and dev dependencies in production images increases attack surface by 5-10x and image size by 200-500MB. Use multi-stage builds: builder stage with full toolchain, runner stage with only runtime artifacts.
Copying source code before dependency files invalidates the cache on every code change, forcing dependency reinstallation every build. Copy dependency manifests first (package*.json, go.mod, Cargo.toml), install dependencies, then copy source code.
latest TagThe latest tag is ambiguous and mutable. It could refer to different images at different times, making rollback impossible. Always tag with semantic version, git SHA, or timestamp. Use latest only as an additional convenience tag alongside specific tags.
Without health checks, Docker has no way to know if your application is actually running and responsive. The container appears "up" even if the process is hung or unhealthy. Always configure HEALTHCHECK with appropriate interval, timeout, and start period.
Secrets baked into images persist in every layer, visible to anyone with image pull access. Registry security doesn't help if the image is shared or published. Use Docker secrets (Swarm), build args (non-persistent), or external secret stores.
Using the default bridge network for all services means every container can communicate with every other container, violating least-privilege networking. Use multiple networks: frontend (app + LB) and backend (app + DB). Make backend networks internal.
When no .dockerignore exists or it's too permissive, the entire project directory (including node_modules, .git, build artifacts) is sent to the Docker daemon. This causes slow builds and cache misses. Always include a strict .dockerignore.
:latestUsing FROM node:latest means builds are non-reproducible. A new Node major version could break your application. Always pin to a specific minor version tag (node:22.3-alpine). Use automated update tools (Renovate, Dependabot) to manage updates.
Without --memory and --cpus limits, a single container can consume all host resources, starving other containers or the host OS. Always set resource limits and reservations. Use Docker Compose deploy.resources or docker run --memory --cpus.
--read-only)--cap-drop=ALL --cap-add=NET_BIND_SERVICE)--userns-remap){
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
docker run -d \
--memory="512M" \
--memory-reservation="256M" \
--memory-swap="1G" \
--cpus="1.5" \
--cpuset-cpus="0-1" \
--pids-limit="100" \
--restart=unless-stopped \
myapp:1.2.3
docker logs <container> — check application logsdocker inspect <container> — check exit code, error statedocker run -it <image> sh — override entrypoint for debuggingdocker stats <container>netstat -tulpn | grep <port>docker inspect --format='{{json .Mounts}}' <container>docker build --no-cache . — fresh build bypasses cachedocker build --progress=plain . — verbose build outputdocker system dfdocker network ls — list networksdocker network inspect <network> — check connected containersdocker exec <container> ping <other-container> — test connectivitydocker exec <container> cat /etc/resolv.confiptables -L -ndocker port <container>docker stats — live resource usage per containerdocker run --rm alpine sh -c "time dd if=/dev/zero of=/tmp/test bs=1M count=1000"docker info | grep Storagels -lah /var/lib/docker/containers/*/*-json.logdocker system df # Show disk usage
docker system prune -a --volumes # Remove all unused
docker image prune -a # Remove unused images
docker container prune # Remove stopped containers
docker volume prune # Remove unused volumes
ls -lah /var/lib/docker/containers/*/*-json.log # Check log files
:latestlatest--cap-drop=ALL)unless-stopped or always)docker exec for production changes — rebuild and redeployHand off to docker for containerization. Hand off to kubernetes-patterns if orchestration is needed. Hand off to cicd-pipeline for CI/CD integration.