Docker Deployment
Relevant source files
The following files were used as context for generating this wiki page:The Kodus Runtime project utilizes Docker and Docker Compose as the recommended method for setting up and running the entire application stack. This approach encapsulates the API, dashboard, and data persistence layer into manageable containers, providing a consistent environment for both production and development. The setup is managed through a combination of docker-compose files, shell scripts, and NPM scripts.
This document details the architecture, services, configuration, and usage of the Docker deployment for Kodus Runtime. It covers both the production and development environments, which are defined in separate compose files.
Architecture Overview
The Docker environment consists of three main services orchestrated by Docker Compose: api, dashboard, and a placeholder database service. Data persistence is achieved through a shared Docker volume.
The following diagram illustrates the high-level architecture of the production deployment.
This diagram shows that the user interacts with the kodus-dashboard service on port 80. The dashboard, served by Nginx, handles static content and proxies API requests to the kodus-api service. The API service uses an embedded Sled database, which persists its data to the data volume.
Sources: tools/docker/docker-compose.yml, tools/docker/nginx.conf:60-70
Docker Services
The application stack is defined by services in docker-compose.yml for production and docker-compose.dev.yml for development.
| Service | Container Name (Prod/Dev) | Description | Ports (Prod/Dev) |
|---|---|---|---|
api | kodus-api / kodus-api-dev | The Node.js/Elysia backend API. It handles event processing and persistence. | 3201:3201 |
dashboard | kodus-dashboard / kodus-dashboard-dev | The React frontend. In production, it's served by Nginx. In development, it uses Vite's dev server. | 80:80 / 5173:5173 |
database | kodus-database / kodus-database-dev | A placeholder service to represent the data layer. The actual database (Sled) is embedded in the api service. | N/A |
Sources: tools/docker/docker-compose.yml:4-53, tools/docker/docker-compose.dev.yml:6-57
API Service (api)
The api service runs the Node.js backend. It is responsible for all business logic, authentication, and data persistence.
- Build: Uses
tools/docker/Dockerfile.apifor production andDockerfile.api.devfor development. - Persistence: It mounts a local
./datadirectory to/app/datainside the container, where the embedded Sled database writes its files. - Configuration: A local
config.jsonis mounted to/app/config.json. - Healthcheck: A healthcheck is configured to poll the
/healthendpoint.
Sources: tools/docker/docker-compose.yml:7-27, tools/docker/docker-compose.dev.yml:9-29
Dashboard Service (dashboard)
The dashboard service provides the user interface. Its setup differs significantly between production and development.
-
Production (
docker-compose.yml):- Builds a production image using
Dockerfile.dashboard. - Exposes port
80. - The underlying
nginx.confproxies all requests starting with/api/to theapiservice. - It serves the static React application files and handles client-side routing.
# Proxy API calls to the API container location /api/ { proxy_pass http://api:3201/; proxy_set_header Host $host; # ... other headers }Sources: tools/docker/docker-compose.yml:31-43, tools/docker/nginx.conf:60-70
- Builds a production image using
-
Development (
docker-compose.dev.yml):- Uses Vite's development server for hot-reloading.
- Exposes port
5173. - The entire project directory is mounted as a volume to reflect code changes instantly.
Database Service (database)
This service is a placeholder and does not run an active database process. Its purpose is to formally associate the data volume within the Docker Compose structure. The command echo 'Database uses Sled embedded in API' && sleep infinity confirms its passive role. The actual data persistence is handled by the api service writing to the volume.
Sources: tools/docker/docker-compose.yml:47-59
Configuration
Environment Variables
The services are configured using environment variables defined in the compose files.
| Variable | Service | Description | Example Value (Prod) |
|---|---|---|---|
NODE_ENV | api, dashboard | Sets the environment mode. | production |
PORT | api | The port the API server listens on inside the container. | 3201 |
CORS_ORIGIN | api | Specifies the allowed origin for CORS requests. | http://localhost:80 |
JWT_ACCESS_SECRET | api | Secret key for signing JWT access tokens. | dev-access-secret (default) |
JWT_REFRESH_SECRET | api | Secret key for signing JWT refresh tokens. | dev-refresh-secret (default) |
DATABASE_URL | api | Path to the database storage directory inside the container. | /app/data |
Sources: tools/docker/docker-compose.yml:12-18, tools/docker/docker-compose.dev.yml:14-20
Volumes
data: A named volume (driver: local) used for persisting the Sled database files from theapiservice. This ensures data is not lost when containers are stopped or removed.- Bind Mounts:
./data:/app/data: Maps the localdatadirectory to the API container for persistence../config.json:/app/config.json: Maps the local configuration file into the API container.- In development, the entire project root (
../..:/app) is mounted to enable hot-reloading.
Sources: tools/docker/docker-compose.yml:19-21, 61-63, tools/docker/docker-compose.dev.yml:21-24, 59-61
Usage and Scripts
The project provides helper scripts to simplify Docker environment management. These are available as both shell scripts in tools/docker/ and as NPM scripts in the root package.json.
Management Scripts
The primary scripts are docker-up.sh for production and docker-dev.sh for development.
Production Startup (docker-up.sh)
This script automates the setup for a production-like environment.
Sources: tools/docker/docker-up.sh
Development Startup (docker-dev.sh)
This script starts the environment in development mode with hot-reloading. It uses docker-compose.dev.yml and runs docker-compose up in the foreground to show logs.
Sources: tools/docker/docker-dev.sh
NPM Scripts
Convenient NPM scripts are defined in package.json to wrap the shell scripts and docker-compose commands.
| Script | Command | Description |
|---|---|---|
npm run docker:up | ./tools/docker/docker-up.sh | Starts all services for production. |
npm run docker:down | ./tools/docker/docker-down.sh | Stops all services. |
npm run docker:dev | ./tools/docker/docker-dev.sh | Starts all services in development mode (with hot-reload). |
npm run docker:build | docker-compose ... build | Builds the production images. |
npm run docker:logs | docker-compose ... logs -f | Tails the logs from all running services. |
npm run docker:status | docker-compose ... ps | Shows the status of the services. |
npm run docker:clean | docker-compose ... down -v ... | Stops containers, removes volumes and orphaned containers. |
Sources: package.json:19-25, README.md:112-124
Production vs. Development Comparison
The two environments are tailored for different needs: stability and performance for production, and rapid feedback for development.
| Aspect | Production (docker-compose.yml) | Development (docker-compose.dev.yml) |
|---|---|---|
| Compose File | tools/docker/docker-compose.yml | tools/docker/docker-compose.dev.yml |
| Dashboard Port | 80:80 (Nginx) | 5173:5173 (Vite Dev Server) |
| API Command | node apps/api/dist/server.js | tsx watch src/index.ts |
| Dashboard Command | (Nginx serves static files) | vite |
| Volumes | Mounts only data and config.json. | Mounts the entire project source code for hot-reloading. |
| CORS Origin | http://localhost:80 | http://localhost:5173 |
Sources: tools/docker/docker-compose.yml, tools/docker/docker-compose.dev.yml
Summary
The Docker deployment for Kodus Runtime provides a robust and portable way to run the application. It clearly separates production and development concerns through distinct docker-compose files. The use of shell scripts and NPM wrappers simplifies common tasks like starting, stopping, and cleaning the environment. Key features include persistent data storage via Docker volumes, service discovery via the default bridge network, and a reverse-proxy setup in production for serving the UI and API from a single domain.