Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
0a15c99
sfs: initial config
lucaspar Mar 19, 2026
15ca126
sfs: more config
lucaspar Mar 19, 2026
4aa8dfb
solved filer persistence issue; sfs docs
lucaspar Apr 7, 2026
8d18bf4
docs to interact with sfs using the minio cli
lucaspar Apr 7, 2026
70881ae
integrating seaweed and gateway compose stacks
lucaspar Apr 7, 2026
a5bb7e8
increased automation for sfs migration
lucaspar Apr 7, 2026
ff0e78c
wip
lucaspar Apr 9, 2026
e3b698c
additional env variables for sfs integration
lucaspar Apr 14, 2026
df01722
created dual storage backend + tests
lucaspar Apr 14, 2026
4ae3bc8
sfs env things
lucaspar Apr 14, 2026
7d10407
ignoring hostnames file
lucaspar Apr 14, 2026
0eca216
additional healthchecks for services
lucaspar Apr 16, 2026
c787e52
hardening nginx config
lucaspar Apr 16, 2026
3ab6ad1
adjustments to automated secret generation
lucaspar Apr 16, 2026
e4144b5
trying to get sfs loading on ci
lucaspar Apr 16, 2026
77b5c7f
object store integrity checker script
lucaspar Apr 20, 2026
03d13bf
explicitly controlling celery concurrency
lucaspar Apr 28, 2026
614bc38
seaweedfs: align prod deployment with sfs checklist
lucaspar May 5, 2026
a01655a
refactor: rename SFS/MINIO settings to PRIMARY/SECONDARY
lucaspar May 5, 2026
14e88b3
infra: replace MinIO with RustFS in compose files
lucaspar May 5, 2026
bff2100
infra: consolidate storage env files and update scripts
lucaspar May 5, 2026
991bb2c
docs: update minio/sfs references to primary/secondary
lucaspar May 5, 2026
7110269
docs: add deployment documentation and update gateway deploy script
lucaspar May 7, 2026
ca5ed5b
infra: unify seaweedfs compose files across all environments
lucaspar May 7, 2026
33f0e8a
fix: enable external network for CI compose
lucaspar May 7, 2026
046580f
feat: add seaweedfs health check script and just recipes
lucaspar May 7, 2026
3bf359a
feat: add SDS_ENV inline override to env-selection scripts
lucaspar May 7, 2026
d0c8d8f
addressing ci issues
lucaspar May 8, 2026
459ca75
infra: wire storage env into gateway compose and justfile
lucaspar May 9, 2026
a41ede7
fix: improve deploy scripts with debug logs and uid-based ownership
lucaspar May 9, 2026
8f88568
gwy: django management cmd to create buckets
lucaspar May 9, 2026
2f628bf
feat: add seaweedfs as secondary object store for local/dev environments
lucaspar May 9, 2026
b3bec15
fix: resolve ruff linting errors in object store tests and minio client
lucaspar May 9, 2026
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.DS_Store
.agents/
.config/agents/
agents.md
13 changes: 0 additions & 13 deletions gateway/.envs/example/minio.env

This file was deleted.

24 changes: 24 additions & 0 deletions gateway/.envs/example/storage.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# ====================== STORAGE ENV ======================
# PRIMARY (RustFS) — S3-compatible storage, default for local/CI
# SECONDARY (SeaweedFS) — S3-compatible object store for local/dev

# PRIMARY (RustFS) credentials
PRIMARY_ACCESS_KEY_ID=admin
PRIMARY_ENDPOINT_URL=sds-gateway-local-rustfs:9000
PRIMARY_S3_ENDPOINT_URL=http://sds-gateway-local-rustfs:9000
PRIMARY_SECRET_ACCESS_KEY=admin
PRIMARY_STORAGE_BUCKET_NAME=spectrumx
PRIMARY_STORAGE_USE_HTTPS=false

# SECONDARY (SeaweedFS) credentials
SECONDARY_ACCESS_KEY_ID=admin
SECONDARY_SECRET_ACCESS_KEY=admin
SECONDARY_ENDPOINT_URL=sds-gateway-local-sfs-s3:8333
SECONDARY_S3_ENDPOINT_URL=http://sds-gateway-local-sfs-s3:8333
SECONDARY_STORAGE_BUCKET_NAME=spectrumx
SECONDARY_STORAGE_USE_HTTPS=false

# Transition controls
OBJECT_STORE_DUAL_WRITE_STRICT=false
OBJECT_STORE_READ_FALLBACK_TO_SECONDARY_ENABLED=false
OBJECT_STORE_WRITE_BOTH_ENABLED=false
26 changes: 26 additions & 0 deletions gateway/.envs/example/storage.prod.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# ====================== STORAGE ENV (PRODUCTION) ======================
# SeaweedFS config — see seaweedfs/compose.production.yaml
# RustFS config — see gateway/compose.<env>.yaml

# PRIMARY credentials (RustFS in local and ci, SeaweedFS in prod)
PRIMARY_ACCESS_KEY_ID=admin
PRIMARY_ENDPOINT_URL=sds-gateway-prod-sfs-s3:8333
PRIMARY_S3_ENDPOINT_URL=http://sds-gateway-prod-sfs-s3:8333
PRIMARY_SECRET_ACCESS_KEY=admin
PRIMARY_STORAGE_BUCKET_NAME=spectrumx
PRIMARY_STORAGE_USE_HTTPS=false

# SECONDARY credentials (usually RustFS in prod; absent in local and ci)
SECONDARY_ACCESS_KEY_ID=minioadmin
SECONDARY_ENDPOINT_URL=prod-secondary-rustfs:9000
SECONDARY_ROOT_PASSWORD=<GENERATED SECONDARY ROOT PASSWORD>
SECONDARY_ROOT_USER=minioadmin
SECONDARY_S3_ENDPOINT_URL=http://prod-secondary-rustfs:9000
SECONDARY_SECRET_ACCESS_KEY=<SAME AS SECONDARY_ROOT_PASSWORD>
SECONDARY_STORAGE_BUCKET_NAME=spectrumx
SECONDARY_STORAGE_USE_HTTPS=false

# Transition controls
OBJECT_STORE_DUAL_WRITE_STRICT=false
OBJECT_STORE_READ_FALLBACK_TO_SECONDARY_ENABLED=false
OBJECT_STORE_WRITE_BOTH_ENABLED=false
62 changes: 0 additions & 62 deletions gateway/.github/workflows/ci.yml

This file was deleted.

129 changes: 98 additions & 31 deletions gateway/compose.ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ volumes:
sds-gateway-ci-uv-venv-worker: {}
sds-gateway-ci-uv-venv-beat: {}
sds-gateway-ci-uv-venv-flower: {}
sds-gateway-ci-minio-files: {}
sds-gateway-ci-rustfs-files: {}
sds-gateway-ci-opensearch-data: {}
sds-gateway-ci-postgres-data-backups: {}
sds-gateway-ci-postgres-data: {}
sds-gateway-ci-redis-data: {}

networks:
# for safety, all gateway CI networks start with "sds-gateway-ci-"
sds-gateway-ci-minio-net:
sds-gateway-ci-rustfs-net:
driver: bridge
sds-gateway-ci-opensearch-net:
driver: bridge
sds-gateway-ci-postgres-net:
driver: bridge
sds-network-ci:
# external: true # make it external if running with traefik on this machine
# should match traefik's network name
external: true
name: sds-network-ci
driver: bridge
services:
sds-gateway-ci-app:
build:
Expand All @@ -45,8 +45,6 @@ services:
condition: service_healthy
redis:
condition: service_healthy
minio:
condition: service_healthy
volumes:
- sds-gateway-ci-uv-cache:/opt/uv-cache/
- sds-gateway-ci-uv-venv-app:/opt/uv-venv/
Expand Down Expand Up @@ -74,16 +72,17 @@ services:
# - ./staticfiles/:/app/staticfiles/:z # used in prod only
env_file:
- ./.envs/ci/django.env
- ./.envs/ci/minio.env
- ./.envs/ci/storage.env # PRIMARY (RustFS) — local/CI: primary only, no secondary
- ./.envs/ci/postgres.env
- ./.envs/ci/opensearch.env
# remember /entrypoint runs first
command: "/start"
ports:
- "8000:8000" # make sure this port matches traefik's config, if used
networks:
- sds-gateway-ci-minio-net
- sds-gateway-ci-rustfs-net
- sds-gateway-ci-opensearch-net
- sds-gateway-ci-postgres-net
- sds-network-ci
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8000/ || exit 1"]
Expand Down Expand Up @@ -124,34 +123,49 @@ services:
selinux: z
networks:
- sds-network-ci
healthcheck:
test:
[
"CMD-SHELL",
"wget -q -O /dev/null http://localhost/ || exit 1",
]
interval: 30s
timeout: 5s
retries: 5
start_period: 10s

minio:
# main file storage for sds
# minio uses rolling upgrades that are non-disruptive, so we can target latest
# For more information on how to upgrade MinIO deployment, refer to the MinIO documentation:
# https://min.io/docs/minio/container/operations/install-deploy-manage/upgrade-minio-deployment.html
image: minio/minio:latest
container_name: sds-gateway-ci-minio
# Primary storage (RustFS) — S3-compatible, default for local/CI
rustfs:
image: rustfs/rustfs:latest
container_name: sds-gateway-ci-rustfs
volumes:
- sds-gateway-ci-minio-files:/files
- sds-gateway-ci-rustfs-files:/data
ports:
- "9000:9000"
- "19000:9000"
- "9001:9001"
env_file:
- ./.envs/ci/minio.env
- ./.envs/ci/storage.env
environment:
- RUSTFS_VOLUMES=/data
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_CORS_ALLOWED_ORIGINS=*
- RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS=*
- RUSTFS_ACCESS_KEY=${PRIMARY_ACCESS_KEY_ID}
- RUSTFS_SECRET_KEY=${PRIMARY_SECRET_ACCESS_KEY}
networks:
- sds-gateway-ci-rustfs-net
healthcheck:
test:
[
"CMD-SHELL",
"curl -f http://localhost:9000/minio/health/live || exit 1",
"curl -f http://localhost:9000/rustfs/console/health || exit 1",
]
interval: 30s
timeout: 5s
retries: 5
start_period: 10s
command: 'server /files --console-address ":9001"'
networks:
- sds-gateway-ci-minio-net

opensearch:
# used for indexing and searching documents
Expand Down Expand Up @@ -191,7 +205,7 @@ services:
build:
context: .
dockerfile: ./compose/production/postgres/Dockerfile
# this dockerfile is used for both local/CI and prod
# this dockerfile is used for both local and prod
image: sds-gateway-ci-postgres
container_name: sds-gateway-ci-postgres
volumes:
Expand All @@ -200,7 +214,7 @@ services:
env_file:
- ./.envs/ci/postgres.env
networks:
- sds-gateway-ci-minio-net
- sds-gateway-ci-postgres-net
healthcheck:
test:
[
Expand Down Expand Up @@ -264,14 +278,25 @@ services:
selinux: z
env_file:
- ./.envs/ci/django.env
- ./.envs/ci/minio.env
- ./.envs/ci/storage.env # PRIMARY (RustFS) — local/CI: primary only, no secondary
- ./.envs/ci/postgres.env
- ./.envs/ci/opensearch.env
command: "/worker-start"
networks:
- sds-gateway-ci-minio-net
- sds-gateway-ci-rustfs-net
- sds-gateway-ci-opensearch-net
- sds-gateway-ci-postgres-net
- sds-network-ci
healthcheck:
test:
[
"CMD-SHELL",
'uv run celery -A config.celery_app inspect ping -d "celery@$$HOSTNAME" | grep -q "OK"',
]
interval: 30s
timeout: 30s
retries: 5
start_period: 30s

celery-beat:
# Celery Beat scheduler for periodic tasks
Expand Down Expand Up @@ -309,14 +334,25 @@ services:
selinux: z
env_file:
- ./.envs/ci/django.env
- ./.envs/ci/minio.env
- ./.envs/ci/storage.env # PRIMARY (RustFS) — local/CI: primary only, no secondary
- ./.envs/ci/postgres.env
- ./.envs/ci/opensearch.env
command: "/beat-start"
networks:
- sds-gateway-ci-minio-net
- sds-gateway-ci-rustfs-net
- sds-gateway-ci-opensearch-net
- sds-gateway-ci-postgres-net
- sds-network-ci
healthcheck:
test:
[
"CMD-SHELL",
'uv run python -c "import pathlib,sys; ok=any((b\"beat\" in data) and ((b\"celery\" in data) or (b\"watchfiles\" in data)) for data in (path.read_bytes() for path in pathlib.Path(\"/proc\").glob(\"[0-9]*/cmdline\"))); sys.exit(0 if ok else 1)"',
]
interval: 30s
timeout: 30s
retries: 5
start_period: 30s

celery-flower:
# Celery monitoring and administration tool
Expand Down Expand Up @@ -354,16 +390,27 @@ services:
selinux: z
env_file:
- ./.envs/ci/django.env
- ./.envs/ci/minio.env
- ./.envs/ci/storage.env # PRIMARY (RustFS) — local/CI: primary only, no secondary
- ./.envs/ci/postgres.env
- ./.envs/ci/opensearch.env
command: "/flower-start"
ports:
- "5555:5555" # Flower web interface
networks:
- sds-gateway-ci-minio-net
- sds-gateway-ci-rustfs-net
- sds-gateway-ci-opensearch-net
- sds-gateway-ci-postgres-net
- sds-network-ci
healthcheck:
test:
[
"CMD-SHELL",
'curl -f --header "Authorization: Basic $(echo -n "$$CELERY_FLOWER_USER:$$CELERY_FLOWER_PASSWORD" | base64)" http://localhost:5555/api/workers || exit 1',
]
interval: 30s
timeout: 30s
retries: 5
start_period: 30s

# ==========================
# local development services
Expand Down Expand Up @@ -395,6 +442,16 @@ services:
- action: sync
path: ./
target: /app/
healthcheck:
test:
[
"CMD-SHELL",
'node -e "const http=require(\"http\"); const req=http.get(\"http://127.0.0.1:3000\", res => process.exit(res.statusCode < 500 ? 0 : 1)); req.on(\"error\", () => process.exit(1)); req.setTimeout(5000, () => { req.destroy(); process.exit(1); });"',
]
interval: 30s
timeout: 10s
retries: 5
start_period: 45s

mailhog:
# email testing service for local development
Expand All @@ -405,3 +462,13 @@ services:
- "8025:8025" # Web UI
networks:
- sds-network-ci
healthcheck:
test:
[
"CMD-SHELL",
"wget -q -O /dev/null http://localhost:8025/api/v2/messages || exit 1",
]
interval: 30s
timeout: 5s
retries: 5
start_period: 10s
Loading
Loading