QuotaGuard and Gigalixir Integration Guide

QuotaGuard Static IPs allow your Gigalixir applications to send outbound traffic through a load-balanced pair of static IP addresses. Once set up, you can use QuotaGuard’s IPs to connect to firewalled databases and APIs that require IP allowlisting. Gigalixir supports Elixir, Node, Python, Ruby, and Go, and this works across all of them.

You do not need QuotaGuard for internal Gigalixir clustering. Distributed Erlang clustering with libcluster runs over Gigalixir’s internal network and is unaffected. QuotaGuard handles outbound traffic to external services that require a known, static source IP.

Why Gigalixir Apps Need Static IPs

Gigalixir runs your app in containers with dynamically assigned IP addresses, so outbound traffic leaves from an address that changes. Gigalixir offers Dedicated Ingress for static inbound IPs, such as apex domains and webhook receivers, but that is inbound only. It does not give you a static outbound egress IP. Gigalixir’s own documentation recommends QuotaGuard for outbound static IPs.

Common scenarios where you need a static outbound IP:

  • MongoDB Atlas: Requires IP allowlisting in Network Access settings
  • Amazon RDS and managed Postgres: Security groups with IP-based rules
  • Payment and banking APIs: Only accept requests from registered IPs
  • Partner APIs: Corporate firewalls that require known source addresses
  • Legacy systems: On-premise databases and ERPs with strict firewall policies

Getting Started

After creating a QuotaGuard account, you are redirected to your dashboard, where you can find your proxy credentials and two static IP addresses.

Choose the right proxy region: Select the QuotaGuard region closest to where your Gigalixir app runs to minimize latency. The region is set at sign-up. Changes after sign-up require contacting support.

Your proxy URL looks like this:

http://username:password@<your-quotaguard-proxy-host>:9293

Configuring Your Application

Step 1: Add Your Proxy URL as a Config Variable

Store your QuotaGuard credentials as a Gigalixir config variable. Keep them out of your Git repository.

gigalixir config:set QUOTAGUARDSTATIC_URL="http://username:password@<your-quotaguard-proxy-host>:9293"

Verify it was set:

gigalixir config

You should see QUOTAGUARDSTATIC_URL in the list.

For Elixir Releases: config variables are available as OS environment variables at runtime. Read them in config/runtime.exs so they are evaluated when the release boots, not at compile time:

# config/runtime.exs
config :my_app, :proxy_url, System.get_env("QUOTAGUARDSTATIC_URL")

Step 2: Configure Your HTTP Client

Route the outbound calls that need a static IP through the proxy. The Elixir clients are below, followed by Node, Python, Ruby, and Go for polyglot Gigalixir apps.

Elixir (Req)

proxy_url = System.get_env("QUOTAGUARDSTATIC_URL")
uri = URI.parse(proxy_url)

Req.get!("https://api.example.com/data",
  connect_options: [
    proxy: {:http, uri.host, uri.port, []},
    proxy_headers: [{"proxy-authorization", "Basic " <> Base.encode64(uri.userinfo)}]
  ]
)

Req runs on Finch and Mint, so the proxy is a {:http, host, port, opts} tuple, not a URL string, and the credentials go in proxy_headers.

Elixir (HTTPoison)

proxy_url = System.get_env("QUOTAGUARDSTATIC_URL")
uri = URI.parse(proxy_url)
[username, password] = String.split(uri.userinfo, ":")

options = [
  proxy: {String.to_charlist(uri.host), uri.port},
  proxy_auth: {String.to_charlist(username), String.to_charlist(password)}
]

{:ok, response} = HTTPoison.get("https://api.example.com/data", [], options)
IO.inspect(response.body)

Elixir (Finch)

# In your application supervision tree
proxy_url = System.get_env("QUOTAGUARDSTATIC_URL")
uri = URI.parse(proxy_url)

Finch.start_link(
  name: MyFinch,
  pools: %{
    :default => [
      conn_opts: [
        proxy: {:http, uri.host, uri.port, []},
        proxy_headers: [{"proxy-authorization", "Basic " <> Base.encode64(uri.userinfo)}]
      ]
    ]
  }
)

Elixir (Tesla with Hackney adapter)

proxy_url = System.get_env("QUOTAGUARDSTATIC_URL")
uri = URI.parse(proxy_url)
[user, pass] = String.split(uri.userinfo, ":")

client = Tesla.client([], {Tesla.Adapter.Hackney, [
  proxy: {uri.host, uri.port},
  proxy_auth: {user, pass}
]})

Tesla.get(client, "https://api.example.com/data")

Requires the hackney dependency.

Node.js (axios with https-proxy-agent)

const axios = require('axios');
const { HttpsProxyAgent } = require('https-proxy-agent');

const agent = new HttpsProxyAgent(process.env.QUOTAGUARDSTATIC_URL);

axios.get('https://api.example.com/data', { httpsAgent: agent })
  .then(response => console.log(response.data));

Install the agent: npm install https-proxy-agent

Python (requests)

import os, requests

proxy_url = os.environ['QUOTAGUARDSTATIC_URL']
proxies = {'http': proxy_url, 'https': proxy_url}

response = requests.get('https://api.example.com/data', proxies=proxies)
print(response.json())

Ruby (Net::HTTP)

require 'net/http'
require 'uri'

proxy = URI.parse(ENV['QUOTAGUARDSTATIC_URL'])
http = Net::HTTP.new('api.example.com', 443, proxy.host, proxy.port, proxy.user, proxy.password)
http.use_ssl = true

puts http.get('/data').body

Go

proxyURL, _ := url.Parse(os.Getenv("QUOTAGUARDSTATIC_URL"))
client := &http.Client{
    Transport: &http.Transport{Proxy: http.ProxyURL(proxyURL)},
}
resp, _ := client.Get("https://api.example.com/data")
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(string(body))

Connecting to Firewalled Databases with QGTunnel

For database connections such as PostgreSQL, MySQL, or MongoDB, use QuotaGuard’s SOCKS5 proxy through QGTunnel. QGTunnel transparently routes your Ecto traffic through your static IPs without changing your connection code.

Step 1: Add QGTunnel to Your Release

Download QGTunnel and include it in your release overlay so it ships inside the container:

mkdir -p rel/overlays/bin
curl https://s3.amazonaws.com/quotaguard/qgtunnel-latest.tar.gz | tar xz -C rel/overlays

This places bin/qgtunnel and vendor/nss_wrapper/ into your release.

Step 2: Prefix Your Start Command

Gigalixir reads a Procfile to determine the start command. Prefix it with bin/qgtunnel so the tunnel starts before your app:

web: bin/qgtunnel bin/my_app start

Step 3: Configure the Tunnel in the Dashboard

In the QuotaGuard dashboard, go to Setup > QGTunnel Configuration > Create a Tunnel.

Example PostgreSQL configuration:

Setting Value
Remote Destination tcp://your-database.example.com:5432
Local Port 5432
Transparent true
Encrypted false

Transparent mode overrides DNS so Ecto connects to the original database hostname while traffic routes through your static IPs. QGTunnel reads QUOTAGUARDSTATIC_URL automatically, so no code change is needed in your Repo config.

The SOCKS5 proxy is on port 1080 if you prefer to configure a driver directly instead of using QGTunnel.

Testing Your Implementation

From Your Local Machine

curl -x "$QUOTAGUARDSTATIC_URL" https://ip.quotaguard.com

Expected response:

{"ip":"<one of your two QuotaGuard static IPs>"}

The returned IP should match one of the two static IPs in your QuotaGuard dashboard. Run it more than once to see both IPs (load-balanced).

From Inside Your Running App

Add a temporary route or run it in a remote console to confirm the proxy works from the deployed container, not just locally.

proxy_url = System.get_env("QUOTAGUARDSTATIC_URL")
{:ok, resp} = Req.get("https://ip.quotaguard.com", connect_options: [proxy: proxy_url])
IO.inspect(resp.body)

Open a remote console against your running app with gigalixir ps:remote_console -a my-app and run the snippet. The IP returned must be one of your two static IPs.

Latency Considerations

Routing through QuotaGuard adds one network hop:

Configuration Added Latency
Same region (app and proxy co-located) 10-20ms
Cross-region 50-100ms

Select a QuotaGuard region that matches your Gigalixir deployment region to keep this minimal.

Troubleshooting

407 Proxy Authentication Required

Your credentials are wrong. Confirm the config variable:

gigalixir config

Check that the username and password match your QuotaGuard dashboard exactly.

Connection Timeout

  1. Confirm your app can reach external networks.
  2. Check the proxy hostname is correct.
  3. Ensure nothing blocks outbound connections to port 9293.

Wrong IP Address Returned

The proxy is not being applied to the request.

  1. Confirm the env var is read at runtime, not compile time (config/runtime.exs, not config.exs).
  2. Check you are passing the proxy to the specific request, not only setting an environment variable.
  3. Some Elixir HTTP clients require explicit per-request proxy options, as shown above.

Config Not Available at Boot

Elixir Releases evaluate config/runtime.exs at boot and config/config.exs at compile time. If you read QUOTAGUARDSTATIC_URL in compile-time config, it will be missing. Move it to config/runtime.exs.

QGTunnel Not Starting

  1. Confirm bin/qgtunnel is in your release overlay and is executable.
  2. Confirm QUOTAGUARDSTATIC_URL is set as a config variable.
  3. Enable debug logging:
gigalixir config:set QGTUNNEL_DEBUG="true"

Then check logs:

gigalixir logs | grep qgtunnel

Clustering Stopped Working

It should not. QuotaGuard only handles the outbound calls you route through it. If clustering broke, you are routing internal libcluster traffic through the proxy by mistake. Apply the proxy per external request rather than forcing all traffic through it.

QuotaGuard Static vs QuotaGuard Shield

Feature QuotaGuard Static QuotaGuard Shield
Protocol HTTP / HTTPS / SOCKS5 HTTPS / SOCKS5 over TLS
Customer-to-proxy hop Plaintext TLS-encrypted
HTTPS payload Tunneled end-to-end, never decrypted at the proxy Tunneled end-to-end, never decrypted at the proxy
Best for Most apps Regulated data or environments that require TLS on every hop
Starting price $19/month $29/month

For most Gigalixir apps, Static is the right product. Choose QuotaGuard Shield if your app handles regulated data or your environment requires TLS between your app and the proxy itself.


Ready to Get Started?

Get in touch or create a free trial account.

Try QuotaGuard Now

View Gigalixir Integration Features

Read: How to Get a Static IP for Gigalixir Apps

Contact Support


Ready to Get Started?

Get in touch or create a free trial account

Back to top ↑

Copyright © 2009 - 2026 QuotaGuard. All rights reserved.

Copyright © 2009 - 2026 QuotaGuard. All rights reserved.