Cowboy without Nginx
Phoenix is using a webserver called Cowboy, or more accurately the newest version Cowboy2
- which supports http2.
The usual approach would be to run cowboy, and then reverse-proxy requests through Nginx to port 4000
or whatever cowboy is configured to listen to.
🔥 Running cowboy on its own is possible, but does not provide many advantages over using Nginx. Especially static file serving is faster when using Nginx, but if you want to run a bare-bone Phoenix application on a server, you will have to make a few adjustments. 🔥
You should only consider setting up a server without Nginx if you have a rather simple API, without any HTML / Javascript / other static files. It does remove one of the moving parts with nginx
though.
Most of the approaches in this wiki came from this blog post
The linux permission system will not let you run an app listening on ports < 1000
when not running under root
. For security reasons, we do not want to run the app under root, so the easiest way around this is to configure iptables to redirect incoming requests on port 80
(http) and 443
(https) to - for example - 4080
and 4443
and have cowboy listen to those ports.
# prod.exs or prod.secret.exs
url: [host: "your_app.com", port: 4000, scheme: "https"],
server: true,
http: [:inet6, port: 4080],
https: [
port: 4443,
otp_app: :your_app,
cipher_suite: :strong,
keyfile: "/etc/letsencrypt/live/your_app.com/privkey.pem",
certfile: "/etc/letsencrypt/live/your_app.com/cert.pem",
cacertfile: "/etc/letsencrypt/live/your_app.com/chain.pem",
dhfile: "/etc/letsencrypt/dhparam.pem"
]
As you can see, you have to create the certificates yourself and tell cowboy where to find them. You can create certificates running certbot in standalone mode - you might have to change access rights to /etc/letsencrypt/live/your_app.com/*
files. If your application does not start with the error message "/etc/letsencrypt/live/your_app.com/privkey.pem" does not exist or can not be accessed
run
sudo chmod 0775 /etc/letsencrypt/ -R
You will probably have to create DH parameters (the dhparam.pem
file). This is a very CPU heavy and long running process (can take up to 10 minutes), so make sure your server is not doing anything meaningful while running this:
openssl dhparam -out /etc/letsencrypt/dhparam.pem 4096
An easy way of doing this is using iptables which comes preinstalled on Ubuntu servers.
# Forward requests to 443:
sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 443 -j REDIRECT --to-ports 4443
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 4443
# Forward requests to 80:
sudo iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 4080
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 4080
TODO: How do renewals work, and will cowboy load the new cert files after a renewal?