I’m trying to deploy a Phoenix liveview app behind Ngnix on a single VPS. I tried to get Phoenix to serve HTTP, while Ngnix handles HTTPS/SSL. However, I’m getting 502 bad gateway with a “Connection refused while connecting to upstream” error. Both the Phoenix server and Ngnix are running in docker containers. Does anybody know what could be going wrong?
Elixir: 1.13.4-otp-25
Phoenix: 1.6.11
Phoenix_live_view: 0.17.11
Logs from sudo docker logs --tail 50 --follow --timestamps <nginx-container-hash>
when I go to my.site.com
:
2025-05-11T08:51:05.331109428Z 2025/05/11 08:51:05 [error] 21#21: *52 connect() failed (111: Connection refused) while connecting to upstream, client: 208.123.61.54, server: my.site.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:4001/", host: "my.site.com"
2025-05-11T08:51:05.331152962Z 2025/05/11 08:51:05 [warn] 21#21: *52 upstream server temporarily disabled while connecting to upstream, client: 208.123.61.54, server: my.site.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:4001/", host: "my.site.com"
2025-05-11T08:51:05.331160447Z 2025/05/11 08:51:05 [error] 21#21: *52 connect() failed (111: Connection refused) while connecting to upstream, client: 208.123.61.54, server: my.site.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:4001/", host: "my.site.com"
2025-05-11T08:51:05.331247276Z 2025/05/11 08:51:05 [warn] 21#21: *52 upstream server temporarily disabled while connecting to upstream, client: 208.123.61.54, server: my.site.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:4001/", host: "my.site.com"
2025-05-11T08:51:05.331262155Z 208.123.61.54 - - [11/May/2025:08:51:05 +0000] "GET / HTTP/1.1" 502 157 "-" "Mozilla/5.0 (iPhone; CPU iPhone OS 17_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) FxiOS/138.0 Mobile/15E148 Safari/605.1.15" "-"
prod.exs:
config :mysite, MysiteWeb.Endpoint,
cache_static_manifest: "priv/static/cache_manifest.json",
url: [host: "my.site.com", port: 4000]
http: [ip: {0, 0, 0, 0}, port: 4000],
check_origin: false,
server: true,
check_origin: ["https://my.site.com"],
secret_key_base: Map.fetch!(System.get_env(), "SECRET_KEY_BASE")
config :mysite, MySite.Repo,
start_apps_before_migration: [:ssl],
adapter: Ecto.Adapters.Postgres,
url: System.get_env("DATABASE_URL"),
ssl: true,
pool_size: 10
Nginx:
server {
listen 443 default_server ssl;
listen [::]:443 ssl;
server_name my.site.com;
ssl_certificate /etc/nginx/ssl/live/my.site.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/my.site.com/privkey.pem;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass http://localhost:4001/;
proxy_redirect off;
}
# required for websocket
location /live {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
proxy_pass http://localhost:4001/live;
# raise the proxy timeout for the websocket
proxy_read_timeout 6000s;
}
}
Starting Phoenix server:
$ sudo docker run -p 4001:4000 --env-file .env collaborlist:v1
09:25:15.666 [info] Running CollaborlistWeb.Endpoint with cowboy 2.9.0 at :::4000 (http)
09:25:15.667 [info] Access CollaborlistWeb.Endpoint at http://0.0.0.0:4000
09:25:15.797 [warning] Description: 'Server authenticity is not verified since certificate path validation is not enabled'
Reason: 'The option {verify, verify_peer} and one of the options \'cacertfile\' or \'cacerts\' are required to enable this.'