Build and deploy Docker images in the monorepo - platform targeting, GHCR integration, and container optimization. Use this skill when working with Docker.
This skill covers Docker workflows in the monorepo, including multi-stage builds, platform targeting, GitHub Container Registry (GHCR) integration, and container optimization.
See tool-execution-model for when to run Docker directly vs. Nx wrappers.
The monorepo uses Docker for:
applications/caelundas/
Dockerfile # Single-stage build (runs TypeScript directly)
.dockerignore # Exclude node_modules, etc.
Caelundas uses a single-stage build that runs TypeScript directly via pnpm (no compilation step):
# Base Image - Alpine for minimal size
FROM node:22.20.0-alpine
# Install build tools needed for native modules like sqlite3
RUN apk add --no-cache python3 make g++
# Setup Environment
WORKDIR /app
RUN npm install -g pnpm
# Install Dependencies (layer caching - copy package files first)
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
COPY applications/caelundas/package.json ./applications/caelundas/
RUN pnpm install --filter caelundas
# Copy Source Code (entire monorepo for workspace resolution)
COPY . .
# Run the application
WORKDIR /app/applications/caelundas
CMD ["pnpm", "start"]
tsx/ts-nodepython3 make g++ required for sqlite3 native module compilationpnpm install --filter caelundas installs only the app's dependenciesApple Silicon Macs (M1/M2) use arm64 architecture, but Kubernetes clusters often run amd64. Building images on Apple Silicon without platform targeting creates incompatible images.
# Single platform
docker build --platform linux/amd64 -t caelundas:latest .
# Multi-platform (if needed)
docker buildx build --platform linux/amd64,linux/arm64 -t caelundas:latest .
{
"targets": {
"docker-build": {
"executor": "nx:run-commands",
"options": {
"command": "docker build --platform linux/amd64 -t ghcr.io/jimmypaolini/caelundas:latest .",
"cwd": "applications/caelundas"
}
}
}
}
Check image platform:
docker inspect ghcr.io/jimmypaolini/caelundas:latest | jq '.[0].Architecture'
# Should output: "amd64"
# Login with personal access token
echo $GITHUB_TOKEN | docker login ghcr.io -u USERNAME --password-stdin
# Or use GitHub CLI
gh auth token | docker login ghcr.io -u USERNAME --password-stdin
# Latest tag (main branch)
ghcr.io/jimmypaolini/caelundas:latest
# Version tag (semantic version)
ghcr.io/jimmypaolini/caelundas:v1.2.3
# Commit SHA tag (CI builds)
ghcr.io/jimmypaolini/caelundas:sha-abc1234
# Branch tag (feature branches)
ghcr.io/jimmypaolini/caelundas:feat-new-feature
# Tag image
docker tag caelundas:latest ghcr.io/jimmypaolini/caelundas:latest
# Push to registry
docker push ghcr.io/jimmypaolini/caelundas:latest
# Pull from GHCR
docker pull ghcr.io/jimmypaolini/caelundas:latest
# Run locally
docker run ghcr.io/jimmypaolini/caelundas:latest
# docker-compose.yml