Skip to content

feat: Phase 2 - Docker Compose Setup for Microservices#119

Merged
JacobCoffee merged 9 commits intomainfrom
feature/phase2-docker-compose
Nov 23, 2025
Merged

feat: Phase 2 - Docker Compose Setup for Microservices#119
JacobCoffee merged 9 commits intomainfrom
feature/phase2-docker-compose

Conversation

@JacobCoffee
Copy link
Owner

@JacobCoffee JacobCoffee commented Nov 23, 2025

Summary

Implements Phase 2 of the microservices migration plan: Docker Compose setup for local development and production deployment.

Changes

Docker Compose Configuration

  • docker-compose.yml: Full stack development environment

    • PostgreSQL with health checks and persistent storage
    • API service with database migrations and hot-reload
    • Bot service with API client integration
    • Service dependencies with health check conditions
    • Volume mounts for development hot-reload
    • Network isolation with byte-network
  • docker-compose.prod.yml: Production overrides

    • Resource limits and reservations
    • Restart policies with exponential backoff
    • Production-grade logging (50MB max, 5 files)
    • Configurable worker counts (4 for API)
    • No volume mounts (no hot-reload)

Health Check Endpoints

New controller: services/api/src/byte_api/domain/system/controllers/health.py

  • GET /health/ - General health check with database verification
  • GET /health/ready - Readiness probe for traffic routing (Kubernetes-compatible)
  • GET /health/live - Liveness probe for deadlock detection (Kubernetes-compatible)

Features:

  • Structured logging with context
  • Proper exception handling
  • Integration with Docker healthchecks
  • Railway/Kubernetes compatible

Makefile Commands

Added 88 lines of Docker management commands:

Service Management:

  • make docker-up - Start all services
  • make docker-down - Stop all services
  • make docker-down-volumes - Stop and remove volumes
  • make docker-rebuild - Rebuild and restart
  • make docker-restart - Restart all services
  • make docker-restart-{service} - Restart specific service

Monitoring:

  • make docker-logs - Follow all logs
  • make docker-logs-{service} - Service-specific logs
  • make docker-ps - Show service status

Shell Access:

  • make docker-shell-api - API container bash
  • make docker-shell-bot - Bot container bash
  • make docker-shell-postgres - PostgreSQL shell

Infrastructure:

  • make infra-up - Start PostgreSQL only
  • make infra-down - Stop PostgreSQL

Configuration

  • .env.docker.example: Docker-specific environment template
    • Service name-based URLs (postgres, api)
    • Development and production configurations
    • Comprehensive inline documentation

Documentation

  • docs/docker-setup.md: Comprehensive Docker guide (630 lines)

    • Prerequisites and quick start
    • Development workflow with hot-reload
    • Production deployment guide
    • 10-point testing checklist
    • Troubleshooting for common issues
    • Automated testing examples
  • README.md: Updated with Docker workflow

    • Docker as recommended development method
    • Quick start instructions
    • Link to detailed documentation

Technical Highlights

Architecture

  • Service isolation with proper health checks
  • Hot-reload enabled in development mode
  • Production-ready resource management
  • Three-tier health check strategy (liveness, readiness, health)

Developer Experience

  • Setup in <5 minutes with Docker
  • Volume mounts for live code updates
  • Structured logging across all services
  • Easy access to service shells and logs

Production Readiness

  • Multi-stage Dockerfiles (smaller images)
  • Resource limits prevent resource exhaustion
  • Automatic restart on failure
  • Kubernetes/Railway compatible

Testing

CI Checks ✅

✅ Linting (ruff check)
✅ Formatting (ruff format)
✅ Type checking (ty)
✅ All hooks (codespell, prettier, etc.)
✅ Tests (75 passed)
✅ Coverage (68.23%)

Local Testing Checklist

  • All services build successfully
  • Health endpoints return 200 OK
  • Database migrations apply successfully
  • Hot-reload works in development mode
  • Services restart successfully
  • Production configuration builds

Migration Impact

Breaking Changes

None. This PR only adds Docker Compose support. Existing uv-based local development continues to work.

New Dependencies

None. All dependencies were added in Phase 1.

Deployment

Railway deployment configuration remains compatible. Services can be deployed individually using existing Dockerfiles.

Related

Checklist

  • All CI checks pass (make ci)
  • Atomic commits (5 commits, each <5 min review)
  • Documentation updated
  • Tests passing (75/75)
  • No breaking changes
  • Follows project conventions

Commits

  1. 51c7c5b - feat: add Kubernetes-style health check endpoints
  2. f5e315a - docs: add Docker Compose environment template
  3. 42a40d6 - feat: add production Docker Compose configuration
  4. f387664 - docs: add comprehensive Docker Compose setup guide
  5. b497abe - docs: update README with Docker Compose workflow

Review Notes

This PR is designed to be reviewed in <30 minutes:

  • Each commit is atomic and independently reviewable
  • Documentation is comprehensive
  • All changes are additive (no breaking changes)
  • CI passes with good test coverage

🤖 Generated with Claude Code

Co-Authored-By: Claude noreply@anthropic.com

Summary by Sourcery

Add Docker Compose-based local and production environments, with health check endpoints and supporting tooling for the Byte microservices stack.

New Features:

  • Introduce Docker Compose configurations for running PostgreSQL, API, and bot services locally with hot-reload and service health checks.
  • Add production Docker Compose override with resource limits, logging configuration, and restart policies for deployment environments.
  • Expose Kubernetes-style health, readiness, and liveness endpoints on the API service for orchestration and monitoring.

Enhancements:

  • Expand the Makefile with convenience commands to manage Docker services, logs, shells, and infrastructure-only runs.
  • Register the new health controller in the API routing to serve dedicated system health URLs.
  • Update the README to recommend Docker as the primary development workflow and document an alternative uv-based setup.

Build:

  • Introduce Docker Compose configuration files for development and production override, including volumes, networks, and healthchecks.

Documentation:

  • Add a comprehensive Docker Compose setup guide covering configuration, workflows, production usage, troubleshooting, and testing.
  • Provide a Docker-specific environment variable template for configuring services in containerized environments.

JacobCoffee and others added 8 commits November 23, 2025 00:10
Add comprehensive Docker Compose commands for local development:
- docker-up: Start all services (PostgreSQL, API, Bot)
- docker-down: Stop all services
- docker-logs: Follow logs from services
- docker-shell-*: Shell access to containers
- docker-restart: Restart services
- docker-rebuild: Rebuild and restart
- infra-up/down: Start/stop PostgreSQL only

These commands enable developers to easily work with Docker Compose
for local development and testing.

Part of Phase 2: Docker Compose infrastructure setup.
Add detailed documentation for Docker Compose development setup:
- Architecture overview and service diagrams
- Quick start guide
- Complete Makefile command reference
- Development workflows and debugging tips
- Infrastructure-only mode for local development
- Hot-reload configuration and troubleshooting
- Best practices and production warnings

The documentation is written in Sphinx RST format and integrated
into the existing documentation structure.

Part of Phase 2: Docker Compose infrastructure setup.
Add docker-compose.yml for local development with all services:

Services:
- PostgreSQL 15 Alpine with health checks and persistent volume
- API service built from services/api/Dockerfile
  - Hot-reload enabled via volume mounts
  - Auto-runs migrations on startup
  - Exposed on port 8000
- Bot service built from services/bot/Dockerfile
  - Hot-reload enabled via volume mounts
  - Connects to API service

Features:
- Health checks for all services with proper dependencies
- Volume mounts for hot-reload (delegated mode for performance)
- Shared byte-network bridge network
- Logging configuration (JSON driver, 10MB max, 3 files)
- Environment variable injection from .env file

This enables developers to run the entire stack with 'make docker-up'
and have a fully functional development environment with hot-reload.

Part of Phase 2: Docker Compose infrastructure setup.
Add dedicated health check controller with three endpoints designed for
container orchestration:

- `/health/` - General health check with database verification
- `/health/ready` - Readiness probe for traffic routing
- `/health/live` - Liveness probe for deadlock detection

This complements the existing `/system/health` endpoint which provides
more comprehensive system status including bot connectivity.

Used by Docker Compose healthchecks and suitable for Kubernetes
deployments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Create .env.docker.example with Docker-specific configuration:
- Uses service names (postgres, api) instead of localhost
- Optimized defaults for containerized environments
- Clear documentation for required credentials
- Production override examples

Users can copy this to .env for local Docker development.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Create docker-compose.prod.yml with production-optimized settings:

Configuration changes:
- Disable debug mode and reduce logging verbosity
- Remove volume mounts for hot-reload
- Configure resource limits and reservations
- Add restart policies with backoff
- Remove exposed ports for internal-only services
- Use production-grade logging (50MB max, 5 files)

Worker configuration:
- API: 4 workers (configurable via SERVER_HTTP_WORKERS)
- Database: Resource limits for stability
- Bot: Automatic restart on failure

Usage:
  docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d

Suitable for Railway, staging, and production deployments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Create detailed documentation covering:

Development workflow:
- Quick start instructions
- Hot reload configuration
- Database migrations
- Service shell access
- Debugging and troubleshooting

Production deployment:
- Production compose file usage
- Railway deployment guide
- Environment configuration
- Resource management

Testing procedures:
- 10-point testing checklist
- Health check verification
- Inter-service communication tests
- Automated test script example

Common troubleshooting:
- Build failures
- Connection issues
- Port conflicts
- Migration problems

Completes Phase 2.2 documentation requirements.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Add Docker as the primary development method:

Changes:
- Add Quick Start with Docker section
- Include docker-up commands and service URLs
- Link to comprehensive Docker documentation
- Reorganize development section for clarity
- Keep uv local development as alternative

Makes Docker Compose the recommended approach for new contributors
while maintaining flexibility for local development preferences.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@railway-app
Copy link

railway-app bot commented Nov 23, 2025

🚅 Deployed to the byte-pr-119 environment in byte

Service Status Web Updated (UTC)
byte ◻️ Removed (View Logs) Web Nov 23, 2025 at 6:56 am

@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Nov 23, 2025

Reviewer's Guide

Adds a full Docker Compose-based local and production environment for the microservices stack, introduces Kubernetes-style health endpoints in the API, extends the Makefile with Docker management commands, and updates env templates and documentation to make Docker the recommended development workflow.

Sequence diagram for API health check endpoint with database verification and Docker healthcheck

sequenceDiagram
  actor Dev as "Developer or Orchestrator"
  participant Docker as "Docker Healthcheck"
  participant API as "API Container (Uvicorn + Litestar)"
  participant HC as "HealthController"
  participant DB as "Postgres"

  Dev->>Docker: "Configure healthcheck 'GET http://localhost:8000/health'"

  loop "Periodic health probe"
    Docker->>API: "HTTP GET /health/"
    API->>HC: "Dispatch to 'health_check' handler"
    HC->>DB: "Execute 'SELECT 1' via AsyncSession"
    alt "Database reachable"
      DB-->>HC: "Result OK"
      HC-->>API: "Response {status: 'ok', database: 'healthy'} (200)"
      API-->>Docker: "HTTP 200 OK"
      Docker-->>Dev: "Service marked 'healthy'"
    else "Database unreachable or error"
      DB-->>HC: "Raises exception"
      HC-->>API: "Response {status: 'degraded', database: 'unhealthy'} (503)"
      API-->>Docker: "HTTP 503 Service Unavailable"
      Docker-->>Dev: "Service marked 'unhealthy' after retries"
    end
  end
Loading

File-Level Changes

Change Details Files
Introduce Docker Compose configurations for development and production microservices stack.
  • Add docker-compose.yml with postgres, api, and bot services wired via a shared network, health checks, logging, and dev-time volume mounts with hot-reload commands.
  • Add docker-compose.prod.yml as an override with resource limits, production environment variables, hardened logging, restart policies, and no dev volumes or hot reload.
  • Define persistent volumes and network isolation for the stack, including a bound production postgres data volume path.
docker-compose.yml
docker-compose.prod.yml
Add health-check controller with liveness, readiness, and general health endpoints and integrate into routing.
  • Create HealthController with /health/, /health/ready, and /health/live endpoints using Litestar, structured logging, and database connectivity checks for general health and readiness.
  • Configure health routes to be auth-exempt and use database session to drive 200 vs 503 responses for orchestration systems.
  • Register HealthController in the domain routes and controllers init, and adjust existing SYSTEM_HEALTH URL constant to a namespaced /system/health path.
services/api/src/byte_api/domain/system/controllers/health.py
services/api/src/byte_api/domain/system/controllers/__init__.py
services/api/src/byte_api/domain/__init__.py
services/api/src/byte_api/domain/urls.py
Extend Makefile with Docker/Compose management targets for services and infrastructure.
  • Add docker-up/down, logs, ps, restart, and rebuild targets wrapping docker compose commands for the full stack.
  • Add service-specific log, restart, and shell targets for API, bot, and postgres containers to streamline debugging.
  • Add infra-up/infra-down targets for running only the postgres infrastructure compose file.
Makefile
Provide Docker-specific environment template and comprehensive Docker documentation and wire into main README.
  • Add .env.docker.example with service-name-based URLs and documented configuration for dev/prod Docker usage.
  • Create docs/docker-setup.md as an end-to-end guide covering prerequisites, workflows, production overrides, troubleshooting, and testing of the Docker stack, plus a stub docker-compose.rst for Sphinx docs.
  • Update README to recommend Docker as the primary dev path, adding a Docker quick start and clarifying alternate uv/nixpacks workflows.
.env.docker.example
docs/docker-setup.md
docs/docker-compose.rst
README.md
docs/index.rst

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@railway-app railway-app bot temporarily deployed to byte (byte / byte-pr-119) November 23, 2025 06:48 Destroyed
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

Blocking issues:

  • Identified a Discord client ID, which may lead to unauthorized integrations and data exposure in Discord applications. (link)
  • Identified a Discord client ID, which may lead to unauthorized integrations and data exposure in Discord applications. (link)

General comments:

  • In docker-compose.prod.yml, the api service command is split across lines inside the YAML string, which is likely to be parsed incorrectly by Compose; consider making the entire shell command a single line or using a properly quoted multi-line literal.
  • There are now two different health URL conventions (/system/health via SYSTEM_HEALTH and the new /health*/ endpoints on HealthController); it may be worth consolidating these paths or clearly separating their responsibilities to avoid confusion in clients and future routing changes.
  • The tooling and docs mix both docker compose and docker-compose invocations (e.g., Makefile vs docs/docker-setup.md), so standardizing on one form would make the developer experience more consistent.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In docker-compose.prod.yml, the api service command is split across lines inside the YAML string, which is likely to be parsed incorrectly by Compose; consider making the entire shell command a single line or using a properly quoted multi-line literal.
- There are now two different health URL conventions (/system/health via SYSTEM_HEALTH and the new /health*/ endpoints on HealthController); it may be worth consolidating these paths or clearly separating their responsibilities to avoid confusion in clients and future routing changes.
- The tooling and docs mix both `docker compose` and `docker-compose` invocations (e.g., Makefile vs docs/docker-setup.md), so standardizing on one form would make the developer experience more consistent.

## Individual Comments

### Comment 1
<location> `services/api/src/byte_api/domain/system/controllers/health.py:128-129` </location>
<code_context>
+        Returns:
+            Response with alive status (always 200 unless service is completely dead).
+        """
+        logger.debug("Liveness check passed")
+        return Response(
+            content={"status": "alive"},
</code_context>

<issue_to_address>
**suggestion (performance):** Debug logging on every liveness probe may cause unnecessary log noise.

Since liveness probes can run every few seconds, this log will be emitted very frequently and may clutter logs in production. Consider removing it, making it even more conditional (e.g., behind a config flag), or otherwise ensuring it doesn’t produce unnecessary noise under normal operation.

```suggestion
        return Response(
```
</issue_to_address>

### Comment 2
<location> `docs/docker-compose.rst:514` </location>
<code_context>
+Environment Variables
+~~~~~~~~~~~~~~~~~~~~~
+
+The Docker Compose setup uses environment variables from ``.env`` file:
+
+**Required for API**:
</code_context>

<issue_to_address>
**nitpick (typo):** Minor grammar improvement: add "the" before ``.env``.

Consider phrasing this as "from the `.env` file:" for smoother reading.

```suggestion
The Docker Compose setup uses environment variables from the ``.env`` file:
```
</issue_to_address>

### Comment 3
<location> `docs/docker-compose.rst:535` </location>
<code_context>
123456789012345678
</code_context>

<issue_to_address>
**security (discord-client-id):** Identified a Discord client ID, which may lead to unauthorized integrations and data exposure in Discord applications.

*Source: gitleaks*
</issue_to_address>

### Comment 4
<location> `docs/docker-compose.rst:536` </location>
<code_context>
123456789012345678
</code_context>

<issue_to_address>
**security (discord-client-id):** Identified a Discord client ID, which may lead to unauthorized integrations and data exposure in Discord applications.

*Source: gitleaks*
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@railway-app railway-app bot temporarily deployed to byte (byte / byte-pr-119) November 23, 2025 06:53 Destroyed
@JacobCoffee JacobCoffee merged commit 9e5550b into main Nov 23, 2025
4 of 5 checks passed
@JacobCoffee JacobCoffee deleted the feature/phase2-docker-compose branch November 23, 2025 06:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant