deck9/input

Static Assets not fetched from APP_URL

Closed this issue · 6 comments

When self-hosting ghcr.io/deck9/input:main behind an nginx reverse proxy (port 443 forwarded to port 8080 in the container), static assets (.js and .css) are fetched from http://input:8080/build/app/assets/app-cd48a56c.js instead of https://$APP_URL/build/app/assets/app-cd48a56c.js.

Environment Variables:

DB_CONNECTION=mysql
DB_DATABASE=input
DB_HOST=[docker MariaDB service in same network]
DB_USERNAME=input_user
DB_PASSWORD=[password]
APP_URL=[domain]

@alexander-schoch-linuxdays sounds like APP_URL from your .env is not recognized correctly. Can you share your Docker run command with me?

Usually, the default for APP_URL is localhost:8080, since your assets URLs are using input:8080 something must have set APP_URL to that value.

@PhilReinking

I started the application as a service in docker swarm using the following command:

docker service create --replicas 1 --name input --network cluster --env DB_CONNECTION=mysql --env DB_DATABASE=input --env DB_HOST=mariadb --env DB_USERNAME=[username] --env DB_PASSWORD=[password] --env APP_URL=[domain] ghcr.io/deck9/input:main

The only thing that is actually set to "input" is the DB_DATABASE and the service name.

Also, maybe the reason is the nginx config:

server {
	server_name [domain];
	client_max_body_size 100M;
	location / {
		resolver 127.0.0.11 ipv6=off;
		proxy_pass http://input:8080;
	}

	listen [::]:443 ssl;
	listen 443 ssl;
	ssl_certificate /etc/letsencrypt/live/[domain]/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/[domain]/privkey.pem;
}

server {
	server_name [domain];

	listen 80;
  	listen [::]:80;

	client_max_body_size 100M;

	return 301 https://$host$request_uri;
}

Update on this issue:

The input from the wrong host comes from the docker service name and is set by nginx in the line proxy_pass http://input:8080. Setting proxy_set_header Host $host; , like below, resolves this.

server {
	server_name [domain];
	client_max_body_size 100M;
	location / {
		resolver 127.0.0.11 ipv6=off;
		proxy_pass http://input:8080;
                proxy_set_header Host $host;
	}

	listen [::]:443 ssl;
	listen 443 ssl;
	ssl_certificate /etc/letsencrypt/live/[domain]/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/[domain]/privkey.pem;
}

server {
	server_name [domain];

	listen 80;
  	listen [::]:80;

	client_max_body_size 100M;

	return 301 https://$host$request_uri;
}

However, there's a new problem now: Input tries to fetch all static files via http, but the browser blocks it due to origin policy when accessing input via https (it works with http though). I am still figuring out on how to fix this.

Alright, I got it to work. For anyone also having this problem, this is the nginx config that worked for me:

server {
	server_name [domain];
	location / {
		resolver 127.0.0.11 ipv6=off;
		proxy_pass http://[docker service name]:8080;
		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 Upgrade $http_upgrade;
		proxy_set_header Connection "upgrade";
	}

	listen [::]:443 ssl;
	listen 443 ssl;
	ssl_certificate /etc/letsencrypt/live/[domain]/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/[domain]/privkey.pem;
}

server {
	server_name [domain];

	listen 80;
  	listen [::]:80;

	return 301 https://$host$request_uri;
}

@alexander-schoch-linuxdays Thanks for debugging this. I will improve the docs about running Input behind a proxy.