Skip to content

Latest commit

 

History

History
167 lines (110 loc) · 3.95 KB

File metadata and controls

167 lines (110 loc) · 3.95 KB

Docker Build and Run Guide

The project ships with a production-ready multi-stage Dockerfile using node:20-bookworm-slim. It installs dependencies, compiles TypeScript, prunes devDependencies, then copies only the runtime artifacts into a clean final image.

Prerequisites

  • Docker installed (docker --version)
  • Optional: a .env file in project root

Build and Run

Build:

docker build -f Dockerfile -t github-stats:node .

Compose:

docker compose up --build

Run:

docker run --rm -p 3000:3000 --env-file .env github-stats:node

Open:

  • API root: http://localhost:3000/
  • Health check: http://localhost:3000/health

Note: APP_ENV must be exactly development, production, or test. Any other value (e.g. prod, staging, or extra whitespace) will fail startup validation. You can override a bad value in .env at runtime:

docker run --rm -p 3000:3000 --env-file .env -e APP_ENV=production github-stats:node

Detached Mode and Logs

Run in background:

docker run -d --name github-stats -p 3000:3000 --env-file .env github-stats:node

View logs:

docker logs -f github-stats

Compose logs:

docker compose logs -f

Stop and remove:

docker rm -f github-stats

Compose stop:

docker compose down

Important Environment Variables

Defaults are defined in src/shared/config/env.ts, so the app can run with minimal configuration. Recommended variables for production:

  • NODE_ENV=production
  • APP_ENV=production
  • PORT=3000
  • HOST=0.0.0.0
  • GITHUB_TOKEN (recommended to avoid strict GitHub API rate limits)

Optional cache and storage variables:

  • Redis: REDIS_URL (or REDIS_HOST/REDIS_PORT)
  • Database provider: DATABASE_PROVIDER, DATABASE_URL

Useful Commands

Rebuild without cache:

docker build --no-cache -f Dockerfile -t github-stats:node .

Check image size:

docker images github-stats

Releasing a New Image

1. Bump the version

Update the version field in package.json before tagging a release (current: 2.1.1).

2. Build and tag

Node.js image (Dockerfile):

docker build -t pphatdev/github-stats:2.1.1 -t pphatdev/github-stats:latest .

Bun image (Dockerfile.bun):

docker build -f Dockerfile.bun -t pphatdev/github-stats:2.1.1-bun -t pphatdev/github-stats:latest-bun .

Cross-platform tip: Add --platform linux/amd64 when building on Apple Silicon for Linux server compatibility:

docker build --platform linux/amd64 -t pphatdev/github-stats:latest .

3. Push to registry

docker push pphatdev/github-stats:2.1.1
docker push pphatdev/github-stats:latest

4. Deploy on a remote server

Pull and restart the container:

docker pull pphatdev/github-stats:latest
docker stop github-stats && docker rm github-stats
docker run -d --name github-stats -p 3000:3000 --env-file .env pphatdev/github-stats:latest

Or with Docker Compose:

docker compose pull
docker compose up -d --force-recreate

The repository includes a compose.yaml for local development and self-hosting. It starts:

  • app: the Node.js API built from the local Dockerfile
  • redis: a local Redis 7 instance for cache storage

The compose setup also forces local-safe defaults that differ from the Cloudflare deployment path:

  • DATABASE_PROVIDER=sqlite
  • DATABASE_URL=/app/data/stats.db
  • REDIS_HOST=redis

If you have a .env file with a GITHUB_TOKEN, Docker Compose will pass it through to the app container.

Notes

  • .dockerignore excludes common local artifacts (node_modules, dist, .git, .env, and more) to keep build context small.
  • The multi-stage build uses three stages: deps (install), build (npm ci + tsc + npm prune --omit=dev), and runtime (lean final image).
  • APP_ENV, NODE_ENV must each be one of development, production, or test — any other value fails startup validation.