Skip to content

Commit 9e5550b

Browse files
JacobCoffeeclaude
andauthored
feat: Phase 2 - Docker Compose Setup for Microservices (#119)
Co-authored-by: Claude <[email protected]>
1 parent f9fba4b commit 9e5550b

File tree

12 files changed

+1934
-3
lines changed

12 files changed

+1934
-3
lines changed

.env.docker.example

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# =============================================================================
2+
# Docker Compose Environment Variables
3+
# =============================================================================
4+
# Copy this file to `.env` in the project root for Docker Compose development.
5+
# These settings are optimized for containerized environments.
6+
7+
# --- Discord Settings ---
8+
# Obtain these from Discord Developer Portal: https://discord.com/developers/applications
9+
DISCORD_TOKEN=your_discord_bot_token_here
10+
DISCORD_DEV_GUILD_ID=your_dev_guild_id_here
11+
DISCORD_DEV_USER_ID=your_user_id_here
12+
13+
# --- Database Settings ---
14+
# Docker Compose uses the postgres service name as host
15+
DB_URL=postgresql+asyncpg://byte:bot@postgres:5432/byte
16+
DB_USER=byte
17+
DB_PASSWORD=bot
18+
DB_HOST=postgres
19+
DB_PORT=5432
20+
DB_NAME=byte
21+
DB_ECHO=False
22+
DB_ECHO_POOL=False
23+
DB_POOL_DISABLE=False
24+
25+
# --- API Service Settings ---
26+
# Used by bot service to communicate with API service
27+
API_SERVICE_URL=http://api:8000
28+
29+
# --- Server Settings ---
30+
SERVER_HOST=0.0.0.0
31+
SERVER_PORT=8000
32+
SERVER_HTTP_WORKERS=1
33+
34+
# --- Application Settings ---
35+
ENVIRONMENT=dev
36+
DEBUG=True
37+
LOG_LEVEL=10
38+
SECRET_KEY=generate_a_secure_secret_key_for_production
39+
40+
# --- GitHub Integration ---
41+
# Required for GitHub issue creation and linking features
42+
# Create a GitHub App: https://docs.github.com/en/apps/creating-github-apps
43+
GITHUB_APP_ID=your_github_app_id
44+
GITHUB_APP_CLIENT_ID=your_github_app_client_id
45+
GITHUB_APP_CLIENT_SECRET=your_github_app_client_secret
46+
GITHUB_APP_PRIVATE_KEY=your_github_app_private_key_pem_format
47+
48+
# --- Optional: External APIs ---
49+
POLAR_KEY=optional_polar_api_key
50+
OPENCOLLECTIVE_KEY=optional_opencollective_api_key
51+
52+
# --- Production Overrides (for docker-compose.prod.yml) ---
53+
# Uncomment and configure for production deployments
54+
# ENVIRONMENT=prod
55+
# DEBUG=False
56+
# LOG_LEVEL=20
57+
# SERVER_HTTP_WORKERS=4
58+
# DB_POOL_DISABLE=False

Makefile

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ UV ?= uv $(UV_OPTS)
1616
.PHONY: fmt-fix test coverage check-all lint fmt-check
1717
.PHONY: docs-install docs-clean docs-serve docs-build
1818
.PHONY: clean run-dev-frontend run-dev-server production develop destroy
19+
.PHONY: docker-up docker-down docker-logs docker-shell-api docker-shell-bot docker-ps
20+
.PHONY: docker-restart docker-rebuild infra-up infra-down
1921

2022
help: ## Display this help text for Makefile
2123
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
@@ -154,6 +156,92 @@ migrate: ## Apply database migrations
154156
db: ## Run the database
155157
@docker compose -f "docker-compose.infra.yml" up -d --build
156158

159+
# =============================================================================
160+
# Docker Compose Commands
161+
# =============================================================================
162+
163+
.PHONY: docker-up
164+
docker-up: ## Start all services (PostgreSQL, API, Bot) with Docker Compose
165+
@echo "=> Starting all services with Docker Compose"
166+
@docker compose up -d --build
167+
@echo "=> All services started. API: http://localhost:8000"
168+
169+
.PHONY: docker-down
170+
docker-down: ## Stop all Docker Compose services
171+
@echo "=> Stopping all Docker Compose services"
172+
@docker compose down
173+
@echo "=> All services stopped"
174+
175+
.PHONY: docker-down-volumes
176+
docker-down-volumes: ## Stop all services and remove volumes
177+
@echo "=> Stopping all services and removing volumes"
178+
@docker compose down -v
179+
@echo "=> All services stopped and volumes removed"
180+
181+
.PHONY: docker-logs
182+
docker-logs: ## Follow logs from all Docker Compose services
183+
@docker compose logs -f
184+
185+
.PHONY: docker-logs-api
186+
docker-logs-api: ## Follow logs from API service
187+
@docker compose logs -f api
188+
189+
.PHONY: docker-logs-bot
190+
docker-logs-bot: ## Follow logs from bot service
191+
@docker compose logs -f bot
192+
193+
.PHONY: docker-logs-postgres
194+
docker-logs-postgres: ## Follow logs from PostgreSQL service
195+
@docker compose logs -f postgres
196+
197+
.PHONY: docker-shell-api
198+
docker-shell-api: ## Open shell in API container
199+
@docker compose exec api /bin/bash
200+
201+
.PHONY: docker-shell-bot
202+
docker-shell-bot: ## Open shell in bot container
203+
@docker compose exec bot /bin/bash
204+
205+
.PHONY: docker-shell-postgres
206+
docker-shell-postgres: ## Open PostgreSQL shell
207+
@docker compose exec postgres psql -U byte -d byte
208+
209+
.PHONY: docker-restart
210+
docker-restart: ## Restart all Docker Compose services
211+
@echo "=> Restarting all services"
212+
@docker compose restart
213+
@echo "=> All services restarted"
214+
215+
.PHONY: docker-restart-api
216+
docker-restart-api: ## Restart API service
217+
@docker compose restart api
218+
219+
.PHONY: docker-restart-bot
220+
docker-restart-bot: ## Restart bot service
221+
@docker compose restart bot
222+
223+
.PHONY: docker-ps
224+
docker-ps: ## Show status of Docker Compose services
225+
@docker compose ps
226+
227+
.PHONY: docker-rebuild
228+
docker-rebuild: ## Rebuild and restart all services
229+
@echo "=> Rebuilding all services"
230+
@docker compose up -d --build --force-recreate
231+
@echo "=> All services rebuilt and restarted"
232+
233+
.PHONY: infra-up
234+
infra-up: ## Start only PostgreSQL infrastructure
235+
@echo "=> Starting PostgreSQL infrastructure"
236+
@docker compose -f docker-compose.infra.yml up -d
237+
@echo "=> PostgreSQL started on localhost:5432"
238+
239+
.PHONY: infra-down
240+
infra-down: ## Stop PostgreSQL infrastructure
241+
@echo "=> Stopping PostgreSQL infrastructure"
242+
@docker compose -f docker-compose.infra.yml down
243+
@echo "=> PostgreSQL stopped"
244+
157245
# =============================================================================
158246
# Main
159247
# =============================================================================

README.md

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,54 @@ Byte is currently deployed to [Railway][railway] for both the bot and the web se
3939

4040
## Development
4141

42-
You can use the provided [nixpack][nixpacks] [file](./nixpacks.toml), or set up your environment using [uv][uv].
42+
Byte Bot uses a microservices architecture with Docker Compose for local development.
43+
44+
### Quick Start with Docker (Recommended)
45+
46+
```bash
47+
# 1. Clone the repository
48+
git clone https://github.com/JacobCoffee/byte.git
49+
cd byte
50+
51+
# 2. Configure environment
52+
cp .env.docker.example .env
53+
# Edit .env with your Discord token and other credentials
54+
55+
# 3. Start all services
56+
make docker-up
57+
58+
# 4. Access the application
59+
# API: http://localhost:8000
60+
# API Docs: http://localhost:8000/api/swagger
61+
```
62+
63+
**📚 Full Docker Guide**: See [docs/docker-setup.md](docs/docker-setup.md) for comprehensive documentation including:
64+
65+
- Configuration options
66+
- Development workflow with hot-reload
67+
- Database migrations
68+
- Troubleshooting
69+
- Production deployment
70+
71+
### Local Development with uv
72+
73+
For development without Docker:
74+
75+
```bash
76+
# Install dependencies
77+
uv sync
78+
79+
# Start PostgreSQL (via Docker)
80+
make infra-up
81+
82+
# Run database migrations
83+
uv run app database upgrade
84+
85+
# Start services
86+
make run-dev # Runs bot + web + frontend watcher
87+
```
88+
89+
**Alternative**: Use the provided [nixpack][nixpacks] [file](./nixpacks.toml) for Nixpacks-based deployments.
4390

4491
## Contributing
4592

docker-compose.prod.yml

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
version: "3.9"
2+
3+
# =============================================================================
4+
# Production Docker Compose Override
5+
# =============================================================================
6+
# This file provides production-specific configuration that overrides the
7+
# base docker-compose.yml settings.
8+
#
9+
# Usage:
10+
# docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
11+
#
12+
# Or set via environment:
13+
# export COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml
14+
# docker-compose up -d
15+
#
16+
# This file should be used for:
17+
# - Railway deployments
18+
# - Production environments
19+
# - Staging environments
20+
# =============================================================================
21+
22+
services:
23+
postgres:
24+
# Production PostgreSQL configuration
25+
environment:
26+
# Use strong passwords from environment/secrets
27+
POSTGRES_PASSWORD: ${DB_PASSWORD:-changeme}
28+
volumes:
29+
# Use named volume for data persistence
30+
- pgdata-prod:/var/lib/postgresql/data
31+
# Remove port exposure in production (internal only)
32+
ports: []
33+
logging:
34+
driver: "json-file"
35+
options:
36+
max-size: "50m"
37+
max-file: "5"
38+
deploy:
39+
resources:
40+
limits:
41+
cpus: "2.0"
42+
memory: 2G
43+
reservations:
44+
cpus: "1.0"
45+
memory: 1G
46+
47+
api:
48+
# Production API service configuration
49+
environment:
50+
# Production environment settings
51+
- ENVIRONMENT=prod
52+
- DEBUG=False
53+
- LOG_LEVEL=20
54+
- SERVER_HTTP_WORKERS=${SERVER_HTTP_WORKERS:-4}
55+
- DB_POOL_DISABLE=False
56+
- DB_URL=${DB_URL}
57+
- SECRET_KEY=${SECRET_KEY}
58+
- GITHUB_APP_ID=${GITHUB_APP_ID}
59+
- GITHUB_APP_PRIVATE_KEY=${GITHUB_APP_PRIVATE_KEY}
60+
- GITHUB_APP_CLIENT_ID=${GITHUB_APP_CLIENT_ID}
61+
- GITHUB_APP_CLIENT_SECRET=${GITHUB_APP_CLIENT_SECRET}
62+
# Remove volume mounts (no hot-reload in production)
63+
volumes: []
64+
# Production command without reload
65+
command:
66+
sh -c "alembic upgrade head && uvicorn byte_api.app:create_app --factory --host 0.0.0.0 --port 8000 --workers
67+
${SERVER_HTTP_WORKERS:-4}"
68+
logging:
69+
driver: "json-file"
70+
options:
71+
max-size: "50m"
72+
max-file: "5"
73+
deploy:
74+
resources:
75+
limits:
76+
cpus: "2.0"
77+
memory: 2G
78+
reservations:
79+
cpus: "0.5"
80+
memory: 512M
81+
restart_policy:
82+
condition: on-failure
83+
delay: 5s
84+
max_attempts: 3
85+
window: 120s
86+
87+
bot:
88+
# Production bot service configuration
89+
environment:
90+
# Production environment settings
91+
- DISCORD_TOKEN=${DISCORD_TOKEN}
92+
- DISCORD_DEV_GUILD_ID=${DISCORD_DEV_GUILD_ID:-}
93+
- DISCORD_DEV_USER_ID=${DISCORD_DEV_USER_ID:-}
94+
- API_SERVICE_URL=http://api:8000
95+
- ENVIRONMENT=prod
96+
- LOG_LEVEL=20
97+
# Remove volume mounts (no hot-reload in production)
98+
volumes: []
99+
logging:
100+
driver: "json-file"
101+
options:
102+
max-size: "50m"
103+
max-file: "5"
104+
deploy:
105+
resources:
106+
limits:
107+
cpus: "1.0"
108+
memory: 1G
109+
reservations:
110+
cpus: "0.25"
111+
memory: 256M
112+
restart_policy:
113+
condition: on-failure
114+
delay: 5s
115+
max_attempts: 3
116+
window: 120s
117+
118+
volumes:
119+
pgdata-prod:
120+
driver: local
121+
driver_opts:
122+
type: none
123+
o: bind
124+
# Bind to persistent storage location
125+
# Update this path based on your deployment environment
126+
device: /var/lib/byte/postgres-data

0 commit comments

Comments
 (0)