This commit is contained in:
Toby
2026-01-27 17:35:45 -05:00
commit 2639af6531
176 changed files with 27104 additions and 0 deletions
@@ -0,0 +1,411 @@
---
name: container-registries
description: Manage container registries including ECR, ACR, GCR, and Docker Hub. Push and pull images, configure authentication, set up repository policies, and implement image lifecycle management. Use when working with container image storage and distribution.
license: MIT
metadata:
author: devops-skills
version: "1.0"
---
# Container Registries
Store, manage, and distribute container images across cloud and self-hosted registries.
## When to Use This Skill
Use this skill when:
- Pushing and pulling container images
- Configuring registry authentication
- Setting up image retention policies
- Managing private container registries
- Implementing image scanning and security
## Prerequisites
- Docker or Podman installed
- Cloud CLI tools (AWS CLI, az, gcloud) for respective registries
- Appropriate IAM permissions
## Docker Hub
### Authentication
```bash
# Login
docker login
# Login with token
echo "$DOCKER_TOKEN" | docker login -u username --password-stdin
```
### Push/Pull Images
```bash
# Tag image
docker tag myapp:latest username/myapp:latest
# Push
docker push username/myapp:latest
# Pull
docker pull username/myapp:latest
```
### Automated Builds
Configure in Docker Hub UI:
1. Connect GitHub/Bitbucket repository
2. Set build rules (branch → tag mapping)
3. Configure build context and Dockerfile path
## Amazon ECR
### Setup
```bash
# Create repository
aws ecr create-repository \
--repository-name myapp \
--image-scanning-configuration scanOnPush=true \
--encryption-configuration encryptionType=AES256
# Get registry URI
REGISTRY=$(aws ecr describe-repositories \
--repository-names myapp \
--query 'repositories[0].repositoryUri' \
--output text | cut -d'/' -f1)
```
### Authentication
```bash
# Login (Docker)
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin $REGISTRY
# Login with credential helper
# Add to ~/.docker/config.json:
{
"credHelpers": {
"123456789.dkr.ecr.us-east-1.amazonaws.com": "ecr-login"
}
}
```
### Push/Pull
```bash
# Tag and push
docker tag myapp:latest $REGISTRY/myapp:latest
docker push $REGISTRY/myapp:latest
# Pull
docker pull $REGISTRY/myapp:latest
```
### Lifecycle Policy
```bash
# Create lifecycle policy
aws ecr put-lifecycle-policy \
--repository-name myapp \
--lifecycle-policy-text '{
"rules": [
{
"rulePriority": 1,
"description": "Keep last 10 images",
"selection": {
"tagStatus": "any",
"countType": "imageCountMoreThan",
"countNumber": 10
},
"action": {
"type": "expire"
}
}
]
}'
```
### Repository Policy
```bash
# Allow cross-account access
aws ecr set-repository-policy \
--repository-name myapp \
--policy-text '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CrossAccountPull",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::OTHER_ACCOUNT:root"
},
"Action": [
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage"
]
}
]
}'
```
## Azure Container Registry (ACR)
### Setup
```bash
# Create registry
az acr create \
--resource-group mygroup \
--name myregistry \
--sku Standard \
--admin-enabled false
# Get login server
az acr show --name myregistry --query loginServer -o tsv
```
### Authentication
```bash
# Login with Azure CLI
az acr login --name myregistry
# Login with service principal
docker login myregistry.azurecr.io \
-u $SP_APP_ID \
-p $SP_PASSWORD
# Get access token
az acr login --name myregistry --expose-token
```
### Push/Pull
```bash
# Tag and push
docker tag myapp:latest myregistry.azurecr.io/myapp:latest
docker push myregistry.azurecr.io/myapp:latest
# ACR Build (build in cloud)
az acr build \
--registry myregistry \
--image myapp:latest \
--file Dockerfile .
```
### Retention Policy
```bash
# Enable retention policy
az acr config retention update \
--registry myregistry \
--status enabled \
--days 30 \
--type UntaggedManifests
```
### Geo-Replication
```bash
# Enable replication
az acr replication create \
--registry myregistry \
--location westeurope
# List replications
az acr replication list --registry myregistry
```
## Google Container Registry (GCR) / Artifact Registry
### Setup (Artifact Registry)
```bash
# Create repository
gcloud artifacts repositories create myrepo \
--repository-format=docker \
--location=us-central1 \
--description="Docker repository"
```
### Authentication
```bash
# Configure Docker auth
gcloud auth configure-docker us-central1-docker.pkg.dev
# Or use credential helper
gcloud auth print-access-token | \
docker login -u oauth2accesstoken --password-stdin \
https://us-central1-docker.pkg.dev
```
### Push/Pull
```bash
# Tag for Artifact Registry
docker tag myapp:latest \
us-central1-docker.pkg.dev/PROJECT_ID/myrepo/myapp:latest
# Push
docker push us-central1-docker.pkg.dev/PROJECT_ID/myrepo/myapp:latest
# Pull
docker pull us-central1-docker.pkg.dev/PROJECT_ID/myrepo/myapp:latest
```
### Cleanup Policy
```bash
# Create cleanup policy
gcloud artifacts repositories set-cleanup-policies myrepo \
--location=us-central1 \
--policy=policy.json
# policy.json
{
"name": "delete-old",
"action": {"type": "Delete"},
"condition": {
"olderThan": "30d",
"tagState": "untagged"
}
}
```
## GitHub Container Registry (GHCR)
### Authentication
```bash
# Login with PAT
echo "$GITHUB_TOKEN" | docker login ghcr.io -u USERNAME --password-stdin
```
### Push/Pull
```bash
# Tag
docker tag myapp:latest ghcr.io/OWNER/myapp:latest
# Push
docker push ghcr.io/OWNER/myapp:latest
# Pull
docker pull ghcr.io/OWNER/myapp:latest
```
### Visibility Settings
Configure in GitHub:
1. Go to package settings
2. Change visibility (public/private)
3. Manage access for teams/users
## Self-Hosted Registry
### Deploy with Docker
```bash
# Run registry
docker run -d -p 5000:5000 \
--name registry \
-v registry-data:/var/lib/registry \
registry:2
# Configure TLS
docker run -d -p 443:5000 \
--name registry \
-v /certs:/certs \
-v registry-data:/var/lib/registry \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
```
### Harbor Registry
```bash
# Download Harbor
wget https://github.com/goharbor/harbor/releases/download/v2.9.0/harbor-online-installer-v2.9.0.tgz
tar xzvf harbor-online-installer-v2.9.0.tgz
# Configure harbor.yml
# Set hostname, https certificate, admin password
# Install
./install.sh --with-trivy --with-chartmuseum
```
## Image Security
### Vulnerability Scanning
```bash
# ECR - Enable scan on push
aws ecr put-image-scanning-configuration \
--repository-name myapp \
--image-scanning-configuration scanOnPush=true
# Get scan results
aws ecr describe-image-scan-findings \
--repository-name myapp \
--image-id imageTag=latest
# ACR - Scan with Defender
az acr task create \
--registry myregistry \
--name scan-images \
--cmd "mcr.microsoft.com/azure-cli az acr run-scan"
```
### Image Signing
```bash
# Enable content trust
export DOCKER_CONTENT_TRUST=1
# Sign image on push
docker push myregistry/myapp:latest
# Verify signature
docker trust inspect myregistry/myapp:latest
```
## Common Issues
### Issue: Authentication Expired
**Problem**: Push/pull fails with auth error
**Solution**: Re-run login command, check credential helper
### Issue: Image Not Found
**Problem**: Pull fails with manifest unknown
**Solution**: Verify tag exists, check registry URL
### Issue: Push Permission Denied
**Problem**: Cannot push to repository
**Solution**: Check IAM permissions, verify repository exists
### Issue: Rate Limiting (Docker Hub)
**Problem**: Too many requests error
**Solution**: Authenticate for higher limits, use pull-through cache
## Best Practices
- Enable vulnerability scanning on all repositories
- Implement lifecycle policies to manage storage costs
- Use immutable tags for production images
- Configure cross-region replication for availability
- Use service accounts/principals for CI/CD authentication
- Enable audit logging for compliance
- Implement image signing for supply chain security
- Use pull-through cache to avoid rate limits
## Related Skills
- [docker-management](../docker-management/) - Building images
- [container-scanning](../../../security/scanning/container-scanning/) - Security scanning
- [aws-iam](../../../infrastructure/cloud-aws/aws-iam/) - AWS permissions
+458
View File
@@ -0,0 +1,458 @@
---
name: docker-compose
description: Define and run multi-container Docker applications using Docker Compose. Create compose files, manage service dependencies, configure networks and volumes, and orchestrate local development environments. Use when setting up multi-service applications or development environments.
license: MIT
metadata:
author: devops-skills
version: "1.0"
---
# Docker Compose
Orchestrate multi-container applications with declarative YAML configuration.
## When to Use This Skill
Use this skill when:
- Running multi-container applications locally
- Setting up development environments
- Defining service dependencies and networking
- Managing application stacks with multiple services
- Creating reproducible development setups
## Prerequisites
- Docker Engine with Compose plugin (v2)
- Basic Docker knowledge
- YAML syntax understanding
## Basic Configuration
### Simple Application Stack
```yaml
# docker-compose.yml
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=development
- DATABASE_URL=postgres://postgres:secret@db:5432/myapp
depends_on:
- db
- redis
db:
image: postgres:15-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- postgres-data:/var/lib/postgresql/data
ports:
- "5432:5432"
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres-data:
```
## Service Configuration
### Build Options
```yaml
services:
app:
build:
context: ./app
dockerfile: Dockerfile.dev
args:
NODE_VERSION: "20"
target: development
cache_from:
- myapp:cache
image: myapp:dev
```
### Environment Variables
```yaml
services:
app:
environment:
- NODE_ENV=production
- API_KEY=${API_KEY} # From shell or .env file
env_file:
- .env
- .env.local
```
### Port Mapping
```yaml
services:
web:
ports:
- "3000:3000" # HOST:CONTAINER
- "127.0.0.1:9229:9229" # Bind to localhost only
- "8080-8090:8080-8090" # Port range
expose:
- "3000" # Internal only (no host binding)
```
### Volume Mounts
```yaml
services:
app:
volumes:
# Named volume
- app-data:/app/data
# Bind mount
- ./src:/app/src
# Read-only bind mount
- ./config:/app/config:ro
# Anonymous volume (for node_modules)
- /app/node_modules
volumes:
app-data:
driver: local
```
### Dependencies
```yaml
services:
web:
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
db:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
```
## Networking
### Custom Networks
```yaml
services:
frontend:
networks:
- frontend-net
backend:
networks:
- frontend-net
- backend-net
db:
networks:
- backend-net
networks:
frontend-net:
driver: bridge
backend-net:
driver: bridge
internal: true # No external access
```
### Network Aliases
```yaml
services:
db:
networks:
backend:
aliases:
- database
- postgres
networks:
backend:
```
## Resource Limits
```yaml
services:
app:
deploy:
resources:
limits:
cpus: '2'
memory: 1G
reservations:
cpus: '0.5'
memory: 256M
```
## Multiple Compose Files
### Override Files
```yaml
# docker-compose.yml (base)
services:
web:
image: myapp:latest
ports:
- "3000:3000"
# docker-compose.override.yml (development - auto-loaded)
services:
web:
build: .
volumes:
- ./src:/app/src
environment:
- DEBUG=true
# docker-compose.prod.yml (production)
services:
web:
deploy:
replicas: 3
environment:
- DEBUG=false
```
### Using Multiple Files
```bash
# Development (uses override automatically)
docker compose up
# Production
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
# Merge and view final config
docker compose -f docker-compose.yml -f docker-compose.prod.yml config
```
## Profiles
```yaml
services:
web:
image: myapp
db:
image: postgres:15
debug:
image: busybox
profiles:
- debug
monitoring:
image: prometheus
profiles:
- monitoring
```
```bash
# Run without profiles (web, db only)
docker compose up
# Run with debug profile
docker compose --profile debug up
# Run with multiple profiles
docker compose --profile debug --profile monitoring up
```
## Commands
### Lifecycle
```bash
# Start services
docker compose up -d
# Start specific service
docker compose up -d web
# Stop services
docker compose stop
# Stop and remove containers
docker compose down
# Stop and remove everything including volumes
docker compose down -v --rmi all
# Restart services
docker compose restart web
```
### Building
```bash
# Build images
docker compose build
# Build without cache
docker compose build --no-cache
# Build and start
docker compose up --build
# Pull latest images
docker compose pull
```
### Monitoring
```bash
# View logs
docker compose logs -f
# View specific service logs
docker compose logs -f web
# View running services
docker compose ps
# View resource usage
docker compose top
```
### Execution
```bash
# Run command in new container
docker compose run --rm web npm test
# Execute in running container
docker compose exec web /bin/sh
# Scale service
docker compose up -d --scale worker=3
```
## Development Workflow
### Watch Mode (Compose v2.22+)
```yaml
services:
web:
build: .
develop:
watch:
- action: sync
path: ./src
target: /app/src
- action: rebuild
path: ./package.json
```
```bash
docker compose watch
```
### Hot Reload Setup
```yaml
services:
web:
build:
context: .
target: development
volumes:
- ./src:/app/src
- /app/node_modules
environment:
- CHOKIDAR_USEPOLLING=true
command: npm run dev
```
## Common Patterns
### Database Initialization
```yaml
services:
db:
image: postgres:15
volumes:
- postgres-data:/var/lib/postgresql/data
- ./init-scripts:/docker-entrypoint-initdb.d:ro
environment:
POSTGRES_DB: myapp
```
### Reverse Proxy
```yaml
services:
proxy:
image: traefik:v3.0
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./traefik.yml:/etc/traefik/traefik.yml:ro
web:
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`app.localhost`)"
```
## Common Issues
### Issue: Container Cannot Resolve Service Name
**Problem**: Service can't connect to another service by name
**Solution**: Ensure services are on the same network, check depends_on
### Issue: Volume Permissions
**Problem**: Container can't write to mounted volume
**Solution**: Match container user UID with host, or use named volumes
### Issue: Port Already in Use
**Problem**: Error binding to port
**Solution**: Change host port or stop conflicting service
### Issue: Changes Not Reflected
**Problem**: Code changes don't appear in container
**Solution**: Check volume mounts, rebuild if Dockerfile changed
## Best Practices
- Use named volumes for persistent data
- Define healthchecks for database dependencies
- Use profiles to separate optional services
- Keep secrets in .env files (not committed)
- Use override files for environment-specific config
- Pin image versions for reproducibility
- Use networks to isolate service groups
- Leverage watch mode for development
## Related Skills
- [docker-management](../docker-management/) - Docker fundamentals
- [kubernetes-ops](../../orchestration/kubernetes-ops/) - Production orchestration
- [reverse-proxy](../../../infrastructure/networking/reverse-proxy/) - Production routing
@@ -0,0 +1,124 @@
# Docker Compose Patterns
## Basic Structure
```yaml
version: '3.8'
services:
app:
build: .
ports:
- "8080:80"
environment:
- NODE_ENV=production
depends_on:
- db
networks:
- frontend
- backend
db:
image: postgres:15
volumes:
- db_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: myapp
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
networks:
- backend
volumes:
db_data:
networks:
frontend:
backend:
secrets:
db_password:
file: ./secrets/db_password.txt
```
## Health Checks
```yaml
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
```
## Resource Limits
```yaml
services:
app:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
```
## Multiple Compose Files
```bash
# Base + overrides
docker compose -f docker-compose.yml -f docker-compose.prod.yml up
# Or use COMPOSE_FILE
export COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml
docker compose up
```
## Environment Variables
```yaml
# .env file
services:
app:
image: myapp:${VERSION:-latest}
environment:
- DATABASE_URL=${DATABASE_URL}
env_file:
- .env
- .env.local
```
## Service Profiles
```yaml
services:
app:
profiles: [] # Always starts
debug:
profiles: [debug]
# Only starts with --profile debug
```
## Extension Fields
```yaml
x-common: &common
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
services:
app:
<<: *common
image: myapp
```
@@ -0,0 +1,402 @@
---
name: docker-management
description: Build, optimize, and troubleshoot Docker containers and images. Create efficient Dockerfiles, manage container lifecycle, configure networking and volumes, and debug container issues. Use when working with Docker, containerization, or container troubleshooting.
license: MIT
metadata:
author: devops-skills
version: "1.0"
---
# Docker Management
Build, run, and manage Docker containers for application deployment and development.
## When to Use This Skill
Use this skill when:
- Creating and optimizing Dockerfiles
- Building and tagging Docker images
- Running and managing containers
- Debugging container issues
- Configuring Docker networking and volumes
- Implementing container security best practices
## Prerequisites
- Docker Engine installed (20.10+)
- Basic command line knowledge
- Understanding of application deployment
## Dockerfile Best Practices
### Multi-Stage Build
```dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine AS production
WORKDIR /app
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
USER nodejs
EXPOSE 3000
CMD ["node", "dist/index.js"]
```
### Layer Optimization
```dockerfile
FROM python:3.12-slim
# Install dependencies first (cached unless requirements change)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code (changes frequently)
COPY . .
CMD ["python", "app.py"]
```
### Security Hardening
```dockerfile
FROM node:20-alpine
# Create non-root user
RUN addgroup -g 1001 appgroup && \
adduser -u 1001 -G appgroup -D appuser
WORKDIR /app
# Copy with proper ownership
COPY --chown=appuser:appgroup . .
# Drop privileges
USER appuser
# Use exec form for proper signal handling
CMD ["node", "server.js"]
```
## Building Images
### Basic Build
```bash
# Build with tag
docker build -t myapp:1.0 .
# Build with build args
docker build --build-arg NODE_ENV=production -t myapp:prod .
# Build for specific platform
docker build --platform linux/amd64 -t myapp:amd64 .
# Build with no cache
docker build --no-cache -t myapp:fresh .
```
### Multi-Platform Builds
```bash
# Create builder
docker buildx create --name multiplatform --use
# Build for multiple architectures
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t myregistry/myapp:latest \
--push .
```
## Running Containers
### Basic Operations
```bash
# Run container
docker run -d --name myapp -p 8080:3000 myapp:latest
# Run with environment variables
docker run -d \
-e DATABASE_URL=postgres://localhost/db \
-e NODE_ENV=production \
myapp:latest
# Run with resource limits
docker run -d \
--memory="512m" \
--cpus="1.0" \
myapp:latest
# Run with restart policy
docker run -d --restart=unless-stopped myapp:latest
```
### Volume Management
```bash
# Named volume
docker volume create mydata
docker run -v mydata:/app/data myapp:latest
# Bind mount
docker run -v $(pwd)/config:/app/config:ro myapp:latest
# tmpfs mount (memory)
docker run --tmpfs /tmp:rw,noexec,nosuid myapp:latest
```
### Networking
```bash
# Create network
docker network create mynetwork
# Run on network
docker run -d --network mynetwork --name api myapp:latest
# Connect existing container
docker network connect mynetwork existing-container
# Expose specific ports
docker run -d -p 127.0.0.1:8080:3000 myapp:latest
```
## Container Lifecycle
### Management Commands
```bash
# List containers
docker ps -a
# Stop container
docker stop myapp
# Remove container
docker rm myapp
# Force remove running container
docker rm -f myapp
# Prune stopped containers
docker container prune -f
```
### Logs and Monitoring
```bash
# View logs
docker logs myapp
# Follow logs
docker logs -f --tail 100 myapp
# View resource usage
docker stats myapp
# Inspect container
docker inspect myapp
```
## Debugging Containers
### Interactive Access
```bash
# Execute command in running container
docker exec -it myapp /bin/sh
# Run container with shell
docker run -it --rm myapp:latest /bin/sh
# Debug failed container
docker run -it --entrypoint /bin/sh myapp:latest
```
### Troubleshooting
```bash
# Check container logs for errors
docker logs myapp 2>&1 | grep -i error
# Inspect container state
docker inspect --format='{{.State.Status}}' myapp
# Check container processes
docker top myapp
# View container filesystem changes
docker diff myapp
# Export container filesystem
docker export myapp > myapp-fs.tar
```
### Health Checks
```dockerfile
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
```
```bash
# Check health status
docker inspect --format='{{.State.Health.Status}}' myapp
```
## Image Management
### Tagging and Pushing
```bash
# Tag image
docker tag myapp:latest myregistry.com/myapp:v1.0
# Push to registry
docker push myregistry.com/myapp:v1.0
# Pull image
docker pull myregistry.com/myapp:v1.0
```
### Cleanup
```bash
# Remove unused images
docker image prune -a
# Remove all unused resources
docker system prune -a --volumes
# Remove specific image
docker rmi myapp:old
# List image sizes
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
```
### Image Analysis
```bash
# View image history
docker history myapp:latest
# Inspect image layers
docker inspect myapp:latest
# Check image vulnerabilities (with Docker Scout)
docker scout cves myapp:latest
```
## Docker Compose Integration
```yaml
# docker-compose.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=production
volumes:
- app-data:/app/data
depends_on:
- db
restart: unless-stopped
db:
image: postgres:15-alpine
environment:
POSTGRES_PASSWORD: secret
volumes:
- db-data:/var/lib/postgresql/data
volumes:
app-data:
db-data:
```
## Security Best Practices
### Image Security
```dockerfile
# Use specific version tags
FROM node:20.10-alpine3.18
# Don't run as root
USER nobody
# Remove unnecessary packages
RUN apk del --purge build-dependencies
# Use COPY instead of ADD
COPY . .
```
### Runtime Security
```bash
# Run with security options
docker run -d \
--security-opt=no-new-privileges \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
--read-only \
myapp:latest
# Use user namespace remapping
# Add to /etc/docker/daemon.json: {"userns-remap": "default"}
```
## Common Issues
### Issue: Container Exits Immediately
**Problem**: Container starts and stops instantly
**Solution**: Check if CMD/ENTRYPOINT runs foreground process, use `docker logs` to see errors
### Issue: Cannot Connect to Container
**Problem**: Port not accessible
**Solution**: Verify port mapping (-p), check container is running, verify firewall rules
### Issue: Out of Disk Space
**Problem**: Docker using too much disk
**Solution**: Run `docker system prune -a --volumes`, check for large unused images
### Issue: Build Cache Not Working
**Problem**: Every build downloads dependencies
**Solution**: Order Dockerfile instructions from least to most frequently changing
## Best Practices
- Use multi-stage builds to minimize image size
- Never store secrets in images - use runtime injection
- Pin base image versions for reproducibility
- Implement health checks for production containers
- Use .dockerignore to exclude unnecessary files
- Run containers as non-root users
- Scan images for vulnerabilities regularly
- Use Docker BuildKit for faster builds
## Related Skills
- [docker-compose](../docker-compose/) - Multi-container applications
- [container-scanning](../../../security/scanning/container-scanning/) - Security scanning
- [container-hardening](../../../security/hardening/container-hardening/) - Security hardening
@@ -0,0 +1,111 @@
# Docker Command Reference
## Container Lifecycle
```bash
# Run container
docker run -d --name myapp -p 8080:80 nginx
docker run -it --rm ubuntu bash
# Start/Stop
docker start myapp
docker stop myapp
docker restart myapp
# Remove
docker rm myapp
docker rm -f myapp # Force
# Logs
docker logs myapp
docker logs -f myapp # Follow
docker logs --tail 100 myapp
```
## Images
```bash
# List/Pull/Build
docker images
docker pull nginx:latest
docker build -t myapp:1.0 .
docker build -t myapp:1.0 -f Dockerfile.prod .
# Tag/Push
docker tag myapp:1.0 registry.example.com/myapp:1.0
docker push registry.example.com/myapp:1.0
# Remove
docker rmi myapp:1.0
docker image prune -a # Remove unused
```
## Inspection
```bash
# Container info
docker ps
docker ps -a
docker inspect myapp
docker stats
docker top myapp
# Exec into container
docker exec -it myapp bash
docker exec myapp ls -la /app
```
## Networks
```bash
# List/Create
docker network ls
docker network create mynet
# Connect container
docker network connect mynet myapp
docker run --network mynet nginx
```
## Volumes
```bash
# List/Create
docker volume ls
docker volume create mydata
# Mount
docker run -v mydata:/data nginx
docker run -v $(pwd):/app nginx
docker run --mount type=bind,source=$(pwd),target=/app nginx
```
## Cleanup
```bash
# Remove stopped containers
docker container prune
# Remove unused images
docker image prune -a
# Remove everything unused
docker system prune -a --volumes
# Disk usage
docker system df
```
## Multi-stage Build
```dockerfile
FROM node:20 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
```
+381
View File
@@ -0,0 +1,381 @@
---
name: podman
description: Manage containers using Podman, the daemonless container engine. Run rootless containers, create pods, manage images, and use Docker-compatible commands. Use when working with Podman or requiring rootless container operations.
license: MIT
metadata:
author: devops-skills
version: "1.0"
---
# Podman
Run and manage containers without a daemon using Podman's rootless container engine.
## When to Use This Skill
Use this skill when:
- Running containers without root privileges
- Managing containers on systems without Docker
- Creating pod-based container groups
- Using systemd for container management
- Working in security-conscious environments
## Prerequisites
- Podman installed (4.x+)
- For rootless: user namespaces enabled
- Basic container concepts understanding
## Key Differences from Docker
| Feature | Docker | Podman |
|---------|--------|--------|
| Architecture | Client-daemon | Daemonless |
| Root required | Default | Optional (rootless) |
| Pod support | No | Yes (Kubernetes-style) |
| Systemd integration | Limited | Native |
| Socket | docker.sock | podman.sock (optional) |
## Basic Commands
### Container Operations
```bash
# Run container (identical to Docker)
podman run -d --name webserver -p 8080:80 nginx
# List containers
podman ps -a
# Stop and remove
podman stop webserver
podman rm webserver
# Execute command
podman exec -it webserver /bin/sh
# View logs
podman logs -f webserver
```
### Image Management
```bash
# Pull image
podman pull docker.io/library/nginx:latest
# List images
podman images
# Build image
podman build -t myapp:latest .
# Push to registry
podman push myapp:latest registry.example.com/myapp:latest
# Remove image
podman rmi nginx:latest
```
## Rootless Containers
### Setup
```bash
# Check user namespace support
cat /proc/sys/user/max_user_namespaces
# Enable if needed (as root)
echo "user.max_user_namespaces=28633" | sudo tee /etc/sysctl.d/userns.conf
sudo sysctl -p /etc/sysctl.d/userns.conf
# Configure subuid/subgid for user
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
# Verify
podman unshare cat /proc/self/uid_map
```
### Running Rootless
```bash
# Run as regular user (no sudo)
podman run -d --name myapp -p 8080:80 nginx
# Check user namespace mapping
podman unshare id
# Verify non-root
podman top myapp user
```
### Port Considerations
```bash
# Rootless cannot bind to ports < 1024 by default
# Use ports >= 1024
podman run -d -p 8080:80 nginx
# Or enable unprivileged ports (as root)
echo "net.ipv4.ip_unprivileged_port_start=80" | sudo tee /etc/sysctl.d/ports.conf
sudo sysctl -p /etc/sysctl.d/ports.conf
```
## Pods
### Creating Pods
```bash
# Create pod
podman pod create --name mypod -p 8080:80 -p 5432:5432
# Add containers to pod
podman run -d --pod mypod --name web nginx
podman run -d --pod mypod --name db postgres:15
# List pods
podman pod ps
# Containers share network namespace
podman exec web curl localhost:5432
```
### Pod Management
```bash
# Start/stop pod (affects all containers)
podman pod start mypod
podman pod stop mypod
# Remove pod and containers
podman pod rm -f mypod
# View pod details
podman pod inspect mypod
# Generate Kubernetes YAML from pod
podman generate kube mypod > mypod.yaml
```
## Systemd Integration
### Generate Systemd Unit
```bash
# Generate unit file for container
podman generate systemd --new --name myapp > ~/.config/systemd/user/container-myapp.service
# For pod
podman generate systemd --new --name mypod --files
# Reload systemd
systemctl --user daemon-reload
# Enable and start
systemctl --user enable --now container-myapp.service
```
### Quadlet (Podman 4.4+)
```ini
# ~/.config/containers/systemd/webapp.container
[Container]
Image=docker.io/library/nginx:latest
PublishPort=8080:80
Volume=webapp-data:/usr/share/nginx/html
[Service]
Restart=always
[Install]
WantedBy=default.target
```
```bash
# Reload to generate service
systemctl --user daemon-reload
# Start the service
systemctl --user start webapp
```
## Compose Compatibility
### Using Podman Compose
```bash
# Install podman-compose
pip install podman-compose
# Run compose file
podman-compose up -d
# Or use Docker Compose with Podman socket
systemctl --user enable --now podman.socket
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock
docker-compose up -d
```
### Native Podman Kube
```bash
# Play Kubernetes YAML
podman kube play deployment.yaml
# Stop and remove
podman kube down deployment.yaml
```
## Networking
### Network Management
```bash
# Create network
podman network create mynetwork
# Run on network
podman run -d --network mynetwork --name app myapp
# Connect container to network
podman network connect mynetwork existing-container
# List networks
podman network ls
# Inspect network
podman network inspect mynetwork
```
### DNS Resolution
```bash
# Containers on same network can resolve by name
podman run -d --network mynetwork --name db postgres:15
podman run -d --network mynetwork --name app \
-e DATABASE_HOST=db myapp
```
## Storage
### Volume Management
```bash
# Create volume
podman volume create mydata
# Use volume
podman run -d -v mydata:/data myapp
# List volumes
podman volume ls
# Inspect volume
podman volume inspect mydata
# Rootless volumes location
ls ~/.local/share/containers/storage/volumes/
```
### Bind Mounts
```bash
# Bind mount with SELinux label
podman run -v ./data:/app/data:Z myapp
# Z = private label (single container)
# z = shared label (multiple containers)
```
## Registry Configuration
### Configure Registries
```bash
# Edit registries.conf
# ~/.config/containers/registries.conf
```
```toml
unqualified-search-registries = ["docker.io", "quay.io"]
[[registry]]
prefix = "docker.io"
location = "docker.io"
[[registry.mirror]]
location = "mirror.gcr.io"
```
### Authentication
```bash
# Login to registry
podman login docker.io
# Login to private registry
podman login registry.example.com
# Credentials stored in
# ~/.config/containers/auth.json
```
## Building Images
### Buildah Integration
```bash
# Podman uses Buildah for builds
podman build -t myapp:latest .
# Build with specific format
podman build --format docker -t myapp .
# Multi-stage build
podman build --target production -t myapp:prod .
```
### Buildah Commands
```bash
# Create container from scratch
buildah from scratch
buildah copy working-container ./app /app
buildah config --entrypoint '["/app/main"]' working-container
buildah commit working-container myapp:minimal
```
## Common Issues
### Issue: Permission Denied
**Problem**: Cannot access files in mounted volumes
**Solution**: Use `:Z` or `:z` suffix for SELinux, or check ownership
### Issue: Cannot Connect to Container
**Problem**: Port not accessible in rootless mode
**Solution**: Use ports >= 1024 or configure unprivileged port start
### Issue: Slow Image Pulls
**Problem**: Images download slowly
**Solution**: Configure registry mirrors in registries.conf
### Issue: Systemd Service Fails
**Problem**: Container doesn't start via systemd
**Solution**: Enable lingering: `loginctl enable-linger $USER`
## Best Practices
- Use rootless mode for enhanced security
- Leverage pods for related containers
- Generate systemd units for production
- Use Quadlet for declarative container services
- Configure SELinux labels for bind mounts
- Enable user lingering for persistent services
- Use podman auto-update for automatic updates
- Alias `docker` to `podman` for compatibility
## Related Skills
- [docker-management](../docker-management/) - Docker fundamentals
- [kubernetes-ops](../../orchestration/kubernetes-ops/) - K8s orchestration
- [container-hardening](../../../security/hardening/container-hardening/) - Security