Before directing real traffic to your NISIRA Assistant deployment, work through every section below. Each accordion covers one configuration category. A missed item in Security or Database is the most common cause of production incidents, so start there and work your way down. Items are phrased as actionable checkboxes — mark them off as you confirm each one.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/HugoX2003/nisira-assistant/llms.txt
Use this file to discover all available pages before exploring further.
1 · Security
1 · Security
Hardening Django’s security settings is the first step before exposing the application to the internet.
-
SECRET_KEYis set to a unique, cryptographically random value (minimum 50 characters). Generate one with: -
DEBUG=False— this must beFalsein production. Leaving itTrueexposes stack traces and internal configuration to any visitor. -
ALLOWED_HOSTSlists only your actual domain(s) and/or Droplet IP, e.g.your-domain.com,www.your-domain.com. Wildcard (*) is not acceptable in production. -
SECURE_SSL_REDIRECT=True— Django redirects all HTTP requests to HTTPS. Enable only after the SSL certificate is installed. -
SESSION_COOKIE_SECURE=True— the session cookie is sent only over HTTPS. -
CSRF_COOKIE_SECURE=True— the CSRF cookie is sent only over HTTPS. -
DJANGO_SETTINGS_MODULE=core.production_settings— the production settings module is active. -
.env.productionandcredentials.jsonare listed in.gitignoreand are not present in any Git commit.
2 · Database
2 · Database
NISIRA Assistant requires PostgreSQL with the
pgvector extension for storing vector embeddings. The default MySQL development database is not supported in production.-
DATABASE_URLis set and points to a PostgreSQL 16 instance (e.g.postgresql://user:pass@host:5432/rag_asistente). On DigitalOcean App Platform, use the${db.DATABASE_URL}binding. -
DB_PASSWORDis a strong, unique password — not the defaultsistemasfrom the development config. - The
pgvectorextension is available. Thepgvector/pgvector:pg16image used indocker-compose.production.ymlincludes it automatically. For managed databases, verify with: - All Django migrations have been applied:
- There are no unapplied migrations (
--checkexits0). - A database backup strategy is in place (cron job, DigitalOcean managed backup, or equivalent).
3 · LLM & API Keys
3 · LLM & API Keys
The backend requires at least one LLM provider key to answer chat queries. Without a valid key the chat endpoint will return errors for every message.
- At least one of the following LLM provider keys is set and valid:
OPENROUTER_API_KEY— used whenLLM_PROVIDER=openrouterGOOGLE_API_KEY— used whenLLM_PROVIDER=geminiGROQ_API_KEY— used whenLLM_PROVIDER=groq
-
LLM_PROVIDERis set to the provider whose key you have configured (openrouter,gemini, orgroq). -
GOOGLE_API_KEYis set if you want to use Google’s embedding model. The default embedding model (sentence-transformers/all-mpnet-base-v2) does not require a key, but Google embeddings may offer better quality for Spanish-language documents. - API keys have been tested independently before deployment (e.g. with a
curlcall to the provider’s API) to confirm they are active and have sufficient quota.
4 · RAG Initialization
4 · RAG Initialization
The retrieval-augmented generation (RAG) system must be initialized after the first deployment so that document embeddings are generated and stored in ChromaDB.
-
INIT_RAGis set to"false"indocker-compose.production.yml(this is the default). The RAG system is initialized on-demand via the API, not automatically at startup, to avoid long container start times. - After the backend is healthy, initialize the RAG system:
- The RAG status endpoint confirms the system is ready:
- Documents in
./backend/data/documents(or therag_datavolume) have been synced and processed. - The
chroma_datavolume is persistent (defined as a named volume indocker-compose.production.yml) so embeddings survive container restarts.
5 · Google Drive (Optional)
5 · Google Drive (Optional)
Google Drive integration allows the backend to automatically sync documents from a shared Drive folder. This section only applies if you are enabling Drive sync.
-
ENABLE_GOOGLE_DRIVE=trueis set. -
GOOGLE_DRIVE_FOLDER_IDis set to the ID of your shared Google Drive folder. -
credentials.jsonis present in the backend container (mounted via thecredentialsvolume) orGOOGLE_CREDENTIALS_JSONis set as an environment variable containing the full JSON content of the service account credentials. - The
credentials.jsonfile has restrictive permissions (chmod 600) on the host. - The Google Drive API is enabled in the Google Cloud project associated with the service account.
- The service account has Viewer access to the target Drive folder.
If Google Drive is not needed, leave
ENABLE_GOOGLE_DRIVE unset or set to false. The backend will skip Drive-related startup checks and avoid noisy authentication logs.6 · Frontend
6 · Frontend
The React frontend must be built against the correct backend URL. A mismatch here results in CORS errors and a non-functional chat interface.
-
REACT_APP_API_URLis set to the production backend’s base URL (e.g.https://your-domain.comorhttps://<your-app>.ondigitalocean.app). No trailing slash. - The frontend Docker build completes without errors (
npm run buildexits0). - The compiled frontend serves the correct API URL — verify in the browser’s Network tab that XHR requests go to the expected backend host.
-
GENERATE_SOURCEMAP=falseis set to prevent exposing source maps in production builds. - The login, registration, and chat flows work end-to-end after deployment.
7 · Health Checks
7 · Health Checks
Container orchestration and load balancers rely on health checks to determine whether a service is ready to receive traffic.
- The backend
/api/health/endpoint returnsHTTP 200. This is the health check path configured in bothdocker-compose.production.ymland DigitalOcean App Platform. - All Docker Compose services report
healthyindocker compose ps. - The frontend responds at the root path (
/) withHTTP 200. - Health check intervals are appropriate: the
backend/Dockerfileuses--interval=30s --timeout=10s --start-period=40s --retries=3.
8 · Gunicorn
8 · Gunicorn
Gunicorn is the production WSGI server. Under-sizing workers leads to request queuing; over-sizing wastes memory on small Droplets.
-
GUNICORN_WORKERSis set. The general formula is(2 × CPU cores) + 1. On the DigitalOcean 5/month, shared CPU), use2. -
GUNICORN_TIMEOUTis set to300. RAG queries and document embedding can be long-running; a 30-second default timeout will cause silent failures. - Gunicorn is binding on
0.0.0.0:${PORT}(not127.0.0.1) so the container’s port is reachable from Nginx or the App Platform router. - Worker recycling (
--max-requests/--max-requests-jitter) is considered for long-running deployments to prevent gradual memory growth.
9 · CORS
9 · CORS
Cross-Origin Resource Sharing must be locked down so that only the trusted frontend domain can make authenticated API requests from a browser.
-
CORS_ALLOWED_ORIGINSlists only the production frontend domain(s), e.g.: -
CORS_ALLOWED_ORIGINSdoes not contain*(wildcard) in production. - The frontend URL in
CORS_ALLOWED_ORIGINSexactly matches theOriginheader sent by the browser (scheme + hostname + port, no trailing slash). - After deployment, confirm CORS is working by checking that a login request from the frontend does not produce a
CORS policybrowser error.
10 · Monitoring
10 · Monitoring
Basic observability allows you to detect and diagnose issues before users report them.
- Container logs are accessible and being reviewed. On Docker Compose:
On DigitalOcean App Platform: Runtime Logs tab in the dashboard.
-
/api/admin/metrics/is responding correctly for admin users and returns expected system metrics. -
docker stats(or equivalent) shows reasonable CPU and memory usage — no containers pinned at 100% CPU. - A database backup cron job is scheduled and has been tested with a manual run:
- Log rotation or an external log aggregator is configured to prevent disk exhaustion on long-running Droplets.
- An uptime monitor (e.g. DigitalOcean Uptime, Better Uptime) is pointed at
/api/health/with an alert sent to your email or Slack on failure.