Unitru Academic deploys to Railway as two independent services —Documentation Index
Fetch the complete documentation index at: https://mintlify.com/Andr21Da16/UNITRU-ACADEMIC/llms.txt
Use this file to discover all available pages before exploring further.
backend and frontend — from the same GitHub monorepo. Each service has its own Dockerfile and railway.json at the root of its subdirectory, so Railway knows exactly how to build and health-check each one. The backend runs FastAPI with Uvicorn behind Railway’s TLS proxy; the frontend serves the Next.js standalone bundle with Node. The two services communicate exclusively over a secure WebSocket connection (wss://).
${{service.RAILWAY_PUBLIC_DOMAIN}} is a Railway cross-service reference. Railway resolves it automatically at deploy time — you never need to copy and paste the actual domain string between services.Deployment Steps
Create two Railway services from the same repo
In your Railway project, click New → GitHub Repo and select this repository twice — once for the backend and once for the frontend.After adding each service, open its Settings and set the Root Directory:
Railway detects the
| Service | Root Directory | Dockerfile | Health check |
|---|---|---|---|
backend | backend | backend/Dockerfile | GET /health |
frontend | frontend | frontend/Dockerfile | (none) |
railway.json in each root directory and uses it to configure the build and restart policy automatically.Generate public domains for each service
In each service, go to Settings → Networking → Generate Domain. Railway assigns a public
*.up.railway.app subdomain.For example:- Backend →
unitru-backend.up.railway.app - Frontend →
unitru-academic.up.railway.app
Set environment variables
Open the Variables tab in each service and add the following:This tells FastAPI’s CORS middleware to allow requests from the deployed frontend domain.This variable is passed as a Docker build argument (
backend service:frontend service:ARG) and baked into the Next.js bundle at build time. Note the wss:// scheme (TLS) and the /ws path suffix — both are required.Push to main — Railway builds and deploys both services
Railway automatically builds and deploys both services on every push to the configured branch (default:
main). Monitor build logs in the Railway dashboard.Once both deployments are green, open the frontend public domain in your browser to access the dashboard.Important Notes
PORT is injected by Railway automatically
The backend’s CMD uses ${PORT:-8000} — Railway injects the PORT environment variable at runtime and the server binds to it. Do not set PORT manually in the backend service variables; doing so will conflict with Railway’s internal port assignment.
Backend image size and RAM requirements
The backend Docker image bundles Chromium (viaplaywright install --with-deps chromium) and Tesseract OCR. This makes it significantly larger than a typical Python API image. The first build on Railway will take several minutes.
At runtime, a headless Chromium session requires meaningful memory. Recommend allocating at least 1 GB of RAM to the backend service in Railway’s resource settings to avoid OOM kills during active scraping sessions.
WebSocket behind Railway’s TLS proxy
Railway terminates TLS at its edge proxy and forwards traffic to the container over plain HTTP/WS. The backend starts Uvicorn with--proxy-headers --forwarded-allow-ips=* so that FastAPI correctly sees the original client IP and protocol — this is required for WebSocket upgrades to work through the proxy.
Schedule catalog is baked into the image
The schedule optimizer reads fromdata/horarios_catalogo.json, which is copied into the backend image at build time. To update the catalog with new semester data:
- Run
python3 scripts/download_horarios.py <google_sheets_url>to fetch the latest spreadsheet. - Run
python3 scripts/parse_horarios.pyto convert it tohorarios_catalogo.json. - Commit the updated JSON file and push — Railway will rebuild and redeploy the backend automatically.
Credentials are never persisted
Even in production, SUV credentials are transmitted only over the encrypted WebSocket connection (wss://), held in memory during the active session, and discarded when the connection closes. Nothing is written to disk, a database, or logs.
Reference: railway.json Files
Both services ship with a railway.json that instructs Railway to use the Dockerfile builder. The backend additionally configures a health check endpoint:
backend/railway.json:
frontend/railway.json: