Skip Navigation
Show nav
Dev Center
  • Get Started
  • Documentation
  • Changelog
  • Search
  • Get Started
    • Node.js
    • Ruby on Rails
    • Ruby
    • Python
    • Java
    • PHP
    • Go
    • Scala
    • Clojure
    • .NET
  • Documentation
  • Changelog
  • More
    Additional Resources
    • Home
    • Elements
    • Products
    • Pricing
    • Careers
    • Help
    • Status
    • Events
    • Podcasts
    • Compliance Center
    Heroku Blog

    Visit the Heroku Blog

    Find news and updates from Heroku in the blog.

    Visit Blog
  • Log inorSign up
Hide categories

Categories

  • Heroku Architecture
    • Compute (Dynos)
      • Dyno Management
      • Dyno Concepts
      • Dyno Behavior
      • Dyno Reference
      • Dyno Troubleshooting
    • Stacks (operating system images)
    • Networking & DNS
    • Platform Policies
    • Platform Principles
  • Developer Tools
    • Command Line
    • Heroku VS Code Extension
  • Deployment
    • Deploying with Git
    • Deploying with Docker
    • Deployment Integrations
  • Continuous Delivery & Integration (Heroku Flow)
    • Continuous Integration
  • Language Support
    • Node.js
      • Troubleshooting Node.js Apps
      • Working with Node.js
      • Node.js Behavior in Heroku
    • Ruby
      • Rails Support
      • Working with Bundler
      • Working with Ruby
      • Ruby Behavior in Heroku
      • Troubleshooting Ruby Apps
    • Python
      • Working with Python
      • Background Jobs in Python
      • Python Behavior in Heroku
      • Working with Django
    • Java
      • Java Behavior in Heroku
      • Working with Java
      • Working with Maven
      • Working with Spring Boot
      • Troubleshooting Java Apps
    • PHP
      • Working with PHP
      • PHP Behavior in Heroku
    • Go
      • Go Dependency Management
    • Scala
    • Clojure
    • .NET
      • Working with .NET
  • Databases & Data Management
    • Heroku Postgres
      • Postgres Basics
      • Postgres Getting Started
      • Postgres Performance
      • Postgres Data Transfer & Preservation
      • Postgres Availability
      • Postgres Special Topics
      • Migrating to Heroku Postgres
    • Heroku Key-Value Store
    • Apache Kafka on Heroku
    • Other Data Stores
  • AI
    • Working with AI
    • Heroku Inference
      • Inference API
      • Quick Start Guides
      • Inference Essentials
      • AI Models
    • Vector Database
    • Model Context Protocol
  • Monitoring & Metrics
    • Logging
  • App Performance
  • Add-ons
    • All Add-ons
  • Collaboration
  • Security
    • App Security
    • Identities & Authentication
      • Single Sign-on (SSO)
    • Private Spaces
      • Infrastructure Networking
    • Compliance
  • Heroku Enterprise
    • Enterprise Accounts
    • Enterprise Teams
    • Heroku Connect (Salesforce sync)
      • Heroku Connect Administration
      • Heroku Connect Reference
      • Heroku Connect Troubleshooting
  • Patterns & Best Practices
  • Extending Heroku
    • Platform API
    • App Webhooks
    • Heroku Labs
    • Building Add-ons
      • Add-on Development Tasks
      • Add-on APIs
      • Add-on Guidelines & Requirements
    • Building CLI Plugins
    • Developing Buildpacks
    • Dev Center
  • Accounts & Billing
  • Troubleshooting & Support
  • Integrating with Salesforce
  • Add-ons
  • All Add-ons
  • Fixie
Fixie

This add-on is operated by Fixie

Static IP addresses for outbound HTTP and HTTPS requests

Fixie

Last updated October 26, 2022

Table of Contents

  • Provisioning the add-on
  • Your static IP addresses
  • Dashboard
  • Local setup
  • Using with Node
  • Using with Ruby
  • Using with Python
  • Using with Java
  • Using with Go
  • Using with PHP
  • Using with .NET
  • Using with other languages
  • End-to-end encryption of HTTPS requests
  • Migrating between plans
  • Removing the add-on
  • Connecting through a single IP address
  • Support

Fixie is an add-on that provides Heroku applications with a fixed set of static IP addresses for outbound requests. Fixie is language- and framework-agnostic.

Without Fixie, your Heroku application makes requests from an unpredictable and impermanent set of IP addresses. Because Heroku IPs are dynamic, it can be difficult to integrate Heroku applications with services that allowlist a fixed IP range, including certain APIs and services that operate behind a corporate firewall.

Fixie acts as a proxy for outbound traffic, tunneling your requests through a known IP address. Each Fixie subscriber is assigned a set of static IP addresses. These addresses can be used anywhere you need a fixed IP range: API providers, firewall configurations, etc.

Fixie provides customers with a standard proxy URL that can be used to make requests from any server-side language, including Ruby, Python, Node, Java, and Go. Fixie can also be used by CURL and other command-line tools. Fixie can proxy both HTTP traffic and HTTPS traffic.

Provisioning the add-on

Fixie can be attached to a Heroku application via the CLI:

A list of all plans available can be found here.

To add our free plan (the default):

$ heroku addons:add fixie
-----> Adding fixie to sharp-mountain-4005... done, v18 (free)

Once Fixie has been added, a FIXIE_URL setting will be available in the app configuration and will contain the outbound proxy URL. This can be confirmed using the heroku config:get command.

$ heroku config:get FIXIE_URL
http://fixie:your-token@your-subdomain.usefixie.com:80

Your static IP addresses

You can retrieve your static IP addresses in the “Account” tab of the Fixie Dashboard. Your IP adresses are listed under “Account Details.”

Your static IP addresses are also shown in the command line when you enable Fixie using the Heroku CLI:

$ heroku addons:add fixie
Adding fixie to sharp-mountain-4005… done, v18 (free)
Your static IP addresses are 54.174.229.200, 54.176.231.252

Dashboard

The Fixie dashboard can be used to monitor your Fixie usage, retrieve your Fixie URL, and retrieve your outbound static IPs.

The dashboard can be accessed by visiting the Heroku Dashboard and selecting the application in question. Select Fixie from the Add-ons menu.

The dashboard can also be accessed via the CLI:

$ heroku addons:open fixie
Opening fixie for sharp-mountain-4005…

Local setup

Environment setup

If you wish to use Fixie to proxy requests while developing locally, it is necessary to locally replicate the FIXIE_URL environment variable.

Though less portable, it is also possible to set local environment variables using export FIXIE_URL=value.

Use Foreman to configure, run and manage process types specified in your app’s Procfile. Foreman reads configuration variables from an .env file. Use the following command to add the FIXIE_URL values retrieved from heroku config to .env.

$ heroku config -s | grep FIXIE_URL >> .env
$ more .env

Credentials and other sensitive configuration values should not be committed to source-control. In Git, exclude the .env file with: echo .env >> .gitignore.

Using with Node

Fixie works with both the standard http and https modules and with higher-level http clients, including the popular axios library.

These examples assume the FIXIE_URL environment variable is set. For instructions on setting this variable on your local machine, see the Local Setup section.

Using Axios:

const axios = require('axios');
const url = require('url');
const fixieUrl = url.parse(process.env.FIXIE_URL);
const fixieAuth = fixieUrl.auth.split(':');

axios.get('https://example.com', {
  proxy: {
    protocol: 'http',
    host: fixieUrl.hostname,
    port: fixieUrl.port,
    auth: {username: fixieAuth[0], password: fixieAuth[1]}
  }
}).then(response => {
  console.log(response.status);
});

Using with Ruby

You can use Fixie with any Ruby http client. Included are example of using it with Net::HTTP from the standard library and with popular rest-client or faraday gems.

These examples assume the FIXIE_URL environment variable is set. For instructions on setting this variable on your local machine, see the Local Setup section.

Using rest-client:

require 'rest-client'
RestClient.proxy = ENV["FIXIE_URL"]
response = RestClient.get("http://welcome.usefixie.com")

Using faraday:

require 'faraday'
conn = Faraday.new(:url => "http://welcome.usefixie.com", :proxy => ENV["FIXIE_URL"])
response = conn.get

Using with httparty:

fixie = URI.parse ENV['FIXIE_URL']

HTTParty.get(
  "http://welcome.usefixie.com",
  http_proxyaddr: fixie.host,
  http_proxyport: fixie.port,
  http_proxyuser: fixie.user,
  http_proxypass: fixie.password
)

Using Net::HTTP from the standard library:

require 'net/http'
_, username, password, host, port = ENV["FIXIE_URL"].gsub(/(:|\/|@)/,' ').squeeze(' ').split
uri       = URI("http://welcome.usefixie.com")
request   = Net::HTTP.new(uri.host, uri.port, host, port, username, password)
response  = request.get(uri)

Using with Python

Fixie works with any http client library, including urllib2 from the standard library and third-party packages including the popular requests package.

These examples assume the FIXIE_URL environment variable is set. For instructions on setting this variable on your local machine, see the Local Setup section.

To route a specific request through Fixie using requests:

import os, requests
proxyDict = {
              "http"  : os.environ.get('FIXIE_URL', ''),
              "https" : os.environ.get('FIXIE_URL', '')
            }
r = requests.get('http://www.example.com', proxies=proxyDict)

Using urllib2 to send a specific request through Fixie:

import os, urllib2
proxy  = urllib2.ProxyHandler({'http': os.environ.get('FIXIE_URL', '')})
auth   = urllib2.HTTPBasicAuthHandler()
opener = urllib2.build_opener(proxy, auth, urllib2.HTTPHandler)
response = opener.open('http://www.example.com')
html = response.read()

The urllib2 API is significantly more verbose than that of the requests package. The requests package is a better choice for most applications.

If you intend to route all outbound traffic through Fixie, a simpler option is to set the http_proxy and https_proxy environment variables. Both urllib2 and requests honor the http_proxy and https_proxy environment variables, so you can route all outbound requests through Fixie using these environment variables:

import os, requests
os.environ['http_proxy'] = os.environ.get('FIXIE_URL', '')
os.environ['https_proxy'] = os.environ.get('FIXIE_URL', '')
requests.get("http://www.example.com")

Using with Java

You can use Fixie with any HTTP library. Popular options include Apache HttpClient and OkHttp.

These examples assume the FIXIE_URL environment variable is set. For instructions on setting this variable on your local machine, see the Local Setup section.

A simple example using HttpClient:

import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

public class FixieExample
{
    public static void main(String[] args) throws Exception {
        String fixieUrl = System.getenv("FIXIE_URL");

        String[] fixieValues = fixieUrl.split("[/(:\\/@)/]+");
        String fixieUser = fixieValues[1];
        String fixiePassword = fixieValues[2];
        String fixieHost = fixieValues[3];
        int fixiePort = Integer.parseInt(fixieValues[4]);

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope(fixieHost, fixiePort),
                new UsernamePasswordCredentials(fixieUser, fixiePassword));
        CloseableHttpClient httpclient = HttpClients.custom()
                .setDefaultCredentialsProvider(credsProvider).build();
        try {
            HttpHost proxy = new HttpHost(fixieHost, fixiePort);
            RequestConfig config = RequestConfig.custom()
                .setProxy(proxy)
                .build();

            HttpHost target = new HttpHost("www.example.com", 80, "http");
            HttpGet httpget = new HttpGet("/");
            httpget.setConfig(config);

            CloseableHttpResponse response = httpclient.execute(target, httpget);
            try {
                System.out.println(EntityUtils.toString(response.getEntity()));
            } finally {
                response.close();
            }
        } finally {
            httpclient.close();
        }
    }
}

Or, for projects that use OkHttp:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import okhttp3.OkHttpClient;
import okhttp3.Authenticator;
import okhttp3.Credentials;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.Route;

public class FixieExample
{
    public static void main(String[] args) throws Exception {
        String fixieUrl = System.getenv("FIXIE_URL");
        String[] fixieValues = fixieUrl.split("[/(:\\/@)/]+");
        String fixieUser = fixieValues[1];
        String fixiePassword = fixieValues[2];
        String fixieHost = fixieValues[3];
        int fixiePort = Integer.parseInt(fixieValues[4]);

        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
        Authenticator proxyAuthenticator = new Authenticator() {
          @Override public Request authenticate(Route route, Response response) throws IOException {
               String credential = Credentials.basic(fixieUser, fixiePassword);
               return response.request().newBuilder()
                   .header("Proxy-Authorization", credential)
                   .build();
          }
        };
        clientBuilder.proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress(fixieHost, fixiePort)))
        .proxyAuthenticator(proxyAuthenticator);

        OkHttpClient client = clientBuilder.build();
        Request request = new Request.Builder().url("http://www.example.com").build();
        Response response = client.newCall(request).execute();

        System.out.println(response.body().string());
    }
}

Using with Go

These examples assume the FIXIE_URL environment variable is set. For instructions on setting this variable on your local machine, see the Local Setup section.

To use Fixie for specific http requests, you can create a custom http.Client:

package main

import (
  "net/url"
  "net/http"
  "os"
  "io/ioutil"
)
func main () {
  fixieUrl, err := url.Parse(os.Getenv("FIXIE_URL"))
  customClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(fixieUrl)}}
  resp, err := customClient.Get("http://welcome.usefixie.com")
  if (err != nil) {
    println(err.Error())
    return
  }
  defer resp.Body.Close()
  body, err := ioutil.ReadAll(resp.Body)
  println(string(body))
}

If you intend to use Fixie for all outbound requests, an alternative is to use the HTTP_PROXY and HTTPS_PROXY environment variables. Go honors these environment variables by default. You can set HTTP_PROXY and HTTPS_PROXY in your application, typically in main.go:

package main

import (
  "net/http"
  "os"
  "io/ioutil"
)
func main () {
  os.Setenv("HTTP_PROXY", os.Getenv("FIXIE_URL"))
  os.Setenv("HTTPS_PROXY", os.Getenv("FIXIE_URL"))
  resp, err := http.Get("http://welcome.usefixie.com")
  if (err != nil) {
    println(err.Error())
    return
  }
  defer resp.Body.Close()
  body, err := ioutil.ReadAll(resp.Body)
  println(string(body))
}

Using with PHP

These examples assume the FIXIE_URL environment variable is set. For instructions on setting this variable on your local machine, see the Local Setup section.

PHP cURL is the easiest way to get your PHP application working correctly with Fixie. Here’s how:

<?php
  function proxyRequest() {
    $fixieUrl = getenv("FIXIE_URL");
    $parsedFixieUrl = parse_url($fixieUrl);

    $proxy = $parsedFixieUrl['host'].":".$parsedFixieUrl['port'];
    $proxyAuth = $parsedFixieUrl['user'].":".$parsedFixieUrl['pass'];

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_PROXY, $proxy);
    curl_setopt($ch, CURLOPT_PROXYUSERPWD, $proxyAuth);
    curl_close($ch);
  }

  $response = proxyRequest();
  print_r($response);
?>

Using with .NET

HttpWebRequest myWebRequest=(HttpWebRequest)WebRequest.Create("https://www.example.com");
WebProxy fixie=new WebProxy();
fixie.Address=new Uri(FIXIE_ADDRESS);
fixie.Credentials=new NetworkCredential("fixie",FIXIE_TOKEN);
myWebRequest.Proxy=fixie;

See Microsoft’s documentation for more information.

Using with other languages

The FIXIE_URL environment variable is a standard proxy URL that can be used by request libraries in any language. You can also use Fixie directly in cURL and other command-line tools:

curl http://welcome.usefixie.com --proxy $FIXIE_URL

This example assumes the FIXIE_URL environment variable is set. For instructions on setting this variable on your local machine, see the Local Setup section.

End-to-end encryption of HTTPS requests

When your application makes a request to an HTTPS resource via Fixie, your application sends a CONNECT request to Fixie. This request instructs Fixie to open a TCP connection to the remote host. Once this connection has been established, Fixie transparently tunnels this connection. Neither Fixie nor any other party has the ability to decrypt this traffic. The proxy negotiation (the initial CONNECT request to Fixie) happens in the clear, but the connection with the remote host remains encrypted end-to-end.

For more information, see Wikipedia’s article on HTTP tunnels

Migrating between plans

Use the heroku addons:upgrade command to migrate to a new plan.

$ heroku addons:upgrade fixie:newplan
-----> Upgrading fixie:newplan to sharp-mountain-4005... done, v18 ($49/mo)
       Your plan has been updated to: fixie:newplan

Removing the add-on

Fixie can be removed via the CLI.

This will destroy all associated data and cannot be undone!

$ heroku addons:remove fixie
-----> Removing fixie from sharp-mountain-4005... done, v20 (free)

Connecting through a single IP address

By default, Fixie provides a load-balance pair of IP addresses. This allows us to provide very high (>99.99%) availability by load balancing across two availability zones.

If you have an external dependency that can only whitelist a single IP address, you can connect to a single IP in the cluster. To do this, replace the proxy group URL with either of the proxy IP addresses. So instead of http://fixie:abcd1234@pannier.usefixie.com:80, connect to http://fixie:abcd1234@54.173.229.123:80.

Connecting to a single IP address theoretically comes at some cost of availability, but in practice, this is tolerable for most applications.

Support

All Fixie support and runtime issues should be submitted via one of the Heroku Support channels. Any non-support related issues or product feedback is welcome at team@usefixie.com.

Keep reading

  • All Add-ons

Feedback

Log in to submit feedback.

Zara 4 Fixie Socks

Information & Support

  • Getting Started
  • Documentation
  • Changelog
  • Compliance Center
  • Training & Education
  • Blog
  • Support Channels
  • Status

Language Reference

  • Node.js
  • Ruby
  • Java
  • PHP
  • Python
  • Go
  • Scala
  • Clojure
  • .NET

Other Resources

  • Careers
  • Elements
  • Products
  • Pricing
  • RSS
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku Blog
    • Heroku News Blog
    • Heroku Engineering Blog
  • Twitter
    • Dev Center Articles
    • Dev Center Changelog
    • Heroku
    • Heroku Status
  • Github
  • LinkedIn
  • © 2025 Salesforce, Inc. All rights reserved. Various trademarks held by their respective owners. Salesforce Tower, 415 Mission Street, 3rd Floor, San Francisco, CA 94105, United States
  • heroku.com
  • Legal
  • Terms of Service
  • Privacy Information
  • Responsible Disclosure
  • Trust
  • Contact
  • Cookie Preferences
  • Your Privacy Choices