[GH-ISSUE #2983] No styles on VW or admin page for subfolder using Nginx Proxy Manager #1433

Closed
opened 2026-03-03 02:09:10 +03:00 by kerem · 8 comments
Owner

Originally created by @bitsandbooks on GitHub (Dec 13, 2022).
Original GitHub issue: https://github.com/dani-garcia/vaultwarden/issues/2983

Subject of the issue

I'm running the latest (1.23.1, as of this post) version of VW inside a Docker container, and then routing it to the web using Nginx Proxy Manager. Vaultwarden should be accessible at https://subdomain.domain.tld/vw/. I can get to the URL and get "Bitwarden" in return, and I can get to the /admin page, but both are completely unstyled, and JavaScripts do not load. Even though the documentation mentions the importance of setting the DOMAIN variable, I'm still getting 404 errors on all static assets.

Deployment environment

  • vaultwarden version: 1.23.1
  • Install method: Docker
  • Clients used: web vault (attempting first-time setup)
  • Reverse proxy and version: Nginx Proxy Manager, version 2.9.19
  • MySQL/MariaDB or PostgreSQL version: N/A (SQLite only to start)

Here's my Docker Compose file for the container:

---
version: "3.3"

services:
  vaultwarden:
    image: "vaultwarden/server:latest"
    container_name: "vaultwarden"
    hostname: "myservername"
    user: "3000:3000"
    environment:
      WEBSOCKET_ENABLED: "true" # Enable WebSocket notifications.
      LOG_FILE: "/data/bitwarden.log"
      INVITATIONS_ALLOWED: "false"
      SIGNUPS_ALLOWED: "true"
      SHOW_PASSWORD_HINT: "false"
      DOMAIN: "https://subdomain.domain.tld/vw/"
      ADMIN_TOKEN: "myadmintoken"
    volumes:
      - "/path/to/vaultwarden/data:/data"

Nginx Proxy Manager (which is managing HTTPS certificates) has a Proxy Host and SSL cert set up for subdomain.domain.tld. The Proxy Host is set up with these options:

  • Serve a simple, unrelated placeholder (static HTML) file to visitors of https://subdomain.domain.tld/.
  • Cache Assets
  • Block Common Exploits
  • WebSockets support
  • Force SSL
  • HTTP/2 Support
  • HSTS Enabled
  • HSTS Subdomains

Under the site's Advanced tab, I have the following:

location /vw/ {
    proxy_http_version 1.1;
    proxy_set_header "Connection" "";
    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_pass http://vw_container:80;
}
location /vw/notifications/hub/negotiate {
    proxy_http_version 1.1;
    proxy_set_header "Connection" "";
    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_pass http://vw_container:80;
}
location /vw/notifications/hub {
    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 Forwarded $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://vw_container:3012;
}

Expected behaviour

I expect to be able to visit https://subdomain.domain.tld/vw/ and get page that loads static assets (e.g., images and scripts).

Actual behaviour

I get an unstyled site with no Javascript capabilities, and 404 errors on all static assets.

Troubleshooting data

VW Docker logs:

/--------------------------------------------------------------------\
|                        Starting Vaultwarden                        |
|                           Version 1.23.1                           |
|--------------------------------------------------------------------|
| This is an *unofficial* Bitwarden implementation, DO NOT use the   |
| official channels to report bugs/features, regardless of client.   |
| Send usage/configuration questions or feature requests to:         |
|   https://vaultwarden.discourse.group/                             |
| Report suspected bugs/issues in the software itself at:            |
|   https://github.com/dani-garcia/vaultwarden/issues/new            |
\--------------------------------------------------------------------/

[INFO] No .env file found.

[2022-12-13 23:56:27.476][start][INFO] Rocket has launched from http://0.0.0.0:80
[2022-12-13 23:56:27.476][parity_ws][INFO] Listening for new connections on 0.0.0.0:3012.
[2022-12-13 23:56:30.539][request][INFO] GET /vw/admin
[2022-12-13 23:56:30.539][response][INFO] GET /vw/admin [2] (admin_login) => 200 OK

And here are the Errors and Warnings from Firefox's Inspector:

GET https://subdomain.domain.tld/vw/theme_head.8e5494e39b48bad5e654.js
[HTTP/2 404 Not Found 50ms]

GET https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.css
[HTTP/2 404 Not Found 49ms]

GET https://subdomain.domain.tld/vw/app/polyfills.8e5494e39b48bad5e654.js
[HTTP/2 404 Not Found 48ms]

GET https://subdomain.domain.tld/vw/app/vendor.8e5494e39b48bad5e654.js
[HTTP/2 404 Not Found 52ms]

GET https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.js
[HTTP/2 404 Not Found 49ms]

Loading failed for the <script> with source “https://subdomain.domain.tld/vw/theme_head.8e5494e39b48bad5e654.js”. vw:1:1
GET https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.css
[HTTP/2 404 Not Found 45ms]

GET https://subdomain.domain.tld/vw/app/polyfills.8e5494e39b48bad5e654.js
[HTTP/2 404 Not Found 41ms]

Loading failed for the <script> with source “https://subdomain.domain.tld/vw/app/polyfills.8e5494e39b48bad5e654.js”. vw:1:1
GET https://subdomain.domain.tld/vw/app/vendor.8e5494e39b48bad5e654.js
[HTTP/2 404 Not Found 49ms]

Loading failed for the <script> with source “https://subdomain.domain.tld/vw/app/vendor.8e5494e39b48bad5e654.js”. vw:1:1
GET https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.js
[HTTP/2 404 Not Found 43ms]

Loading failed for the <script> with source “https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.js”. vw:1:1
GET https://subdomain.domain.tld/vw/images/icons/apple-touch-icon.png
[HTTP/2 404 Not Found 0ms]

GET https://subdomain.domain.tld/vw/images/icons/favicon-32x32.png
[HTTP/2 404 Not Found 0ms]

The Nginx error logs contain several entries like this. The "upstream" IP is the IP of the Docker container, so it's pointing to the right place... but notice that it's trying to use HTTPS protocol on port 80. Why?

2022/12/13 21:58:02 [error] 670#670: *280 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 33.122.78.96, server: subdomain.domain.tld, request: "GET /vw/ADMIN HTTP/2.0", upstream: "https://192.168.56.24:80/vw/ADMIN", host: "subdomain.domain.tld"
2022/12/13 21:58:06 [error] 670#670: *280 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 33.122.78.96, server: subdomain.domain.tld, request: "GET /vw/ADMIN HTTP/2.0", upstream: "https://192.168.56.24:80/vw/ADMIN", host: "subdomain.domain.tld"
2022/12/13 21:58:10 [error] 670#670: *280 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 33.122.78.96, server: subdomain.domain.tld, request: "GET /vw/admin HTTP/2.0", upstream: "https://192.168.56.24:80/vw/admin", host: "subdomain.domain.tld"
Originally created by @bitsandbooks on GitHub (Dec 13, 2022). Original GitHub issue: https://github.com/dani-garcia/vaultwarden/issues/2983 ### Subject of the issue I'm running the latest (1.23.1, as of this post) version of VW inside a Docker container, and then routing it to the web using Nginx Proxy Manager. Vaultwarden should be accessible at **https://subdomain.domain.tld/vw/**. I can get to the URL and get "Bitwarden" in return, and I can get to the `/admin` page, but both are completely unstyled, and JavaScripts do not load. Even though the documentation mentions the importance of [setting the DOMAIN variable](https://github.com/dani-garcia/vaultwarden/wiki/Configuration-overview#setting-the-domain-url), I'm still getting 404 errors on all static assets. ### Deployment environment * vaultwarden version: 1.23.1 * Install method: Docker * Clients used: web vault (attempting first-time setup) * Reverse proxy and version: Nginx Proxy Manager, version 2.9.19 * MySQL/MariaDB or PostgreSQL version: N/A (SQLite only to start) Here's my Docker Compose file for the container: --- version: "3.3" services: vaultwarden: image: "vaultwarden/server:latest" container_name: "vaultwarden" hostname: "myservername" user: "3000:3000" environment: WEBSOCKET_ENABLED: "true" # Enable WebSocket notifications. LOG_FILE: "/data/bitwarden.log" INVITATIONS_ALLOWED: "false" SIGNUPS_ALLOWED: "true" SHOW_PASSWORD_HINT: "false" DOMAIN: "https://subdomain.domain.tld/vw/" ADMIN_TOKEN: "myadmintoken" volumes: - "/path/to/vaultwarden/data:/data" Nginx Proxy Manager (which is managing HTTPS certificates) has a Proxy Host and SSL cert set up for **subdomain.domain.tld**. The Proxy Host is set up with these options: * Serve a simple, unrelated placeholder (static HTML) file to visitors of **https://subdomain.domain.tld/**. * ✅ Cache Assets * ✅ Block Common Exploits * ✅ WebSockets support * ✅ Force SSL * ✅ HTTP/2 Support * ✅ HSTS Enabled * ❌ HSTS Subdomains Under the site's Advanced tab, I have the following: location /vw/ { proxy_http_version 1.1; proxy_set_header "Connection" ""; 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_pass http://vw_container:80; } location /vw/notifications/hub/negotiate { proxy_http_version 1.1; proxy_set_header "Connection" ""; 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_pass http://vw_container:80; } location /vw/notifications/hub { 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 Forwarded $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://vw_container:3012; } ### Expected behaviour I expect to be able to visit https://subdomain.domain.tld/vw/ and get page that loads static assets (e.g., images and scripts). ### Actual behaviour I get an unstyled site with no Javascript capabilities, and 404 errors on all static assets. ### Troubleshooting data VW Docker logs: /--------------------------------------------------------------------\ | Starting Vaultwarden | | Version 1.23.1 | |--------------------------------------------------------------------| | This is an *unofficial* Bitwarden implementation, DO NOT use the | | official channels to report bugs/features, regardless of client. | | Send usage/configuration questions or feature requests to: | | https://vaultwarden.discourse.group/ | | Report suspected bugs/issues in the software itself at: | | https://github.com/dani-garcia/vaultwarden/issues/new | \--------------------------------------------------------------------/ [INFO] No .env file found. [2022-12-13 23:56:27.476][start][INFO] Rocket has launched from http://0.0.0.0:80 [2022-12-13 23:56:27.476][parity_ws][INFO] Listening for new connections on 0.0.0.0:3012. [2022-12-13 23:56:30.539][request][INFO] GET /vw/admin [2022-12-13 23:56:30.539][response][INFO] GET /vw/admin [2] (admin_login) => 200 OK And here are the Errors and Warnings from Firefox's Inspector: GET https://subdomain.domain.tld/vw/theme_head.8e5494e39b48bad5e654.js [HTTP/2 404 Not Found 50ms] GET https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.css [HTTP/2 404 Not Found 49ms] GET https://subdomain.domain.tld/vw/app/polyfills.8e5494e39b48bad5e654.js [HTTP/2 404 Not Found 48ms] GET https://subdomain.domain.tld/vw/app/vendor.8e5494e39b48bad5e654.js [HTTP/2 404 Not Found 52ms] GET https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.js [HTTP/2 404 Not Found 49ms] Loading failed for the <script> with source “https://subdomain.domain.tld/vw/theme_head.8e5494e39b48bad5e654.js”. vw:1:1 GET https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.css [HTTP/2 404 Not Found 45ms] GET https://subdomain.domain.tld/vw/app/polyfills.8e5494e39b48bad5e654.js [HTTP/2 404 Not Found 41ms] Loading failed for the <script> with source “https://subdomain.domain.tld/vw/app/polyfills.8e5494e39b48bad5e654.js”. vw:1:1 GET https://subdomain.domain.tld/vw/app/vendor.8e5494e39b48bad5e654.js [HTTP/2 404 Not Found 49ms] Loading failed for the <script> with source “https://subdomain.domain.tld/vw/app/vendor.8e5494e39b48bad5e654.js”. vw:1:1 GET https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.js [HTTP/2 404 Not Found 43ms] Loading failed for the <script> with source “https://subdomain.domain.tld/vw/app/main.8e5494e39b48bad5e654.js”. vw:1:1 GET https://subdomain.domain.tld/vw/images/icons/apple-touch-icon.png [HTTP/2 404 Not Found 0ms] GET https://subdomain.domain.tld/vw/images/icons/favicon-32x32.png [HTTP/2 404 Not Found 0ms] The Nginx error logs contain several entries like this. The "upstream" IP is the IP of the Docker container, so it's pointing to the right place... but notice that it's trying to use HTTPS protocol on port 80. Why? 2022/12/13 21:58:02 [error] 670#670: *280 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 33.122.78.96, server: subdomain.domain.tld, request: "GET /vw/ADMIN HTTP/2.0", upstream: "https://192.168.56.24:80/vw/ADMIN", host: "subdomain.domain.tld" 2022/12/13 21:58:06 [error] 670#670: *280 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 33.122.78.96, server: subdomain.domain.tld, request: "GET /vw/ADMIN HTTP/2.0", upstream: "https://192.168.56.24:80/vw/ADMIN", host: "subdomain.domain.tld" 2022/12/13 21:58:10 [error] 670#670: *280 peer closed connection in SSL handshake while SSL handshaking to upstream, client: 33.122.78.96, server: subdomain.domain.tld, request: "GET /vw/admin HTTP/2.0", upstream: "https://192.168.56.24:80/vw/admin", host: "subdomain.domain.tld"
kerem closed this issue 2026-03-03 02:09:10 +03:00
Author
Owner

@BlackDex commented on GitHub (Dec 13, 2022):

What does the nginx, Vaultwarden and browser logs tell you?

<!-- gh-comment-id:1350082336 --> @BlackDex commented on GitHub (Dec 13, 2022): What does the nginx, Vaultwarden and browser logs tell you?
Author
Owner

@BlackDex commented on GitHub (Dec 13, 2022):

Also, your nginx config is wrong, since one part is using /vw and the others /vault, that will not work, but in theory should but break the interface.

<!-- gh-comment-id:1350097106 --> @BlackDex commented on GitHub (Dec 13, 2022): Also, your nginx config is wrong, since one part is using `/vw` and the others `/vault`, that will not work, but in theory should but break the interface.
Author
Owner

@bitsandbooks commented on GitHub (Dec 13, 2022):

Also, your nginx config is wrong, since one part is using /vw and the others /vault, that will not work, but in theory should but break the interface.

Sorry, that's a victim of my poor anonymizing efforts. Comment updated: results same so far.

<!-- gh-comment-id:1350102890 --> @bitsandbooks commented on GitHub (Dec 13, 2022): > Also, your nginx config is wrong, since one part is using `/vw` and the others `/vault`, that will not work, but in theory should but break the interface. Sorry, that's a victim of my poor anonymizing efforts. Comment updated: results same so far.
Author
Owner

@BlackDex commented on GitHub (Dec 13, 2022):

Also, your nginx config is wrong, since one part is using /vw and the others /vault, that will not work, but in theory should but break the interface.

Sorry, that's a victim of my poor anonymizing efforts. Comment updated: results same so far.

Still need some logs. Either/or Vaultwarden, nginx, browser (F12)

<!-- gh-comment-id:1350106889 --> @BlackDex commented on GitHub (Dec 13, 2022): > > Also, your nginx config is wrong, since one part is using `/vw` and the others `/vault`, that will not work, but in theory should but break the interface. > > Sorry, that's a victim of my poor anonymizing efforts. Comment updated: results same so far. Still need some logs. Either/or Vaultwarden, nginx, browser (F12)
Author
Owner

@bitsandbooks commented on GitHub (Dec 14, 2022):

OK, I've added the browser logs, and the VW logs, and some Nginx log entries that look relevant. It's looking for the upstream, and sees it for the content, but not the assets. What am I missing? Do I need to get VW to accept the NPM certs somehow?

<!-- gh-comment-id:1350428371 --> @bitsandbooks commented on GitHub (Dec 14, 2022): OK, I've added the browser logs, and the VW logs, and some Nginx log entries that look relevant. It's looking for the upstream, and sees it for the content, but not the assets. What am I missing? Do I need to get VW to accept the NPM certs somehow?
Author
Owner

@BlackDex commented on GitHub (Dec 14, 2022):

I would start by using a more recent version. You are using 1.23.1 which isn't the latest version. That should be 1.26.0 at the moment.

That also makes me wonder if all the compose settings are fully passed on. Try the following.

docker-compose pull
docker-compose up -d

And check again.

<!-- gh-comment-id:1350471664 --> @BlackDex commented on GitHub (Dec 14, 2022): I would start by using a more recent version. You are using `1.23.1` which isn't the latest version. That should be `1.26.0` at the moment. That also makes me wonder if all the compose settings are fully passed on. Try the following. ```bash docker-compose pull docker-compose up -d ``` And check again.
Author
Owner

@stefan0xC commented on GitHub (Dec 14, 2022):

The Nginx error logs contain several entries like this. The "upstream" IP is the IP of the Docker container, so it's pointing to the right place... but notice that it's trying to use HTTPS protocol on port 80. Why?

You probably have set the scheme of the proxy host to https somewhere. As for the why it seems that because of the Cache Assets option this assets.conf will get included which includes this proxy.conf so the settings for your proxy host $forward_scheme://$server:$port are probably incorrect.

<!-- gh-comment-id:1350650429 --> @stefan0xC commented on GitHub (Dec 14, 2022): > The Nginx error logs contain several entries like this. The "upstream" IP is the IP of the Docker container, so it's pointing to the right place... but notice that it's trying to use HTTPS protocol on port 80. Why? You probably have set the scheme of the proxy host to https somewhere. As for the why it seems that because of the `Cache Assets` option this [assets.conf](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/develop/docker/rootfs/etc/nginx/conf.d/include/assets.conf) will get included which includes this [proxy.conf](https://github.com/NginxProxyManager/nginx-proxy-manager/blob/develop/docker/rootfs/etc/nginx/conf.d/include/proxy.conf) so the settings for your proxy host `$forward_scheme://$server:$port` are probably incorrect.
Author
Owner

@BlackDex commented on GitHub (Dec 14, 2022):

I Also just tested it, and it works just fine using the example from the wiki for nginx.

<!-- gh-comment-id:1350770846 --> @BlackDex commented on GitHub (Dec 14, 2022): I Also just tested it, and it works just fine using the example from the wiki for nginx.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vaultwarden#1433
No description provided.