Docker Architecture
Document: 26-docker-architecture.md
Version: 1.0.0
Purpose
This document defines the containerization strategy used across all Rundown projects.
Docker provides a standardized runtime environment that ensures applications behave consistently across development, staging, and production. By packaging applications and their dependencies into containers, Rundown achieves predictable deployments, simplified infrastructure management, and improved portability.
Docker Philosophy
Docker exists to guarantee environment consistency.
Applications should run identically regardless of where they are deployed.
Containers package the application and its dependencies, eliminating differences between local development and production environments.
Responsibilities
Docker owns:
-
Application runtime
-
Dependency isolation
-
Container networking
-
Service orchestration
-
Reproducible environments
Non-Responsibilities
Docker should not own:
-
Business logic
-
Deployment decisions
-
Infrastructure architecture
-
DNS
-
SSL
-
Application configuration
Docker provides the runtime—not the application.
Standard Container Stack
Every Rundown application follows this structure:
Ubuntu LTS
│
Docker Engine
│
Coolify
│
Docker Compose
│
Application Containers
Each layer has a distinct responsibility.
Container Philosophy
Containers should be:
-
Stateless
-
Disposable
-
Reproducible
-
Independent
Persistent data should always exist outside the application container.
Containers should be replaceable at any time without data loss.
Standard Services
A typical Rundown project consists of:
Application
(PostgreSQL)
(Optional Redis)
(Optional Background Worker)
Additional services should only be introduced when justified by project requirements.
Docker Compose
Docker Compose defines the complete application stack.
It is the canonical description of:
-
Services
-
Networks
-
Volumes
-
Dependencies
Every Rundown project should maintain a version-controlled docker-compose.yml.
Infrastructure should be reproducible from this file.
Volumes
Persistent data should be stored using Docker volumes.
Typical persistent volumes include:
-
PostgreSQL data
-
Logs
-
Temporary uploads (when required)
Application source code should not be treated as persistent storage.
Networks
Containers should communicate through private Docker networks.
Only services requiring public access should expose ports externally.
Internal services should remain isolated.
Images
Application images should:
-
Be reproducible.
-
Be versioned.
-
Use multi-stage builds where appropriate.
-
Minimize unnecessary dependencies.
Smaller images improve deployment speed and security.
Environment Variables
Container configuration should be provided through environment variables.
Containers should never contain environment-specific configuration baked into the image.
The same image should be deployable across every environment.
Logging
Containers should write logs to standard output.
Log aggregation and retention should be handled by the hosting environment rather than individual containers.
Health Checks
Critical services should define health checks.
Health checks enable:
-
Automatic recovery
-
Reliable deployments
-
Improved monitoring
Application availability should not depend solely on process startup.
Restart Policies
Production containers should automatically restart after unexpected failures.
Restart policies improve application availability without requiring manual intervention.
Development Workflow
Local development should use the same container definitions as production whenever practical.
Differences should be limited to:
-
Debugging tools
-
Local configuration
-
Development credentials
Maintaining parity reduces deployment issues.
Engineering Decision
Container Standardization
Status: Accepted
Decision
All Rundown production applications are containerized using Docker and orchestrated through Docker Compose.
Coolify serves as the deployment platform but does not replace Docker Compose as the source of infrastructure definition.
Reasoning
This architecture:
-
Ensures reproducible deployments.
-
Simplifies migrations.
-
Supports disaster recovery.
-
Maintains environment consistency.
-
Reduces operational complexity.
Docker Checklist
Before deploying a containerized application, verify:
-
Docker Compose defines all services.
-
Persistent data uses volumes.
-
Environment variables are externalized.
-
Health checks are configured.
-
Restart policies are enabled.
-
Images use optimized builds.
-
Internal networking is isolated.
Summary
Docker provides the standardized runtime foundation for every Rundown application.
By treating containers as disposable execution environments and Docker Compose as the authoritative infrastructure definition, Rundown achieves predictable deployments, environment consistency, and operational simplicity across all projects.
Related Documents
Related ADRs
- ADR-003: Documentation Information Architecture