konstantine

konstantine

Is using a reverse proxy considered best practice for a Phoenix setup?

There are use cases where a reverse proxy may be a necessity. There are administrators that are may be used to having a reverse proxy in place. More generally, however, do you consider the use of a reverse proxy to be best practice for a Phoenix setup?

Cowboy is great, for instance, but support for newer protocols (HTTP2, TLS 1.3) tends to lag considerably behind the likes of Nginx or Caddy. On the other hand, having fewer moving parts (here a lone Cowboy) is usually preferable. Other than the obvious “it depends”, what do you think?

First Post!

LostKobrakai

LostKobrakai

Caddy 2 supports http2 (but afaik you need tls setup for the upstream server):

Edit: Seems this has also been the case for caddy v1

Most Liked

konstantine

konstantine

Having now spent some time experimenting with Caddy 2, I wish to share my experience as to how it complements my Phoenix setup, by compiling a list of areas in which Caddy excels:

• adding support for the latest protocols, such as TLS 1.3 or HTTP/3 (experimental)
• serving a maintenance page when the Cowboy / Phoenix web server is down
• adding security and other headers to all requests, or to a broad range of requests
• adding an authentication token header, e.g. to protect a staging server
• redirecting automatically from the domain root to the www subdomain
• dealing with the issue of trailing slashes in URL paths

On the contrary, I found that for complex request-specific operations (such as the addition of Content Security Policy headers), Caddy is not the right tool. Phoenix mechanisms offer far more flexibility.

I hope that someone finds this information useful.

konstantine

konstantine

Just to bring some closure to this thread:

I decided to go down the reverse proxy path and tried Caddy. I got TLS 1.3 working in no time and removed much more configuration than I added! My basic setup required a Caddyfile as simple as this:

{
  http_port   [port1]
  https_port  [port2]
}

cdn.[my.website] www.[my.website] {
  reverse_proxy [ipv4]:[port3]
}

[my.website] {
  header strict-transport-security "max-age=63072000; includesubdomains; preload"
  redir https://www.[my.website]{uri}
}

derpycoder

derpycoder

I am using Caddy, not only in production, but also in local. As it allows me to forget random port number to access different sub programs running alongside the server.

Plus I get HTTP/3, HTTPS and ease of configuration.

(common) {
	header /* {
		-server
		-X-Powered-By
		-via
	}
	@static {
		file
		path *.ico *.css *.js *.gif *.webp *.avif *.jpg *.jpeg *.png *.svg *.woff *.woff2
	}
	header @static cache-control "max-age=0; must-revalidate; public;"

	handle_errors {
		@custom_err file /errors/{err.status_code}.html /errors/error.html
		handle @custom_err {
			rewrite * {file_match.relative}
			file_server
		}
		respond "{err.status_code} {err.status_text}"
	}
}

www.derpytools.site {
	redir https://derpytools.site permanent
}

derpytools.site {
	tls certs/caddy/cert.pem certs/caddy/key.pem
	# tls /etc/caddy/certs/cert.pem /etc/caddy/certs/key.pem
	encode zstd gzip

	# Directly reverse proxy to Phoenix
	reverse_proxy localhost:4000

	# Proxy to Varnish Cache (Only use with production builds)
	# reverse_proxy localhost:3080

	import common
}

img.derpytools.site {
	# Directly reverse proxy to imgproxy
	reverse_proxy localhost:9080

	# Reverse proxy to Varnish cache instead (Only use with production builds)
	# reverse_proxy localhost:3080 {
	# 	# header_down Cache-Control "max-age=0; must-revalidate; public;"
	# 	# header_down Cache-Control "public; max-age=31536000; immutable;"
	# }

	import common
}

docs.derpytools.site {
	encode zstd gzip

	root * doc
	file_server browse
}

netdata.derpytools.site {
	encode zstd gzip

	reverse_proxy localhost:19999

	basicauth * {
		DerpyCoder $2b$05$4N/0p0i/fsNkiYHhNs9yruEMPbiOsQqxEfMkmrkan9w5hKNxSFRdK
	}

	import common
}

canary.derpytools.site {
	encode zstd gzip

	reverse_proxy localhost:4001

	basicauth * {
		DerpyCoder $2b$05$4N/0p0i/fsNkiYHhNs9yruEMPbiOsQqxEfMkmrkan9w5hKNxSFRdK
	}

	import common
}

metrics.derpytools.site {
	metrics

	import common
}

livebook.derpytools.site {
	encode zstd gzip

	reverse_proxy localhost:49223
}

search.derpytools.site {
	encode zstd gzip

	reverse_proxy localhost:7700
}

grafana.derpytools.site {
	encode zstd gzip

	reverse_proxy localhost:3000
}

prometheus.derpytools.site {
	encode zstd gzip

	reverse_proxy localhost:9090
}

Last Post!

gpartha

gpartha

Thanks for coming back to me. I am leaning more towards Nginx as my reverse proxy, Looking to use the proxy server and also do the Authentication and Authorisation using Vouch Proxy.

The key question I am struggling with is - Should I use Phoenix to do the Authentication and Authorisation with Identity providers or use specific components like Vouch Proxy!!! Increases the moving parts in the deployment but has dedicated elements for specific functionality.

Any suggestions and advice is welcome.

Where Next?

Trending in Questions Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
tj0
I’ve been following the steps here for the upgrade from 1.6 to 1.7 and it has gone relatively smoothly all the way till the phoenix_view ...
New
cgraham
Hi! What is currently the best library/method for parsing text and tabular data out of PDF files in Elixir or Erlang?
New
stefanchrobot
Hi, I need a way to handle data migrations in my application. I found an article by @wojtekmach about manual migrations: Automatic and ma...
New
stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New
webofbits
Squid Mesh is an open source workflow automation runtime for Elixir applications. It is aimed at Phoenix and OTP apps that want to defin...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
kip
In 2021 I started a new library called Tempo with the objective of modelling time as a set of intervals - not as instants. In 2022 I gave...
New

We're in Beta

About us Mission Statement