---
title: "Deploy HAProxy"
description: "The Reliable, High Perf. TCP/HTTP Load Balancer and Reverse Proxy Solution."
category: "Other"
url: https://railway.com/deploy/haproxy
---

# Deploy HAProxy

The Reliable, High Perf. TCP/HTTP Load Balancer and Reverse Proxy Solution.

**[Deploy HAProxy on Railway](https://railway.com/template/haproxy)**

- **Creator:** codestorm
- **Category:** Other
- **Total deploys:** 6

## Template content

### haproxy https://raw.githubusercontent.com/docker-library/docs/4da3e2446a4c257c3a32faac6256bee81f770316/haproxy/logo.png

- **Source:** codestorm-official/haproxy

## Documentation

# Deploy and Host HAProxy on Railway

HAProxy is a high-performance open-source load balancer and reverse proxy used to distribute traffic across backend services. It helps improve availability, route HTTP/TCP traffic, handle failover, and provide a reliable entry point for web applications, APIs, microservices, and internal services.

## About Hosting HAProxy

On Railway, HAProxy can run as a lightweight traffic layer for your application stack. It is useful when you need a dedicated reverse proxy, load balancer, simple routing layer, or central entry point for self-hosted services.

This template includes a default HAProxy configuration so the service can start immediately after deployment. You can keep the default configuration, customize it through Git/GitHub, or provide a persistent custom configuration through a Railway Volume.

## Common Use Cases

* Reverse proxy for web apps, APIs, and internal services
* Load balancing across multiple backend instances
* Routing requests by domain, path, port, or service type
* Improving reliability with backend health checks and failover
* Central traffic entry point for microservices
* HTTP and TCP proxying for self-hosted applications

## Dependencies for HAProxy Hosting

* HAProxy Docker image
* A valid HAProxy configuration
* One or more backend services to proxy traffic to
* Railway public networking or private service networking
* Optional Railway Volume mounted at `/data` for persistent custom config

### Deployment Dependencies

* [HAProxy Docker Image](https://hub.docker.com/_/haproxy)
* [HAProxy Documentation](https://www.haproxy.org/)
* [Railway Documentation](https://docs.railway.com/)

## Configuration

This template supports two HAProxy configuration paths:

| Config Path                          | Purpose                                               |
| ------------------------------------ | ----------------------------------------------------- |
| `/usr/local/etc/haproxy/haproxy.cfg` | Default config included in the image                  |
| `/data/haproxy.cfg`                  | Optional persistent custom config from Railway Volume |

By default, HAProxy uses:

```txt
/usr/local/etc/haproxy/haproxy.cfg
```

If a Railway Volume is attached and this file exists:

```txt
/data/haproxy.cfg
```

the container will automatically use `/data/haproxy.cfg` instead of the default image configuration.

Startup behavior:

```txt
/data/haproxy.cfg exists     -&gt; use /data/haproxy.cfg
/data/haproxy.cfg not found  -&gt; use /usr/local/etc/haproxy/haproxy.cfg
```

This lets the template work immediately after deployment while still supporting persistent user-managed configuration.

## Using Custom Configuration

To customize HAProxy persistently, create or update:

```txt
/data/haproxy.cfg
```

After editing the config, always validate it:

```sh
haproxy -c -f /data/haproxy.cfg
```

If the configuration is valid, restart or redeploy the Railway service.

HAProxy does not automatically reload config changes just because the file was edited.

## Update Configuration via Railway Console

Open your HAProxy service in Railway, then open the **Console** tab.

View the default config:

```sh
cat /usr/local/etc/haproxy/haproxy.cfg
```

Copy the default config into the Railway Volume:

```sh
cp /usr/local/etc/haproxy/haproxy.cfg /data/haproxy.cfg
```

Edit the custom config:

```sh
vi /data/haproxy.cfg
```

If `vi` is unavailable, overwrite the file manually:

```sh
cat &gt; /data/haproxy.cfg &lt;&lt;'EOF'
global
    maxconn 4096
    log stdout format raw local0
    log stdout format raw local1 notice
    user root
    chroot /

defaults
    log     global
    mode    http
    option  httplog
    timeout connect 5000
    timeout client  50000
    timeout server  50000

frontend main
    bind *:80
    http-request return status 200 content-type text/plain string "Custom HAProxy config from /data is running."

listen stats
    bind *:8404
    stats enable
    stats admin if TRUE
    stats uri /stats

EOF
```

Validate the config:

```sh
haproxy -c -f /data/haproxy.cfg
```

Then restart or redeploy the service from Railway.

After restart, logs should show that HAProxy is using:

```txt
/data/haproxy.cfg
```

## Update Configuration via Railway CLI

Install and authenticate Railway CLI, then link your project:

```sh
railway login
railway link
```

Open an interactive shell inside the deployed service:

```sh
railway ssh
```

If your project has multiple services, select the HAProxy service.

Copy the default config to the persistent volume:

```sh
cp /usr/local/etc/haproxy/haproxy.cfg /data/haproxy.cfg
```

Edit it:

```sh
vi /data/haproxy.cfg
```

Or overwrite it:

```sh
cat &gt; /data/haproxy.cfg &lt;&lt;'EOF'
global
    maxconn 4096
    log stdout format raw local0
    log stdout format raw local1 notice
    user root
    chroot /

defaults
    log     global
    mode    http
    option  httplog
    timeout connect 5000
    timeout client  50000
    timeout server  50000

frontend main
    bind *:80
    http-request return status 200 content-type text/plain string "Custom HAProxy config from Railway CLI is running."

listen stats
    bind *:8404
    stats enable
    stats admin if TRUE
    stats uri /stats

EOF
```

Validate it:

```sh
haproxy -c -f /data/haproxy.cfg
```

Exit the shell:

```sh
exit
```

Restart the service:

```sh
railway restart
```

Use redeploy if you want to trigger a new deployment:

```sh
railway redeploy
```

## Update Configuration via Git / GitHub

Use this workflow if you want to manage HAProxy changes through GitHub and let Railway redeploy after every push.

Source repository:

```txt
https://github.com/codestorm-official/haproxy
```

Steps:

1. Deploy the template on Railway.
2. Open the deployed HAProxy service in Railway.
3. Open **Source Repo** or **Upstream Repo** from the Railway dashboard.
4. Fork the repository to your own GitHub account.
5. Clone your fork locally:

```sh
git clone https://github.com/YOUR_USERNAME/haproxy.git
cd haproxy
```

6. Edit the default HAProxy config:

```txt
haproxy.cfg
```

This file is copied into the image as:

```txt
/usr/local/etc/haproxy/haproxy.cfg
```

7. Validate locally if HAProxy is installed:

```sh
haproxy -c -f haproxy.cfg
```

8. Commit and push your changes:

```sh
git add .
git commit -m "Customize HAProxy configuration"
git push origin main
```

9. In Railway, change the service **Source Repo** to your fork if Railway does not automatically link it.
10. After the service is connected to your fork, future pushes can trigger automatic redeployments.

Important: Git/GitHub changes update the default image config. If `/data/haproxy.cfg` exists, HAProxy will still use `/data/haproxy.cfg` instead of the Git-based default config.

To use the Git/GitHub config again, remove the custom volume config:

```sh
rm /data/haproxy.cfg
```

Then restart or redeploy the service.

## Console vs CLI vs GitHub

| Method          | Best For                                                                  |
| --------------- | ------------------------------------------------------------------------- |
| Railway Console | Quick edits, testing, emergency changes                                   |
| Railway CLI     | Terminal-based edits, debugging, validating inside the service            |
| Git / GitHub    | Version control, team collaboration, cleaner rollback, production changes |

For production or reusable templates, Git/GitHub is usually the cleanest workflow because every change is tracked in commit history.

## Roll Back to Default Configuration

If your custom config breaks or you want to return to the default image config, remove:

```sh
rm /data/haproxy.cfg
```

Then restart the service.

On the next startup, HAProxy will fall back to:

```txt
/usr/local/etc/haproxy/haproxy.cfg
```

## Example Backend Configuration

Example backend for one Railway service:

```haproxy
backend app_backend
    balance roundrobin
    server app1 your-service.railway.internal:3000 check
```

Example backend for multiple Railway services:

```haproxy
backend app_backend
    balance roundrobin
    server app1 app-1.railway.internal:3000 check
    server app2 app-2.railway.internal:3000 check
```

Example frontend using the backend:

```haproxy
frontend main
    bind *:80
    default_backend app_backend
```

Replace the service names and ports with your actual Railway service private domains and internal ports.

## Important Notes

* Editing `haproxy.cfg` does not reload HAProxy automatically.
* Always validate the config before restarting the service.
* Use `/data/haproxy.cfg` for persistent custom configuration.
* Use `/usr/local/etc/haproxy/haproxy.cfg` as the default image configuration.
* If `/data/haproxy.cfg` exists, it takes priority over the default config.
* If `/data/haproxy.cfg` does not exist, the default image config is used.
* If the last line of `haproxy.cfg` is missing a newline, HAProxy may fail with a `Missing LF on last line` error.

## Why Deploy HAProxy on Railway?

Railway is a singular platform to deploy your infrastructure stack. Railway hosts your infrastructure so you do not have to deal with manual server configuration, while still allowing you to scale vertically and horizontally.

By deploying HAProxy on Railway, you are one step closer to supporting a complete full-stack application with minimal burden. Host your servers, databases, AI agents, and more on Railway.


## Similar templates

- [Rocky Linux](https://railway.com/deploy/rocky-linux) — Hosted Rocky Linux 9 workspace with SSH and persistent storage. 🚀
- [Foundry Virtual Tabletop](https://railway.com/deploy/X5tR6G) — A Self-Hosted & Modern Roleplaying Platform
- [Letta Code Remote](https://railway.com/deploy/letta-code-remote) — Run a Letta Code agent 24/7. No inbound ports, just deploy.

Open this page in a browser: https://railway.com/deploy/haproxy
