Environments¶
Four environments exist in practice.
1. Local development¶
Infrastructure in Docker, applications on the host.
| Piece | How it runs |
|---|---|
| PostgreSQL | backend/docker-compose-dev.yml, published on 5433 |
| RabbitMQ | same file, 5672 and 15672 |
| Django | python manage.py runserver on 8000 |
| Console | pnpm dev on 5001 |
| Landing | pnpm dev |
The repository-root .env holds only MANAGE_PY_PATH, a developer-specific absolute path
used by the VS Code launch configuration. It is not application configuration.
2. Developer / staging¶
One host serving staging.towitlinks.com, fronted by the host-level nginx configuration in
staging.nginx.
| Route | Upstream |
|---|---|
/ |
127.0.0.1:3001 — the console container |
/api/, /admin/, /twilio/, /google/ |
127.0.0.1:8123 — the staging Django container |
/rabbitmq/ |
127.0.0.1:15672 |
/static/ |
/home/vladimir/VoIP/backend/staticfiles/ on the host |
/android/ |
/home/vladimir/build_apk/VoIP/frontend/android/app/build/outputs/ — the APKs |
/api/ carries the WebSocket upgrade headers and a proxy_read_timeout of 86400
(staging.nginx:18-26), a leftover from the abandoned Channels work.
The backend runs from backend/docker-compose-staging.yml: postgres:16, the web container
on 8123:8000, and Redis as the Channels backend. The console runs from
frontend/docker-compose-staging.yml on 3001:80, from Dockerfile.staging, which bakes
nginx and frontend_staging.conf into the image.
Staging is refreshed either by rebuild_and_run_staging.sh over SSH, or automatically for
the backend when something lands on develop — see Deployment.
3. Production¶
| Host | Serves |
|---|---|
towitlinks.com, www.towitlinks.com |
The landing container on port 3000 (landing.nginx:3) |
app.towitlinks.com |
The console SPA and the Django API (frontend/frontend.conf:3) |
The production backend compose file (backend/docker-compose.yml) runs web on
8000:8000, celery_worker, celery_beat and rabbitmq. There is no database service
— PostgreSQL is external. Container logs ship to a Graylog instance at 154.53.40.104:1514
through the syslog driver, tagged links-backend (:15-18).
Configuration comes from Docker Swarm secrets named TWTLNKPROD_*, loaded by
backend/entrypoint.sh:30-98, not from an .env file.
The production console image is unusual: frontend/Dockerfile serves nothing. It copies the
built bundle into /built-files, and entrypoint.sh rsyncs it into a /voip-frontend
volume and then sleeps. A separate nginx service in the Swarm serves that volume. This means
a deployment is a volume refresh, not a container swap, and nginx keeps serving the old
files until the rsync finishes.
The control plane is a Docker Swarm stack defined in infrastructure/docker-compose.yml:
portainer/agent:2.21.5 as a global service, portainer/portainer-ce:2.21.5 on the
manager, and a custom portainer_nginx image built from infrastructure/nginx/Dockerfile,
publishing port 80. Portainer itself is reachable at portainer.towithouston.com
(infrastructure/nginx/my_custom_conf/portainer.conf:3).
TLS is not in this repository
Every nginx server block in the repository listens on port 80 only. Certificates are
handled outside version control — most likely certbot rewriting the live host copies,
or an upstream proxy. Confirm with the team before changing any nginx file.
4. Android build host¶
A dedicated machine at 154.53.40.104, with the repository checked out at
~/build_apk/VoIP. .github/workflows/android.yml SSHes in and runs rebuild_android.sh.
Artifacts are served from the staging host under /android/. See
Mobile builds.
Other hostnames in the codebase¶
| Host | Used for |
|---|---|
chat.towitlinks.com |
Linked from the landing layout (landing/src/routes/+layout.svelte:8) |
links.towithouston.com |
Twilio webhook / WSS domain (backend/.env.example:99-100) |
minios3.towithouston.com |
MinIO / S3 object storage |
whisper.towithouston.com |
Audio transcription service |
portainer.towithouston.com |
Portainer UI |
Branching and promotion¶
main is the default branch and develop is the integration branch. Feature branches use
feat/, fix/, ref/, test/ and similar prefixes. Work merges into develop by pull
request, and develop into main by pull request.
Promotion to production is manual: the production workflows only push images, and a human triggers the deployment in Portainer. See Deployment.