Agent skill
docker-web
Containerizes web applications with Docker for consistent deployments across environments. Use when creating Dockerfiles, building container images, or setting up Docker Compose for development.
Stars
163
Forks
31
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/development/docker-web
SKILL.md
Docker for Web Applications
Containerize web applications for consistent development and deployment across environments.
Quick Start
bash
# Create Dockerfile
touch Dockerfile
# Build image
docker build -t my-app .
# Run container
docker run -p 3000:3000 my-app
# Docker Compose
docker compose up
Node.js Dockerfile
Basic
dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]
Production Optimized
dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Prune dev dependencies
RUN npm prune --production
# Production stage
FROM node:20-alpine AS production
WORKDIR /app
# Create non-root user
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nodeuser
# Copy built app
COPY --from=builder --chown=nodeuser:nodejs /app/dist ./dist
COPY --from=builder --chown=nodeuser:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodeuser:nodejs /app/package.json ./
USER nodeuser
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "dist/index.js"]
Next.js Dockerfile
Standalone Output
dockerfile
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci
FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"
CMD ["node", "server.js"]
next.config.js
javascript
/** @type {import('next').NextConfig} */
module.exports = {
output: 'standalone',
};
React (Vite) Dockerfile
dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage with nginx
FROM nginx:alpine AS production
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
nginx.conf
nginx
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
# Gzip
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
# SPA routing
location / {
try_files $uri $uri/ /index.html;
}
# Cache static assets
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Docker Compose
Development
yaml
# docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.dev
ports:
- "3000:3000"
volumes:
- .:/app
- /app/node_modules
environment:
- NODE_ENV=development
depends_on:
- db
- redis
db:
image: postgres:16-alpine
ports:
- "5432:5432"
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Production
yaml
# docker-compose.prod.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
target: production
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://user:password@db:5432/myapp
depends_on:
db:
condition: service_healthy
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: myapp
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
interval: 5s
timeout: 5s
retries: 5
restart: unless-stopped
volumes:
postgres_data:
.dockerignore
# Dependencies
node_modules
npm-debug.log
# Build output
dist
build
.next
# Git
.git
.gitignore
# IDE
.idea
.vscode
# Environment
.env*
!.env.example
# Tests
coverage
*.test.js
*.test.ts
__tests__
# Docker
Dockerfile*
docker-compose*
.dockerignore
# Misc
README.md
*.md
Multi-Stage Best Practices
Separate Stages
dockerfile
# Base - shared configuration
FROM node:20-alpine AS base
WORKDIR /app
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
# Dependencies
FROM base AS deps
COPY package.json pnpm-lock.yaml ./
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
# Build
FROM base AS builder
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN pnpm build
# Production deps only
FROM base AS prod-deps
COPY package.json pnpm-lock.yaml ./
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --prod --frozen-lockfile
# Runner
FROM base AS runner
ENV NODE_ENV=production
COPY --from=prod-deps /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]
Build Arguments
dockerfile
ARG NODE_VERSION=20
FROM node:${NODE_VERSION}-alpine AS base
ARG API_URL
ENV NEXT_PUBLIC_API_URL=${API_URL}
bash
docker build --build-arg NODE_VERSION=20 --build-arg API_URL=https://api.example.com .
Health Checks
dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
yaml
# docker-compose.yml
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Security Best Practices
Non-Root User
dockerfile
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 appuser
USER appuser
Read-Only Filesystem
yaml
services:
app:
read_only: true
tmpfs:
- /tmp
volumes:
- app_data:/app/data
Security Scanning
bash
# Scan image for vulnerabilities
docker scout cves my-app
# Trivy
trivy image my-app
Common Commands
bash
# Build
docker build -t my-app .
docker build -t my-app:v1.0 --target production .
# Run
docker run -p 3000:3000 my-app
docker run -d --name my-app -p 3000:3000 my-app
docker run --env-file .env my-app
# Compose
docker compose up
docker compose up -d
docker compose up --build
docker compose down
docker compose logs -f
# Inspect
docker ps
docker logs my-app
docker exec -it my-app sh
# Clean up
docker system prune
docker image prune
docker volume prune
See references/patterns.md for framework-specific patterns.
Didn't find tool you were looking for?