diff --git a/README.md b/README.md index c4a255c..438ccff 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,30 @@ This repository contains detailed developer and architecture documentation in th Key architecture documents: see [architecture](docs/architecture/README.md) for the arc42-based architecture documentation. For contributors: the `routes/`, `models/` and `services/` folders contain the primary application code. Tests and E2E specs are in `tests/`. + +## Run with Docker + +The repository ships with a multi-stage `Dockerfile` that produces a slim runtime image. + +```powershell +# Build the image locally +docker build -t calminer:latest . + +# Run the container (exposes FastAPI on http://localhost:8000) +docker run --rm -p 8000:8000 calminer:latest + +# Provide environment variables (e.g., database URL) +docker run --rm -p 8000:8000 -e DATABASE_URL="postgresql://user:pass@host/db" calminer:latest +``` + +Use `docker compose` or an orchestrator of your choice to co-locate PostgreSQL/Redis alongside the app when needed. The image expects migrations to be applied before startup. + +## CI/CD expectations + +CalMiner uses Gitea Actions workflows stored in `.gitea/workflows/`: + +- `test.yml` runs style/unit/e2e suites on every push with cached Python dependencies. +- `build-and-push.yml` builds the Docker image, reuses cached layers, and pushes to the configured registry. +- `deploy.yml` pulls the pushed image on the target host and restarts the container. + +Pipelines assume the following secrets are provisioned in the Gitea instance: `GITEA_USERNAME`, `GITEA_PASSWORD`, `GITEA_REGISTRY`, `SSH_HOST`, `SSH_USERNAME`, and `SSH_PRIVATE_KEY`. diff --git a/docs/architecture/07_deployment_view.md b/docs/architecture/07_deployment_view.md index 9302edc..c0749ec 100644 --- a/docs/architecture/07_deployment_view.md +++ b/docs/architecture/07_deployment_view.md @@ -4,6 +4,8 @@ description: "Describe deployment topology, infrastructure components, and envir status: draft --- + + # 07 — Deployment View ## Deployment Topology @@ -23,8 +25,8 @@ The infrastructure components for the application include: - **Database Server**: PostgreSQL database for persisting application data. - **Static File Server**: Serves static assets such as CSS, JavaScript, and image files. - **Reverse Proxy (optional)**: An Nginx or Apache server can be used as a reverse proxy. -- **CI/CD Pipeline (optional)**: Automated deployment pipelines can be set up using tools like GitHub Actions. -- **Containerization (optional)**: Docker can be used to containerize the application. +- **Containerization**: Docker images are generated via the repository `Dockerfile`, using a multi-stage build to keep the final runtime minimal. +- **CI/CD Pipeline**: Automated pipelines (Gitea Actions) run tests, build/push Docker images, and trigger deployments. - **Cloud Infrastructure (optional)**: The application can be deployed on cloud platforms. ## Environments @@ -55,7 +57,32 @@ The production environment is set up for serving live traffic and includes: - Load balancer (e.g., Nginx) for distributing incoming requests - Monitoring and logging tools for tracking application performance +## Containerized Deployment Flow + +The Docker-based deployment path aligns with the solution strategy documented in [04 — Solution Strategy](04_solution_strategy.md) and the CI practices captured in [14 — Testing & CI](14_testing_ci.md). + +### Image Build + +- The multi-stage `Dockerfile` installs dependencies in a builder layer (including system compilers and Python packages) and copies only the required runtime artifacts to the final image. +- Build arguments are minimal; environment configuration (e.g., `DATABASE_URL`) is supplied at runtime. Secrets and configuration should be passed via environment variables or an orchestrator. +- The resulting image exposes port `8000` and starts `uvicorn main:app` (s. [README.md](../README.md)). + +### Runtime Environment + +- For single-node deployments, run the container alongside PostgreSQL/Redis using Docker Compose or an equivalent orchestrator. +- A reverse proxy (e.g., Nginx) terminates TLS and forwards traffic to the container on port `8000`. +- Migrations must be applied prior to rolling out a new image; automation can hook into the deploy step to run `scripts/run_migrations.py`. + +### CI/CD Integration + +- Gitea Actions workflows reside under `.gitea/workflows/`. +- `test.yml` executes the pytest suite using cached pip dependencies. +- `build-and-push.yml` logs into the container registry, rebuilds the Docker image using GitHub Actions cache-backed layers, and pushes `latest` (and additional tags as required). +- `deploy.yml` connects to the target host via SSH, pulls the pushed tag, stops any existing container, and launches the new version. +- Required secrets: `GITEA_REGISTRY`, `GITEA_USERNAME`, `GITEA_PASSWORD`, `SSH_HOST`, `SSH_USERNAME`, `SSH_PRIVATE_KEY`. +- Extend these workflows when introducing staging/blue-green deployments; keep cross-links with [14 — Testing & CI](14_testing_ci.md) up to date. + ## Integrations and Future Work (deployment-related) - **Persistence of results**: `/api/simulations/run` currently returns in-memory results; next iteration should persist to `simulation_result` and reference scenarios. -- **Deployment**: documentation focuses on local development; containerization and CI/CD pipelines remain to be defined. Consider Docker + GitHub Actions or a simple Docker Compose for local stacks. +- **Deployment**: implement infrastructure-as-code (e.g., Terraform/Ansible) to provision the hosting environment and maintain parity across dev/stage/prod. diff --git a/docs/architecture/14_testing_ci.md b/docs/architecture/14_testing_ci.md index 6c1e805..af1fa7c 100644 --- a/docs/architecture/14_testing_ci.md +++ b/docs/architecture/14_testing_ci.md @@ -20,9 +20,12 @@ CalMiner uses a combination of unit, integration, and end-to-end tests to ensure ### CI/CD -- Use GitHub Actions for CI. -- Run tests on pull requests. -- Code coverage target: 80% (using pytest-cov). +- Use Gitea Actions for CI/CD; workflows live under `.gitea/workflows/`. +- `test.yml` runs on every push with cached Python dependencies via `actions/cache@v3`. +- `build-and-push.yml` builds the Docker image with `docker/build-push-action@v2`, reusing GitHub Actions cache-backed layers, and pushes to the Gitea registry. +- `deploy.yml` connects to the target host (via `appleboy/ssh-action`) to pull the freshly pushed image and restart the container. +- Mandatory secrets: `GITEA_USERNAME`, `GITEA_PASSWORD`, `GITEA_REGISTRY`, `SSH_HOST`, `SSH_USERNAME`, `SSH_PRIVATE_KEY`. +- Run tests on pull requests to shared branches; enforce coverage target ≥80% (pytest-cov). ### Running Tests @@ -34,7 +37,7 @@ CalMiner uses a combination of unit, integration, and end-to-end tests to ensure Organize tests under the `tests/` directory mirroring the application structure: -```text +````text tests/ unit/ test_.py @@ -71,7 +74,7 @@ To run the Playwright tests: ```bash pytest tests/e2e/ -``` +```` To run headed mode: @@ -93,9 +96,22 @@ pytest tests/e2e/ --headed ### CI Integration -- Configure GitHub Actions workflow in `.github/workflows/ci.yml` to: - - Install dependencies, including Playwright browsers (`playwright install`). - - Run `pytest` with coverage for unit tests. - - Run `pytest tests/e2e/` for E2E tests. - - Fail on coverage <80%. - - Upload coverage artifacts under `reports/coverage/`. +`test.yml` encapsulates the steps below: + +- Check out the repository and set up Python 3.10. +- Restore the pip cache (keyed by `requirements.txt`). +- Install project dependencies and Playwright browsers (if needed for E2E). +- Run `pytest` (extend with `--cov` flags when enforcing coverage). + +`build-and-push.yml` adds: + +- Registry login using repository secrets. +- Docker image build/push with GHA cache storage (`cache-from/cache-to` set to `type=gha`). + +`deploy.yml` handles: + +- SSH into the deployment host. +- Pull the tagged image from the registry. +- Stop, remove, and relaunch the `calminer` container exposing port 8000. + +When adding new workflows, mirror this structure to ensure secrets, caching, and deployment steps remain aligned with the production environment. diff --git a/docs/quickstart.md b/docs/quickstart.md index 5cc6215..4b67bc2 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -22,6 +22,23 @@ pip install -r requirements.txt uvicorn main:app --reload ``` +## Docker-based setup + +To build and run the application using Docker instead of a local Python environment: + +```powershell +# Build the application image (multi-stage build keeps runtime small) +docker build -t calminer:latest . + +# Start the container on port 8000 +docker run --rm -p 8000:8000 calminer:latest + +# Supply environment variables (e.g., Postgres connection) +docker run --rm -p 8000:8000 -e DATABASE_URL="postgresql://user:pass@host/db" calminer:latest +``` + +If you maintain a Postgres or Redis dependency locally, consider authoring a `docker compose` stack that pairs them with the app container. The Docker image expects the database to be reachable and migrations executed before serving traffic. + ## Usage Overview - **API base URL**: `http://localhost:8000/api`