<< All versions
Skill v1.0.0
currentLLM-judged scan98/100youhai020616/pi-extensions/docker-deploy
──Details
PublishedOctober 23, 2026 at 03:48 PM
Content Hashsha256:e1b3af3bdb886b03...
Git SHAcfa6491a90fc
──Files
Files (1 file, 3.9 KB)
SKILL.md3.9 KBactive
SKILL.md · 170 lines · 3.9 KB
version: "1.0.0" name: docker-deploy description: Use when containerizing applications, writing Dockerfiles, creating docker-compose configs, or setting up CI/CD deployment pipelines
Docker & Deployment
Overview
Containers should be small, secure, and reproducible.
Core principle: Immutable builds, minimal images, environment parity.
Dockerfile Best Practices
Multi-Stage Build (Node.js Example)
dockerfile
# Stage 1: BuildFROM node:20-alpine AS builderWORKDIR /appCOPY package*.json ./RUN npm ci --only=production && cp -R node_modules /prod_modulesRUN npm ciCOPY . .RUN npm run build# Stage 2: ProductionFROM node:20-alpineWORKDIR /appCOPY --from=builder /prod_modules ./node_modulesCOPY --from=builder /app/dist ./distCOPY package.json ./USER nodeEXPOSE 3000HEALTHCHECK --interval=30s --timeout=3s CMD wget -qO- http://localhost:3000/health || exit 1CMD ["node", "dist/index.js"]
Rules
| ✅ Do | ❌ Don't | |
|---|---|---|
Use alpine or slim base images | Use full ubuntu / node:latest | |
COPY package*.json first (layer cache) | COPY . . before npm install | |
npm ci (deterministic) | npm install (non-deterministic) | |
USER node (non-root) | Run as root | |
| Multi-stage builds | Single stage with dev deps | |
.dockerignore file | Copy node_modules / .git | |
Pin versions (node:20.11-alpine) | Use latest tag | |
HEALTHCHECK instruction | No health checks |
.dockerignore
node_modules.git.env*.md.githubcoveragedist
Docker Compose
Production Template
yaml
services:app:build:context: .dockerfile: Dockerfileports:- "${PORT:-3000}:3000"environment:- NODE_ENV=production- DATABASE_URL=${DATABASE_URL}depends_on:db:condition: service_healthyrestart: unless-stoppeddeploy:resources:limits:memory: 512Mcpus: "0.5"db:image: postgres:16-alpinevolumes:- pgdata:/var/lib/postgresql/dataenvironment:POSTGRES_DB: ${DB_NAME}POSTGRES_USER: ${DB_USER}POSTGRES_PASSWORD: ${DB_PASSWORD}healthcheck:test: ["CMD-SHELL", "pg_isready -U ${DB_USER}"]interval: 10stimeout: 5sretries: 5restart: unless-stoppedvolumes:pgdata:
Key Rules
- Always use
depends_onwithcondition: service_healthy - Use
restart: unless-stoppedfor production - Set resource
limits - Use named
volumesfor persistent data - Use
.envfile for secrets (never hardcode) - Use
${VAR:-default}syntax for defaults
CI/CD Pipeline (GitHub Actions)
yaml
name: Build & Deployon:push:branches: [main]jobs:build:runs-on: ubuntu-lateststeps:- uses: actions/checkout@v4- name: Build imagerun: docker build -t app:${{ github.sha }} .- name: Run testsrun: docker run --rm app:${{ github.sha }} npm test- name: Push to registryrun: |docker tag app:${{ github.sha }} $REGISTRY/app:${{ github.sha }}docker tag app:${{ github.sha }} $REGISTRY/app:latestdocker push $REGISTRY/app --all-tags
Deployment Checklist
- [ ] Dockerfile uses multi-stage build
- [ ] Image runs as non-root user
- [ ] Health check configured
- [ ]
.dockerignoreexists and is complete - [ ] No secrets baked into image
- [ ] Environment variables for all config
- [ ] Resource limits set
- [ ] Logging to stdout/stderr (not files)
- [ ] Graceful shutdown handles SIGTERM
- [ ] Image scanned for vulnerabilities (
docker scout,trivy)
Common Image Size Reduction
| Technique | Typical Savings | |
|---|---|---|
alpine base | 500MB → 50MB | |
| Multi-stage build | Remove dev deps, build tools | |
.dockerignore | Exclude .git, node_modules, docs | |
npm ci --only=production | No dev dependencies | |
| Pin + minimal layers | Better cache, smaller diff |