From 9ba6571fa6fbaa13a34d056edf6da5fc005f013e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Gruszczy=C5=84ski?= Date: Sat, 31 Oct 2026 15:33:58 +0100 Subject: [PATCH] v0.2.0_docker --- docker/.env.example | 42 ++++++++ docker/README.md | 126 ++++++++++++++++++++-- docker/compose-mysql-nfs-opensearch.yml | 14 ++- docker/compose-postgres-s3-opensearch.yml | 14 ++- docker/compose-single-sqlite.yml | 10 +- 5 files changed, 190 insertions(+), 16 deletions(-) create mode 100644 docker/.env.example diff --git a/docker/.env.example b/docker/.env.example new file mode 100644 index 0000000..a02297f --- /dev/null +++ b/docker/.env.example @@ -0,0 +1,42 @@ +# RustBox Docker Compose defaults. +# Copy to docker/.env if you want persistent local values: +# cp .env.example .env +# Secrets below are development examples only. Change them outside local testing. + +# Application HTTP listener and published host port. +HOST=0.0.0.0 +PORT=3001 + +# Mail servers used by RustBox. +IMAP_HOST=mail.example.com +IMAP_PORT=993 +SMTP_HOST=mail.example.com +SMTP_PORT=587 +TLS_ENABLED=true + +# Application logging. +RUST_LOG=info + +# Shared session encryption key. Required to be identical on all RustBox nodes. +# Replace for any non-local deployment. +SESSION_ENCRYPTION_KEY=MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY= + +# PostgreSQL variant. +POSTGRES_PASSWORD=rustbox-dev-password + +# S3/SILO variant. +S3_ACCESS_KEY=rustbox +S3_SECRET_KEY=rustbox-s3-dev-password + +# MySQL variant. +MYSQL_PASSWORD=rustbox-dev-password +MYSQL_ROOT_PASSWORD=rustbox-root-password + +# NFS variant. NFS_SERVER is required by compose-mysql-nfs-opensearch.yml. +NFS_SERVER=10.0.0.10 +NFS_EXPORT=/exports/rustbox + +# Optional Compose project name. The compose files also declare `name: rustbox`. +# A shell-exported COMPOSE_PROJECT_NAME overrides the top-level `name:` field. +# Recommended launch commands therefore use `docker compose -p rustbox ...`. +COMPOSE_PROJECT_NAME=rustbox diff --git a/docker/README.md b/docker/README.md index 200eb87..50f126f 100644 --- a/docker/README.md +++ b/docker/README.md @@ -1,15 +1,123 @@ -# RustBox 0.2.0 Docker variants +# RustBox Docker -The example images are version-pinned where practical so a release does not silently change its integration stack. The bundled SILO topology is for local/integration validation of the S3 API; production deployments should use a security-reviewed S3-compatible service and their own lifecycle/HA policy. +Run all commands from the `docker/` directory. -Run commands from `docker/`. +The Compose files use the project name `rustbox` and the examples below additionally pass `-p rustbox`. Using `-p` is intentional: a globally exported `COMPOSE_PROJECT_NAME` has higher priority than the `name: rustbox` field in a Compose file and could otherwise attach RustBox to an unrelated Compose project/network. -- `docker compose -f compose-single-sqlite.yml up --build` — single node, SQLite, local filesystem blobs, local Tantivy. -- `docker compose -f compose-postgres-s3-opensearch.yml up --build` — cluster-ready application shape with PostgreSQL, SILO (S3-compatible blobs) and OpenSearch. The RustBox container has no persistent `data_dir` volume. -- `NFS_SERVER=10.0.0.10 NFS_EXPORT=/exports/rustbox docker compose -f compose-mysql-nfs-opensearch.yml up --build` — MySQL, real shared POSIX/NFS blob storage and OpenSearch. +## Quick start -Set `IMAP_HOST` and `SMTP_HOST` for the mail system. Replace all example passwords and `SESSION_ENCRYPTION_KEY` before production use. The OpenSearch examples disable its security plugin only to keep the local Compose topology self-contained; production should use TLS/authentication and `search.urls` with HTTPS. +PostgreSQL + S3/SILO + OpenSearch: -The NFS variant deliberately uses an NFS volume driver instead of a local Docker named volume: a local named volume is not shared across Docker hosts and therefore is not a valid multi-node RustBox blob backend. +```bash +PORT=3009 \ +IMAP_HOST=mail.linuxiarz.pl \ +SMTP_HOST=mail.linuxiarz.pl \ +docker compose -p rustbox -f compose-postgres-s3-opensearch.yml up --build +``` -The two cluster-ready Compose examples intentionally run one RustBox application container so they remain directly runnable on a single Docker host. To run multiple RustBox application nodes, place them behind an external load balancer (or adapt the Compose networking) and do not publish the same host port from every node; the shared SQL/blob/OpenSearch services are the cluster-safe backing topology. +SQLite, local blobs and local Tantivy: + +```bash +IMAP_HOST=mail.linuxiarz.pl \ +SMTP_HOST=mail.linuxiarz.pl \ +docker compose -p rustbox -f compose-single-sqlite.yml up --build +``` + +MySQL + NFS + OpenSearch: + +```bash +NFS_SERVER=10.0.0.10 \ +NFS_EXPORT=/exports/rustbox \ +IMAP_HOST=mail.linuxiarz.pl \ +SMTP_HOST=mail.linuxiarz.pl \ +docker compose -p rustbox -f compose-mysql-nfs-opensearch.yml up --build +``` + +Check only the RustBox project: + +```bash +docker compose -p rustbox -f compose-postgres-s3-opensearch.yml ps +``` + +Stop it without deleting persistent volumes: + +```bash +docker compose -p rustbox -f compose-postgres-s3-opensearch.yml down +``` + +To also delete the Compose volumes, use `down -v` only when you really want to remove local database, S3 and OpenSearch data. + +## Environment variables + +Copy the supplied template if you prefer a persistent local configuration: + +```bash +cp .env.example .env +``` + +| Variable | Default | Used by | Description | +|---|---|---|---| +| `HOST` | `0.0.0.0` | all | Address RustBox listens on inside the container. | +| `PORT` | `3001` | all | RustBox HTTP port. The same value is used for the container listener and host port mapping. Example: `PORT=3009` publishes `3009:3009`. | +| `IMAP_HOST` | `mail.example.com` | all | IMAP server hostname used for mailbox access/authentication. Set this for a real mail system. | +| `IMAP_PORT` | `993` | all | IMAP server port. | +| `SMTP_HOST` | `mail.example.com` | all | SMTP server hostname used for sending mail. | +| `SMTP_PORT` | `587` | all | SMTP submission port. | +| `TLS_ENABLED` | `true` | all | Enables TLS for mail connections according to RustBox configuration. | +| `RUST_LOG` | `info` | all | Rust logging filter/level. | +| `SESSION_ENCRYPTION_KEY` | development key | PostgreSQL, MySQL | Shared key used to encrypt session data. All application nodes must use the same value. Replace it outside local testing. | +| `POSTGRES_PASSWORD` | `rustbox-dev-password` | PostgreSQL | Password for PostgreSQL user `rustbox`; also used in `DATABASE_URL`. | +| `S3_ACCESS_KEY` | `rustbox` | PostgreSQL/S3 | Access key for the bundled S3-compatible SILO service and RustBox S3 client. | +| `S3_SECRET_KEY` | `rustbox-s3-dev-password` | PostgreSQL/S3 | Secret key for SILO and RustBox S3 client. Replace it outside local testing. | +| `MYSQL_PASSWORD` | `rustbox-dev-password` | MySQL/NFS | Password for MySQL user `rustbox`; also used in `DATABASE_URL`. | +| `MYSQL_ROOT_PASSWORD` | `rustbox-root-password` | MySQL/NFS | MySQL root password used by the container and health check. | +| `NFS_SERVER` | none | MySQL/NFS | NFS server address. Required for `compose-mysql-nfs-opensearch.yml`. | +| `NFS_EXPORT` | `/rustbox` | MySQL/NFS | Export path on the NFS server. | +| `COMPOSE_PROJECT_NAME` | `rustbox` in `.env.example` | Compose | Compose project name. A value exported in the shell overrides the file's `name:`. The documented commands use `-p rustbox`, which has the highest priority. | + +`RUSTBOX_CONFIG` and `DATABASE_URL` are set by the Compose files themselves and normally should not be supplied from the shell for these bundled topologies. + +## Avoiding another Compose project + +If `docker compose ... ps` shows containers from another application, inspect the effective project-name override: + +```bash +printf 'COMPOSE_PROJECT_NAME=%s\n' "${COMPOSE_PROJECT_NAME:-}" +docker compose -p rustbox -f compose-postgres-s3-opensearch.yml ps +``` + +For RustBox use `-p rustbox` in operational commands. This isolates service discovery too: the RustBox container resolves PostgreSQL as `postgres` only on the RustBox Compose network. + +Useful DNS/database checks: + +```bash +docker compose -p rustbox -f compose-postgres-s3-opensearch.yml \ + run --rm --no-deps --entrypoint getent rustbox hosts postgres + +docker compose -p rustbox -f compose-postgres-s3-opensearch.yml \ + exec postgres pg_isready -U rustbox -d rustbox +``` + +## Topologies + +### `compose-single-sqlite.yml` + +Single RustBox node with SQLite, filesystem blob storage and local Tantivy search. Persistent application data is stored in the `rustbox-data` Docker volume. + +### `compose-postgres-s3-opensearch.yml` + +Cluster-ready backing topology with PostgreSQL, SILO providing an S3-compatible API, and OpenSearch. The RustBox application container itself has no persistent `data_dir` volume. + +The bundled SILO topology is intended for local/integration validation of the S3 API. Production deployments should use a security-reviewed S3-compatible service with an appropriate lifecycle and HA policy. + +### `compose-mysql-nfs-opensearch.yml` + +MySQL, shared POSIX/NFS blob storage and OpenSearch. The NFS volume driver is deliberate: a normal local Docker named volume is not shared between Docker hosts and therefore is not a valid blob backend for a multi-host RustBox deployment. + +## Production notes + +Replace all example passwords, S3 credentials and `SESSION_ENCRYPTION_KEY` before production use. + +The OpenSearch examples disable its security plugin to keep the local Compose topology self-contained. Production should use TLS/authentication and HTTPS URLs in `search.urls`. + +The two cluster-ready examples intentionally start one RustBox application container so they can run directly on a single Docker host. For multiple RustBox application nodes, put them behind an external load balancer and do not publish the same host port from every node; SQL, blob storage and OpenSearch must remain shared between the nodes. diff --git a/docker/compose-mysql-nfs-opensearch.yml b/docker/compose-mysql-nfs-opensearch.yml index e741518..9f1366e 100644 --- a/docker/compose-mysql-nfs-opensearch.yml +++ b/docker/compose-mysql-nfs-opensearch.yml @@ -1,3 +1,5 @@ +name: rustbox + services: mysql: image: mysql:8.4 @@ -39,13 +41,19 @@ services: opensearch: condition: service_healthy ports: - - "3001:3001" + - "${PORT:-3001}:${PORT:-3001}" environment: RUSTBOX_CONFIG: /etc/rustbox/rustbox.toml + HOST: ${HOST:-0.0.0.0} + PORT: ${PORT:-3001} + IMAP_HOST: ${IMAP_HOST:-mail.example.com} + IMAP_PORT: ${IMAP_PORT:-993} + SMTP_HOST: ${SMTP_HOST:-mail.example.com} + SMTP_PORT: ${SMTP_PORT:-587} + TLS_ENABLED: ${TLS_ENABLED:-true} + RUST_LOG: ${RUST_LOG:-info} DATABASE_URL: mysql://rustbox:${MYSQL_PASSWORD:-rustbox-dev-password}@mysql:3306/rustbox SESSION_ENCRYPTION_KEY: ${SESSION_ENCRYPTION_KEY:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=} - IMAP_HOST: ${IMAP_HOST:-mail.example.com} - SMTP_HOST: ${SMTP_HOST:-mail.example.com} volumes: - ./configs/mysql-nfs-opensearch.toml:/etc/rustbox/rustbox.toml:ro - rustbox-nfs:/mnt/rustbox-shared diff --git a/docker/compose-postgres-s3-opensearch.yml b/docker/compose-postgres-s3-opensearch.yml index 4bfab40..874d2b6 100644 --- a/docker/compose-postgres-s3-opensearch.yml +++ b/docker/compose-postgres-s3-opensearch.yml @@ -1,3 +1,5 @@ +name: rustbox + services: postgres: image: postgres:17-bookworm @@ -63,15 +65,21 @@ services: opensearch: condition: service_healthy ports: - - "3001:3001" + - "${PORT:-3001}:${PORT:-3001}" environment: RUSTBOX_CONFIG: /etc/rustbox/rustbox.toml + HOST: ${HOST:-0.0.0.0} + PORT: ${PORT:-3001} + IMAP_HOST: ${IMAP_HOST:-mail.example.com} + IMAP_PORT: ${IMAP_PORT:-993} + SMTP_HOST: ${SMTP_HOST:-mail.example.com} + SMTP_PORT: ${SMTP_PORT:-587} + TLS_ENABLED: ${TLS_ENABLED:-true} + RUST_LOG: ${RUST_LOG:-info} DATABASE_URL: postgres://rustbox:${POSTGRES_PASSWORD:-rustbox-dev-password}@postgres:5432/rustbox SESSION_ENCRYPTION_KEY: ${SESSION_ENCRYPTION_KEY:-MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=} AWS_ACCESS_KEY_ID: ${S3_ACCESS_KEY:-rustbox} AWS_SECRET_ACCESS_KEY: ${S3_SECRET_KEY:-rustbox-s3-dev-password} - IMAP_HOST: ${IMAP_HOST:-mail.example.com} - SMTP_HOST: ${SMTP_HOST:-mail.example.com} volumes: - ./configs/postgres-s3-opensearch.toml:/etc/rustbox/rustbox.toml:ro restart: unless-stopped diff --git a/docker/compose-single-sqlite.yml b/docker/compose-single-sqlite.yml index 67f790b..c227786 100644 --- a/docker/compose-single-sqlite.yml +++ b/docker/compose-single-sqlite.yml @@ -1,14 +1,22 @@ +name: rustbox + services: rustbox: build: context: .. dockerfile: docker/Dockerfile ports: - - "3001:3001" + - "${PORT:-3001}:${PORT:-3001}" environment: RUSTBOX_CONFIG: /etc/rustbox/rustbox.toml + HOST: ${HOST:-0.0.0.0} + PORT: ${PORT:-3001} IMAP_HOST: ${IMAP_HOST:-mail.example.com} + IMAP_PORT: ${IMAP_PORT:-993} SMTP_HOST: ${SMTP_HOST:-mail.example.com} + SMTP_PORT: ${SMTP_PORT:-587} + TLS_ENABLED: ${TLS_ENABLED:-true} + RUST_LOG: ${RUST_LOG:-info} volumes: - ./configs/single-sqlite.toml:/etc/rustbox/rustbox.toml:ro - rustbox-data:/var/lib/rustbox