Docker Deployment
Deploy ZeroStarter with Docker and Docker Compose.
Overview
ZeroStarter includes Docker configurations for both development and production deployments. This guide covers running the application with Docker Compose and building individual Docker images.
Quick Start
Run the entire stack with Docker Compose:
docker compose upThis starts both the frontend (Next.js) and backend (Hono) services:
- Frontend: http://localhost:3000
- Backend: http://localhost:4000
Docker Compose Configuration
The docker-compose.yml file defines two services:
services:
api:
build:
context: .
dockerfile: api/hono/Dockerfile
env_file:
- .env
environment:
- INTERNAL_API_URL=http://api:4000
ports:
- "4000:4000"
web:
build:
context: .
dockerfile: web/next/Dockerfile
env_file:
- .env
environment:
- INTERNAL_API_URL=http://api:4000
ports:
- "3000:3000"Key Configuration
| Setting | Description |
|---|---|
context: . | Build context is the repository root (for monorepo access) |
env_file: .env | Loads environment variables from root .env file |
INTERNAL_API_URL | Internal service-to-service communication URL |
Building Individual Images
Backend (Hono API)
docker build -f api/hono/Dockerfile -t zerostarter-api .
docker run -p 4000:4000 --env-file .env zerostarter-apiFrontend (Next.js)
docker build -f web/next/Dockerfile -t zerostarter-web .
docker run -p 3000:3000 --env-file .env zerostarter-webEnvironment Variables
Ensure your .env file contains all required variables before building:
NODE_ENV=production
# Server variables
HONO_APP_URL=http://localhost:4000
HONO_TRUSTED_ORIGINS=http://localhost:3000
BETTER_AUTH_SECRET=your_secret
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
POSTGRES_URL=your_postgres_url
# Client variables
NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_API_URL=http://localhost:4000Internal Communication
When running with Docker Compose, services communicate using Docker's internal network:
- The
webservice connects toapiusinghttp://api:4000(service name resolution) - External clients connect using the mapped ports (
localhost:3000,localhost:4000)
The INTERNAL_API_URL environment variable enables server-side rendering to communicate directly with the API container without going through the public network.
Production Considerations
Database Connection
For production, use a managed PostgreSQL service:
Note: This project requires PostgreSQL. MySQL-compatible providers like PlanetScale are not supported without substantial rework (schema migration, SQL/driver changes).
Container Registry
Push images to a container registry for deployment:
# Tag and push to Docker Hub
docker tag zerostarter-api username/zerostarter-api:latest
docker push username/zerostarter-api:latest
# Or use GitHub Container Registry
docker tag zerostarter-api ghcr.io/username/zerostarter-api:latest
docker push ghcr.io/username/zerostarter-api:latestHealth Checks
The API includes a health check endpoint:
curl http://localhost:4000/api/healthAdd health checks to your Docker Compose for production:
services:
api:
# ... other config
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:4000/api/health"]
interval: 30s
timeout: 10s
retries: 3Development with Docker
For development, you might prefer running services locally with bun dev for hot reloading. Use Docker Compose primarily for:
- Testing production builds locally
- CI/CD pipelines
- Consistent environments across team members
- Deploying to container orchestration platforms (Kubernetes, ECS, etc.)
Troubleshooting
Port Already in Use
# Find and kill process using port 3000
lsof -i :3000
kill -9 <PID>
# Or use different ports
docker compose up -d
docker compose run -p 3001:3000 webBuild Cache Issues
# Rebuild without cache
docker compose build --no-cache
# Remove all containers and volumes
docker compose down -vEnvironment Variable Issues
# Verify env vars are loaded
docker compose config
# Run with explicit env file
docker compose --env-file .env.production up