Skip to content

Deploy an edge reverse proxy with the edge-reverse-proxy template

Deployment

Coming from another cloud?

▸AWS·ALB

This Quake AI feature maps to AWS’s ALB.

Deploy an edge reverse proxy with the edge-reverse-proxy template

Stand up a Caddy reverse proxy with automatic TLS on one Quake AI instance using the validated OpenTofu template edge-reverse-proxy. You apply the template, launch a private backend on the same subnet, verify traffic flows through the proxy, lock the backend security group to the proxy, point a domain at the floating IP, and confirm HTTPS end to end.

The proxy holds the only public floating IP. The backend stays on the private subnet with no address on the internet. You operate both instances yourself; this is a regional reverse proxy you run, not a managed global edge network.

BrowserFloating IP80 / 443Proxy VMCaddyBackend VMno floating IPCaddyApp :8080 HTTPSprivate subnet only
Click to zoom
What you'll build: Caddy on a proxy instance with a floating IP terminates TLS and forwards to a private backend on the same subnet

Monthly cost estimate

Pricing calculator ↗

Sized as a custom package on shared vCPU.

Starting template$30.40/mo

Partial estimate: Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.

What each resource is for

Proxy

s1a.small · 2 shared vCPU, 2 GiB RAM, 0.5 Gbps

$16.50/mo

s1a.small

s1a.small · 2 shared vCPU, 2 GiB RAM, 0.5 Gbps

$16.50/mo

Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.

Included in baseline

s1a.small

2 shared vCPU, 2 GiB RAM, 0.5 Gbps

$16.50

s1a.small

2 shared vCPU, 2 GiB RAM, 0.5 Gbps

$16.50

Compute + RAM rate basis

4 vCPU + 4 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.

—

Block storage (30 GiB)

30 GiB at $0.08/GiB/mo

$2.40

Public IP (included)

1 included with the custom package

$0.00

Package promotional discount

Flat −$5.00/mo on the custom package (same promotion as named plans).

$-5.00

Included at no charge

These line items are zero on Quake AI. Many other providers meter them separately.

Data transfer (inbound and outbound)

Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.

AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.

Learn more
$0.00

Private networking

Private networks, subnets, Neutron routers, and security groups are included with the plan.

VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.

$0.00

Control-plane API requests

OpenStack API calls for provisioning and management are included.

Some managed services on other clouds meter API calls or charge for premium control-plane features.

$0.00

Pricing data last validated: . For current rates, check quake.ai/pricing.

Prerequisites#

You need:

  • OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
  • Your OpenStack credentials sourced into the shell (source openrc.sh). See the OpenStack CLI guide.
  • An SSH keypair that already exists in your project. Record its name for the key_name variable.
  • A copy of the edge-reverse-proxy template directory from the template reference page.
  • A domain you can point at the proxy floating IP when you reach the HTTPS step.

Step 1: Apply the proxy template#

Copy the template's example variables file and set key_name. Leave domain empty for now so Caddy serves plain HTTP on port 80 while you stand up the backend. Keep the default upstream_host and upstream_port unless you plan a different private address:

bash
cp terraform.tfvars.example terraform.tfvars
HCL
key_name       = "YOUR_KEY_NAME"
upstream_host  = "10.42.0.10"
upstream_port  = 8080

Initialize, preview, and apply:

bash
tofu init
tofu plan
tofu apply

OpenTofu provisions a private network, router, security group, data volume, proxy instance, and floating IP. cloud-init installs Docker, mounts the data volume at /data, writes a Caddyfile that reverse-proxies to upstream_host:upstream_port, and starts Caddy.

Record the outputs:

bash
tofu output floating_ip
tofu output private_ip
tofu output proxy_url

Wait two to three minutes for cloud-init to finish before you test the proxy.

Step 2: Launch a private backend on the proxy network#

The template creates network edge-reverse-proxy-net and subnet edge-reverse-proxy-subnet (names follow the default app_name). Launch a small backend instance on that subnet at the fixed address 10.42.0.10 with no floating IP.

  1. Create a security group for the backend:
bash
openstack security group create app-backend-sg \
  --description "Private app backend; ingress from proxy only after step 4"

Allow SSH from your workstation while you configure the backend (tighten or remove this rule after setup):

bash
openstack security group rule create \
  --protocol tcp --dst-port 22 --remote-ip YOUR_IP/32 app-backend-sg
  1. Create a port with the fixed private IP:
bash
SUBNET_ID=$(openstack subnet list -f value -c ID -c Name | awk '/edge-reverse-proxy-subnet/ {print $1}')

openstack port create \
  --network edge-reverse-proxy-net \
  --fixed-ip subnet=$SUBNET_ID,ip-address=10.42.0.10 \
  --security-group app-backend-sg \
  app-backend-port
  1. Write a short cloud-init file that serves a test page on port 8080:
bash
cat > backend-cloud-init.yaml <<'EOF'
#cloud-config
package_update: true
packages:
  - nginx
runcmd:
  - |
    echo 'backend ok' > /var/www/html/index.html
    printf '%s\n' 'server {' '  listen 8080;' '  root /var/www/html;' '}' > /etc/nginx/sites-available/default
    systemctl restart nginx
EOF
  1. Launch the backend instance on the port:
bash
openstack server create \
  --flavor s1a.small \
  --image Ubuntu-24.04 \
  --key-name YOUR_KEY_NAME \
  --port app-backend-port \
  --user-data backend-cloud-init.yaml \
  app-backend

Wait until the instance reports ACTIVE, then confirm the backend answers on the private subnet from the proxy host:

bash
ssh ubuntu@YOUR_FLOATING_IP 'curl -s http://10.42.0.10:8080/'

The response body should include backend ok.

Step 3: Verify traffic through the proxy#

From your workstation, request the proxy floating IP over HTTP:

bash
curl -s http://YOUR_FLOATING_IP/

The response should show backend ok. The request path is client to proxy floating IP to Caddy to private backend.

If Caddy returns 502, cloud-init may still be running on the proxy or backend. Wait and retry. If the error persists, SSH to the proxy and run docker compose -f /opt/edge-proxy/docker-compose.yml ps to confirm Caddy is up.

Step 4: Lock the backend security group to the proxy#

Restrict the backend so it accepts application traffic only from the proxy security group edge-reverse-proxy-sg. Remove any rule that opens the application port to 0.0.0.0/0 if you added one during testing.

bash
openstack security group rule create \
  --protocol tcp \
  --dst-port 8080 \
  --remote-group edge-reverse-proxy-sg \
  app-backend-sg

List the backend rules and confirm port 8080 allows only the proxy group:

bash
openstack security group rule list app-backend-sg -f table

The backend still has no floating IP, so it is not reachable directly from the internet. Only the proxy can forward traffic to it on the private subnet.

Step 5: Point a domain and enable HTTPS#

  1. Create a DNS A record for your domain (for example app.example.com) pointing at YOUR_FLOATING_IP. Follow How to point a domain at a Quake AI resource. Wait until it resolves:
bash
dig +short app.example.com
  1. Set domain in terraform.tfvars:
HCL
domain = "app.example.com"
  1. Apply again. OpenTofu updates cloud-init so Caddy serves the domain with automatic Let's Encrypt HTTPS:
bash
tofu apply

OpenTofu may replace the proxy instance when domain changes because cloud-init content changed. Wait for cloud-init to finish on the new instance.

For background on certificates, see How to issue and auto-renew a TLS certificate with Let's Encrypt.

Step 6: Verify HTTPS end to end#

Request the site over HTTPS:

bash
curl -s https://app.example.com/

The response should still show backend ok. Inspect the certificate:

bash
curl -vI https://app.example.com/ 2>&1 | grep -E 'subject:|issuer:'

Traffic now flows client to HTTPS on the domain to Caddy on the proxy to the private backend.

What you built#

  • Applied the edge-reverse-proxy template to provision a private network, proxy security group, data volume, Caddy host, and floating IP
  • Launched a private backend on the same subnet at 10.42.0.10 with no public address
  • Verified HTTP and HTTPS through the proxy floating IP and your domain
  • Locked the backend security group so application traffic accepts only the proxy as its source
  • Obtained automatic TLS by pointing DNS at the floating IP and setting domain in terraform.tfvars

Scope of this deployment#

This proxy runs in one region on VMs you operate. It is a regional reverse proxy, not a global edge network: Quake AI has no anycast, no global PoPs, and no first-party CDN. For geographic distribution and volumetric DDoS absorption at the network edge, front the origin with a third-party CDN. For L7 attack filtering in front of the same shape, see front with a WAF.

The walkthrough adds a second small instance for the backend; that VM is not part of the OpenTofu template. Size the proxy with the template defaults; scale the backend independently for your application.

Next steps#

Clean up#

When you no longer need the deployment, destroy the OpenTofu stack and delete the backend resources you created in step 2:

bash
tofu destroy
openstack server delete app-backend
openstack port delete app-backend-port
openstack security group delete app-backend-sg

Remove the DNS A record you created in step 5.

Was this page helpful?