Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
target/
.direnv/
.git/
.github/
.vscode/
.idea/
docker-data/
node_modules/
dist/
result
smithy/build/
crates/dashboard/
*.md
*.pdf
*.svg
.env*
.DS_Store
60 changes: 60 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Docker Publish

on:
workflow_dispatch:
branches: [main]

env:
REGISTRY: ghcr.io
IMAGE_PREFIX: ghcr.io/${{ github.repository_owner }}/kronos

permissions:
contents: read
packages: write

jobs:
build-and-push:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- binary: kronos-api
features: ""
- binary: kronos-worker
features: ""
steps:
- uses: actions/checkout@v4

- uses: docker/setup-buildx-action@v3

- name: Generate calendar version tag
id: version
run: echo "tag=$(date -u +'%Y%m%d%H%M')" >> "$GITHUB_OUTPUT"

- uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_PREFIX }}/${{ matrix.binary }}
tags: |
type=raw,value=${{ steps.version.outputs.tag }}
type=raw,value=latest

- name: Build and push
uses: docker/build-push-action@v6
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BINARY=${{ matrix.binary }}
FEATURES=${{ matrix.features }}
cache-from: type=gha
cache-to: type=gha,mode=max
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
.env.local
.env.*.local
.env.kms
.env.prod.kms
.kms-key-id

# Nix / direnv
Expand Down
55 changes: 55 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
FROM lukemathwalker/cargo-chef:latest-rust-bookworm AS chef
WORKDIR /app

# --- Plan dependencies ---
FROM chef AS planner
COPY . .
RUN cargo chef prepare --recipe-path recipe.json

# --- Build ---
FROM chef AS builder

RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
cmake \
&& rm -rf /var/lib/apt/lists/*

COPY --from=planner /app/recipe.json recipe.json

ARG FEATURES=""

# Cache dependency build (rebuilds only when Cargo.toml/lock change)
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/app/target \
if [ -n "$FEATURES" ]; then \
cargo chef cook --release --recipe-path recipe.json --features "$FEATURES"; \
else \
cargo chef cook --release --recipe-path recipe.json; \
fi

COPY . .

ARG BINARY

RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/app/target \
if [ -n "$FEATURES" ]; then \
cargo build --release --bin "$BINARY" --features "$FEATURES"; \
else \
cargo build --release --bin "$BINARY"; \
fi \
&& cp /app/target/release/"$BINARY" /usr/local/bin/app

# --- Runtime ---
FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y \
ca-certificates \
curl \
libssl3 \
&& rm -rf /var/lib/apt/lists/*

COPY --from=builder /usr/local/bin/app /usr/local/bin/app

ENTRYPOINT ["/usr/local/bin/app"]
2 changes: 1 addition & 1 deletion crates/common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ aes-gcm.workspace = true
rand.workspace = true
base64.workspace = true
jsonschema.workspace = true
cron.workspace = true
chrono-tz.workspace = true
cron.workspace = true
dotenvy.workspace = true
metrics.workspace = true
metrics-exporter-prometheus.workspace = true
119 changes: 119 additions & 0 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# Prod-like Docker Compose: all services on a shared network with KMS.
# Use via: ./scripts/docker-prod.sh (handles migrations + KMS init)

services:
postgres:
build: docker/postgres
ports:
- "5432:5432"
environment:
POSTGRES_USER: kronos
POSTGRES_PASSWORD: kronos
POSTGRES_DB: taskexecutor
command:
- "postgres"
- "-c"
- "shared_preload_libraries=pg_cron"
- "-c"
- "cron.database_name=taskexecutor"
volumes:
- postgres-prod-data:/var/lib/postgresql/data
- ./migrations:/migrations:ro
networks:
- kronos-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U kronos -d taskexecutor"]
interval: 5s
timeout: 3s
retries: 10

localstack:
image: localstack/localstack:3
ports:
- "4566:4566"
environment:
SERVICES: kms
AWS_DEFAULT_REGION: us-east-1
networks:
- kronos-net
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:4566/_localstack/health"]
interval: 5s
timeout: 3s
retries: 10

kronos-mock-server:
build:
context: .
dockerfile: Dockerfile
args:
BINARY: kronos-mock-server
ports:
- "9999:9999"
environment:
MOCK_PORT: "9999"
networks:
- kronos-net
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:9999/health"]
interval: 5s
timeout: 3s
retries: 10

kronos-api:
build:
context: .
dockerfile: Dockerfile
args:
BINARY: kronos-api
FEATURES: kms
ports:
- "8080:8080"
env_file:
- path: .env.prod.kms
required: false
environment:
TE_LISTEN_ADDR: "0.0.0.0:8080"
networks:
- kronos-net
depends_on:
postgres:
condition: service_healthy
localstack:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "curl -sf http://localhost:8080/health"]
interval: 5s
timeout: 3s
retries: 15

kronos-worker:
build:
context: .
dockerfile: Dockerfile
args:
BINARY: kronos-worker
FEATURES: kms
ports:
- "9090:9090"
env_file:
- path: .env.prod.kms
required: false
environment:
TE_METRICS_PORT: "9090"
networks:
- kronos-net
depends_on:
postgres:
condition: service_healthy
localstack:
condition: service_healthy
kronos-mock-server:
condition: service_healthy

networks:
kronos-net:
driver: bridge

volumes:
postgres-prod-data:
10 changes: 10 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,16 @@ kms-dev:
echo "All services starting with KMS. Press Ctrl+C to stop."
wait

# ─── Docker Prod ─────────────────────────────────────────────

# Start full prod-like Docker environment (postgres + KMS + all services)
docker-prod-up:
./scripts/docker-prod.sh

# Stop and clean up prod-like Docker environment
docker-prod-down:
./scripts/docker-prod-down.sh

# ─── Cargo utilities ─────────────────────────────────────────

# Run clippy lints
Expand Down
10 changes: 10 additions & 0 deletions scripts/docker-prod-down.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env bash
# Tears down the prod-like Docker environment and cleans up generated files.

set -euo pipefail

echo "==> Stopping all services and removing volumes..."
docker compose -f docker-compose.prod.yml down -v

rm -f .env.prod.kms
echo "==> Cleanup complete."
Loading