A dedicated Rust/Axum binary (web/frontend-server/) that:
- Serves the built Vite SPA bundle from dist/ via tower-http ServeDir
- Falls back to index.html for SPA routing (deep links work)
- Reverse-proxies /api/* to the backend container (same-origin, no CORS)
- Listens on port 8080 (configurable via FRONTEND_PORT)
Dockerfile (web/normogen-web/Dockerfile): 3-stage build:
1. Node: npm ci + npm run build -> dist/
2. Rust: cargo build --release the frontend-server binary
3. Runtime: debian-slim + binary + dist/
docker-compose.yml: new 'frontend' service on :8080, depends on backend healthy,
proxies to http://backend:6500. Independently scalable (run N replicas behind
a load balancer).
Architecture:
Browser -> :8080 (frontend container)
/api/* -> proxy -> backend:6500
/* -> static dist/ (SPA)
Resolve the operational/config sprawl (#10-#14 from the review): the app read
NORMOGEN_*/MONGODB_* env vars but every env/compose file set SERVER_*/DATABASE_*,
the ports were all over the place (8080/8000/6500/6800), there were 5
inconsistent Dockerfiles (rust:1.82 vs rust:1.93, missing curl), and an 18 MB
binary was committed.
Env-var names — standardize on what the code reads:
* config/mod.rs: NORMOGEN_PORT default 8080 -> 6500 (avoid the over-common
8000/8080).
* db/mod.rs: create_database() now reads MONGODB_DATABASE (was DATABASE_NAME).
* .env.example, defaults.env, docker-compose.yml, docker-compose.dev.yml,
DEPLOYMENT_GUIDE.md, deployment/README.md, deploy-and-test-solaria.sh,
deploy-local-build.sh: use NORMOGEN_HOST/NORMOGEN_PORT/MONGODB_URI/
MONGODB_DATABASE/APP_ENVIRONMENT; drop the dead SERVER_*/DATABASE_URI/
DATABASE_NAME names.
Ports — canonical container port 6500 everywhere:
* Both Dockerfiles EXPOSE 6500; prod compose maps 6500:6500, dev 6501:6500.
* Bulk-replaced the long tail of solaria:8000/localhost:8000/localhost:8080 in
docs and test scripts -> 6500.
Dockerfiles — 2 canonical, rust:latest, curl + healthcheck:
* backend/Dockerfile (prod): rust:latest builder, debian runtime now installs
curl (so the compose HEALTHCHECK actually works), EXPOSE 6500.
* backend/docker/Dockerfile.dev (dev): rust:latest both stages, EXPOSE 6500.
* Deleted 3 redundant Dockerfiles (Dockerfile.improved x2, docker/Dockerfile).
* Deleted the committed 18 MB binary backend/docker/normogen-backend.
* Deleted 2 stray fix-notes in backend/docker/.
Compose:
* docker-compose.yml: correct env names, 6500:6500, APP_ENVIRONMENT=production,
JWT_SECRET/ENCRYPTION_KEY required via compose interpolation, dropped the
obsolete top-level version: key.
* docker-compose.dev.yml: correct env names, 6501:6500, mongo:7 (was 6.0),
added a working backend healthcheck.
* Deleted docker/docker-compose.improved.yml + backend/deploy-to-solaria-improved.sh
(built around the now-deleted 'improved' Docker files).
Verified: cargo fmt --check clean, build + clippy --all-targets clean, 18 unit
tests pass; grep confirms no SERVER_*/DATABASE_* env names and no rust:1.x tags
remain outside docs/archive and docs/adr (historical).
- Fix DNS resolution: Removed invalid dns_search configuration
- Add graceful MongoDB connection error handling
- Set restart policy to 'unless-stopped' for both services
- Add development helper scripts (start-dev.sh, stop-dev.sh)
- Update Docker Compose configurations for development
- Restore main.rs from git history
- Backend now logs MongoDB errors without crashing
All containers now start successfully with proper DNS resolution
on the dedicated normogen-network.
Changes:
- Changed server port from 8000 to 6800 (in range 6500-6999 as requested)
- Updated all Docker Compose files (dev and prod)
- Updated all Dockerfiles (removed Cargo.lock dependency)
- Created backend/.dockerignore with Cargo.lock
- Added Cargo.lock to .gitignore (generated by cargo)
- Removed obsolete 'version' attribute from docker-compose files
- Updated all documentation to reflect new port:
* README.md
* thoughts/CONFIG.md
* thoughts/QUICKSTART.md
* thoughts/verification-report-phase-2.3.md
This fixes Docker build errors where Cargo.lock was not found during COPY operations.
Docker will now generate Cargo.lock during the build process as expected.
- Created Cargo.toml with all required dependencies
- Implemented health/ready endpoints
- Added Docker configuration (production + development)
- Configured docker-compose with resource limits
- Set up MongoDB service with persistence
- Verified build (cargo check passed)
- Prepared monorepo structure for mobile/web/shared
Next: Phase 2.2 (MongoDB connection and models)