Skip to main content
Version: Next

Docker Operations Workflow

View Source

Build, test, and publish Docker images to container registries.

Overviewโ€‹

This workflow handles complete Docker operations including building multi-architecture images, running health checks, security scanning, and publishing to Docker Hub and GitHub Container Registry (GHCR).

When to Useโ€‹

  • โœ… You need to build Docker images
  • โœ… You want to publish to Docker registries
  • โœ… You need multi-architecture support (amd64, arm64)
  • โœ… You want automated security scanning

Workflow Architectureโ€‹

Inputsโ€‹

Required Inputsโ€‹

InputTypeDescription
operationstringOperation type (build, push, test)
registrystringTarget registry (dockerhub, ghcr, both)
versionstringImage version tag

Optional Inputsโ€‹

InputTypeDefaultDescription
dockerfile_pathstring'Dockerfile'Path to Dockerfile
context_pathstring'.'Build context path
platformsstring'linux/amd64,linux/arm64'Target platforms
health_check_portstring'8000'Health check port
health_check_pathstring'/health'Health check endpoint
docker_run_optionsstring''Additional docker run options
security_scanbooleantrueRun security scanning
generate_sbombooleantrueGenerate SBOM
sign_imagebooleanfalseSign image with Cosign

Secretsโ€‹

SecretRequiredDescription
dockerhub_usernameFor DockerHubDocker Hub username
dockerhub_tokenFor DockerHubDocker Hub access token
github_tokenFor GHCRGitHub token (auto-provided)

Outputsโ€‹

OutputDescription
image_digestImage digest (SHA256)
image_tagsList of applied tags
scan_resultsSecurity scan results
sbom_pathPath to SBOM file

Usage Examplesโ€‹

Basic Build and Pushโ€‹

name: Docker

on:
push:
branches: [main]

jobs:
docker:
uses: Chisanan232/GitHub-Action_Reusable_Workflows-Python/.github/workflows/rw_docker_operations.yaml@master
secrets:
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
with:
operation: push
registry: dockerhub
version: latest

Multi-Registry Publishingโ€‹

jobs:
docker:
uses: Chisanan232/GitHub-Action_Reusable_Workflows-Python/.github/workflows/rw_docker_operations.yaml@master
secrets:
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
with:
operation: push
registry: both # Push to both DockerHub and GHCR
version: ${{ github.ref_name }}

With Security Scanningโ€‹

jobs:
docker:
uses: Chisanan232/GitHub-Action_Reusable_Workflows-Python/.github/workflows/rw_docker_operations.yaml@master
secrets:
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
with:
operation: push
registry: dockerhub
version: v1.0.0
security_scan: true
generate_sbom: true
sign_image: true

Custom Health Checkโ€‹

jobs:
docker:
uses: Chisanan232/GitHub-Action_Reusable_Workflows-Python/.github/workflows/rw_docker_operations.yaml@master
secrets:
dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
with:
operation: push
registry: ghcr
version: latest
health_check_port: '3000'
health_check_path: '/api/health'
docker_run_options: '-e NODE_ENV=production -e API_KEY=test'

How It Worksโ€‹

Step 1: Setup Docker Buildxโ€‹

Configures Docker Buildx for multi-platform builds:

- uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64,linux/arm64

Step 2: Registry Authenticationโ€‹

Logs in to target registries:

# Docker Hub
- uses: docker/login-action@v3
with:
username: ${{ secrets.dockerhub_username }}
password: ${{ secrets.dockerhub_token }}

# GHCR
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

Step 3: Build Imageโ€‹

Builds multi-architecture image:

- uses: docker/build-push-action@v5
with:
context: ${{ inputs.context_path }}
file: ${{ inputs.dockerfile_path }}
platforms: ${{ inputs.platforms }}
tags: |
user/repo:${{ inputs.version }}
user/repo:latest
push: ${{ inputs.operation == 'push' }}
cache-from: type=gha
cache-to: type=gha,mode=max

Step 4: Health Checkโ€‹

Tests container health:

docker run -d -p $PORT:$PORT $IMAGE
sleep 5
curl -f http://localhost:$PORT$PATH || exit 1

Step 5: Security Scanโ€‹

Scans for vulnerabilities:

- uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ inputs.registry }}/${{ inputs.version }}
format: 'sarif'
output: 'trivy-results.sarif'

Step 6: Generate SBOMโ€‹

Creates Software Bill of Materials:

syft $IMAGE -o spdx-json > sbom.json

Step 7: Sign Image (Optional)โ€‹

Signs image with Cosign:

cosign sign --yes $IMAGE@$DIGEST

Operation Typesโ€‹

Buildโ€‹

Build image without pushing:

operation: build
  • Builds image
  • Runs tests
  • No registry push

Pushโ€‹

Build and push to registry:

operation: push
  • Builds image
  • Runs tests
  • Pushes to registry
  • Generates SBOM
  • Signs image (if enabled)

Testโ€‹

Test existing image:

operation: test
  • Pulls image
  • Runs health checks
  • Security scanning

Registry Optionsโ€‹

Docker Hubโ€‹

registry: dockerhub

Image naming:

username/repository:version

Requirements:

  • dockerhub_username secret
  • dockerhub_token secret

GitHub Container Registryโ€‹

registry: ghcr

Image naming:

ghcr.io/owner/repository:version

Requirements:

  • GITHUB_TOKEN (auto-provided)

Both Registriesโ€‹

registry: both

Pushes to both Docker Hub and GHCR simultaneously.

Multi-Architecture Supportโ€‹

Supported Platformsโ€‹

Default platforms:

  • linux/amd64 - x86_64 architecture
  • linux/arm64 - ARM64 architecture

Custom Platformsโ€‹

platforms: 'linux/amd64,linux/arm64,linux/arm/v7'

Platform-Specific Buildsโ€‹

# AMD64 only
platforms: 'linux/amd64'

# ARM64 only
platforms: 'linux/arm64'

Best Practicesโ€‹

1. Multi-Stage Buildsโ€‹

Use multi-stage Dockerfiles:

# Build stage
FROM python:3.11-slim as builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt

# Runtime stage
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY .. .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]

2. Layer Cachingโ€‹

Optimize layer caching:

# Copy requirements first (changes less frequently)
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy code last (changes frequently)
COPY . .

3. Health Checksโ€‹

Include health check in Dockerfile:

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:8000/health || exit 1

4. Securityโ€‹

  • Use specific base image versions
  • Run as non-root user
  • Scan for vulnerabilities
  • Keep images minimal
FROM python:3.11-slim

# Create non-root user
RUN useradd -m -u 1000 appuser
USER appuser

WORKDIR /app
COPY --chown=appuser:appuser . .

CMD ["python", "app.py"]

5. Image Taggingโ€‹

Use semantic versioning:

tags: |
user/repo:${{ github.ref_name }}
user/repo:latest
user/repo:${{ github.sha }}

Troubleshootingโ€‹

Build Failsโ€‹

Symptoms:

  • Docker build errors
  • Dependency installation fails

Solutions:

  1. Check Dockerfile syntax
  2. Verify base image exists
  3. Review build logs
  4. Test build locally:
    docker build -t test .

Multi-Arch Build Failsโ€‹

Symptoms:

  • Platform-specific errors
  • QEMU errors

Solutions:

  1. Verify platform support:

    platforms: 'linux/amd64'  # Start with single platform
  2. Check base image supports target platforms

  3. Use platform-specific instructions:

    FROM --platform=$BUILDPLATFORM python:3.11-slim

Health Check Failsโ€‹

Symptoms:

  • Container starts but health check fails
  • Timeout errors

Solutions:

  1. Verify port mapping:

    health_check_port: '8000'
  2. Check health endpoint exists:

    curl http://localhost:8000/health
  3. Increase startup time:

    docker_run_options: '--health-start-period=30s'

Registry Push Failsโ€‹

Symptoms:

  • Authentication errors
  • Permission denied

Solutions:

  1. Verify credentials:

    secrets:
    dockerhub_username: ${{ secrets.DOCKERHUB_USERNAME }}
    dockerhub_token: ${{ secrets.DOCKERHUB_TOKEN }}
  2. Check repository exists

  3. Verify token permissions

Security Scanningโ€‹

Trivy Scanningโ€‹

Scans for:

  • OS vulnerabilities
  • Application dependencies
  • Misconfigurations
  • Secrets in image

SBOM Generationโ€‹

Creates Software Bill of Materials:

{
"artifacts": [
{
"name": "python",
"version": "3.11.0",
"type": "python-pkg"
}
]
}

Image Signingโ€‹

Signs images with Cosign:

# Verify signed image
cosign verify $IMAGE

Additional Resourcesโ€‹