Mindloom’s production stack runs entirely on a single OCI Ampere A1 virtual machine (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/No-Country-simulation/G9-LATAM-Team-58/llms.txt
Use this file to discover all available pages before exploring further.
linux/arm64) orchestrated by Docker Compose. Three services — inference, api, and web — form a dependency chain: the Python inference service must reach a healthy state before the Spring Boot API starts, and the React frontend served by nginx depends on the API. Because OCI Object Storage cannot host a single-page application (a browser refresh on any deep route returns a 404 with no index.html fallback), the nginx container serves the built React bundle directly from the VM rather than from a bucket.
Services and Ports
The compose file defines three services on a shared bridge network namedtechmind. The table below shows how each service is exposed:
| Service | Port mapping | Notes |
|---|---|---|
inference | expose: 8000 | Internal network only — port 8000 is not published to the host |
api | 8080:8080 | Published to the host for direct API access |
web | 80:80 | Published to the host; requires --profile web |
inference service uses expose rather than ports, meaning port 8000 is reachable only by other containers on the techmind network. Port 8000 remains closed in the OCI Security List. Port 8080 is published while the frontend is being built so teammates can call the API directly; once all traffic routes through nginx’s /api proxy, it can be changed to expose and closed.
Startup Order and Healthcheck
Theapi service declares a hard dependency on inference reaching a healthy state:
Dockerfile:
start-period of 60 seconds gives the load() function time to authenticate with OCI Object Storage via Instance Principal, fetch models/latest.txt, download the joblib artifact it points to, and deserialize the model into memory. The API container will not start until that window completes successfully.
The inference healthcheck uses Python’s built-in
urllib rather than curl because the python:3.12-slim base image does not include curl. This keeps the image layer small.Model Loading at Startup
When the inference container starts, itsload() function executes two sequential reads from OCI Object Storage:
GET models/latest.txt— a small pointer file that contains the path prefix of the current model version (e.g.models/v1/).GET models/v1/model.joblib— the ~0.24 MB serialized scikit-learn pipeline downloaded into memory viajoblib.load().
~/.oci/config.
The SentenceTransformer weights (~470 MB for intfloat/multilingual-e5-small) are baked into the image at build time and loaded from the local HF_HOME=/app/.cache/huggingface cache at startup — no network call to Hugging Face occurs at runtime.
The web Profile
The web service is declared behind profiles: [web] in docker-compose.yml. A plain docker compose build or docker compose up does not include it. The deploy workflow always passes --profile web explicitly:
docker compose up locally for API and inference development is unaffected by any frontend changes.
Oracle Wallet Mount
The API container requires the Oracle Autonomous Database wallet to be available at runtime. The wallet is never stored in the repository — it must be unzipped into./wallet/ on the VM (relative to docker-compose.yml) before the first deploy. Docker Compose mounts it read-only:
TNS_ADMIN environment variable in the container is set to /app/wallet, matching the mount point. The SPRING_DATASOURCE_URL uses the TNS alias techmind_tp from the wallet’s tnsnames.ora:
The db Spring Profile
The api service sets SPRING_PROFILES_ACTIVE=db in docker-compose.yml. This activates application-db.properties, which sets app.database.enabled=true and removes the scaffold-mode spring.autoconfigure.exclude entries that disable the DataSource and JPA autoconfiguration. Without the db profile, the API starts in scaffold mode and every DB-backed endpoint returns 503 Service Unavailable.
First-Time VM Setup
Create and fill the environment file
Copy
.env.example to .env and fill in the credentials. The .env file lives at ~/techmind/.env and is never committed to the repository:Install the Oracle wallet
Download the Oracle Autonomous Database Instance Wallet from the OCI Console and unzip it into The wallet directory must exist at
~/techmind/wallet/:./wallet/ relative to docker-compose.yml before the API container starts.Build the Docker images
Build all images natively on the ARM64 VM. Pass This step downloads the
--profile web to include the nginx frontend:intfloat/multilingual-e5-small transformer weights (~470 MB) into the inference image layer on first build.Start the stack
Bring up all three containers in detached mode:The inference container starts first. After
load() succeeds and the healthcheck passes (up to 60 seconds), Docker Compose automatically starts the API. The web container starts once the API is up.The deploy workflow runs
git reset --hard origin/main on the VM during every deployment. Any files you modify manually inside the ~/techmind git tree will be overwritten and lost on the next deploy. Files that live outside the git tree — .env, wallet/ — survive because git reset does not touch untracked files.