Skip to main content
This guide is for teams deploying Ringlyra onto a Google Cloud Compute Engine (GCE) VM that already has nginx and other applications running. Instead of using Ringlyra’s built-in nginx container, you will add a virtual-host block to your existing nginx and point your domain www.ringlyra.com at it.

Architecture overview

Ringlyra runs via Docker Compose without its own nginx container β€” the remote profile is intentionally skipped.

Step 1 β€” GCP firewall rules

Open the required ports in your GCP project firewall. Run these from Cloud Shell or your local gcloud CLI:
Then add the ringlyra-server network tag to your VM:

Reserve a static external IP

A static IP prevents the VM’s address from changing on restart, which would break DNS.
Note the IP β€” you need it for DNS in the next step.

Step 2 β€” DNS

Log in to your domain registrar and add two A records pointing to your GCE VM’s static IP: Verify propagation before continuing:

Step 3 β€” Deploy Ringlyra containers

SSH into your GCE VM.

3a β€” Clone the repo and create the environment file

Copy the example env file and fill in your values:
Minimum required values for a production deployment:

3b β€” Start the stack (without the built-in nginx)

The remote Docker Compose profile starts Ringlyra’s own nginx container, which conflicts with your existing nginx on ports 80/443. Use the deploy script instead; it starts the app services and starts coturn automatically when TURN_HOST and TURN_SECRET are present:
This starts the API on localhost:8000, the UI on localhost:3010, MinIO on localhost:9000, and coturn on the TURN ports from Step 1. Verify all containers are healthy:

3c β€” Database migrations

infra/deploy.sh runs Alembic migrations automatically after the containers are healthy. If you start the services manually instead of using the deploy script, run:

Step 4 β€” SSL certificate with Let’s Encrypt

Install Certbot on the VM (if not already installed):
Stop your existing nginx temporarily so Certbot can bind to port 80 for the ACME challenge:
Obtain the certificate:
Certificates are stored in /etc/letsencrypt/live/ringlyra.com/. Restart nginx:

Step 5 β€” nginx virtual host

Create a new site config for Ringlyra. This sits alongside your existing sites and does not touch them.
Paste the following (replace www.ringlyra.com / ringlyra.com if your domain differs):
Enable the site and reload nginx:

Step 6 β€” Verify the deployment

Open https://www.ringlyra.com in your browser β€” you should see the Ringlyra dashboard with a valid SSL certificate.

Step 7 β€” Automatic certificate renewal

Certbot installs a renewal timer automatically, but it needs to reload nginx after renewing. Create a deploy hook:

Step 8 β€” GitHub Actions auto-deploy

If you set up the GitHub Actions deploy workflow, add these secrets in your repo settings so the workflow can SSH into this VM and restart the containers: On every push to main, the workflow will build fresh Docker images, push them to Artifact Registry, SSH in via IAP, pull the images, and restart only the api and ui containers β€” leaving your existing nginx and other applications untouched.

Troubleshooting

502 Bad Gateway from nginx

The API or UI container is not running. Check:

Voice calls connect but no audio

WebRTC relay ports may be blocked. Confirm the ringlyra-webrtc firewall rule is applied to your instance tag and that coturn is running:
If coturn is not running, make sure .env includes TURN_HOST, TURN_INTERNAL_HOST, TURN_SECRET, and SERVER_IP, then re-run:
If calls connect but audio still fails, temporarily keep FORCE_TURN_RELAY=true so browser media uses relay candidates only while you verify the firewall and coturn logs.

Certificate renewal fails

Ensure port 80 is reachable from the internet (required for HTTP-01 ACME challenge) and that the ringlyra firewall rule is active: