Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

url_prefix changed behaviour with 4.2.2 #1523

Closed
lukebelliott opened this issue Oct 16, 2019 · 25 comments · Fixed by #2122
Closed

url_prefix changed behaviour with 4.2.2 #1523

lukebelliott opened this issue Oct 16, 2019 · 25 comments · Fixed by #2122

Comments

@lukebelliott
Copy link

I had Verdaccio 4.2.1 running behind an apache proxy working well and just tried upgrading to latest and it's no longer working. Tracked the change in behaviour to 4.2.2.

I have the prefix configured in verdaccio's config:

url_prefix: /npm/

Apache proxy config:

<Location /npm/>
    ProxyPass https://127.0.0.1:4873/ nocanon
    ProxyPassReverse https://127.0.0.1:4873/
    ProxyPreserveHost On
</Location>

With 4.2.1, this is working perfectly. Here's a diff of the initial GET response from 4.2.1 and 4.2.2 out of Verdaccio itself (not apache):

--- good.4.2.1.txt      2019-10-16 15:20:18.931210851 +0100
+++ bad-4.2.2.txt       2019-10-16 15:19:44.480775891 +0100
@@ -15,12 +15,12 @@
         window.VERDACCIO_SCOPE = '';
         window.VERDACCIO_LOGO = '';
         window.VERDACCIO_PRIMARY_COLOR = '';
-        window.VERDACCIO_VERSION = '4.2.1';
+        window.VERDACCIO_VERSION = '4.2.2';
     </script>
-<link rel="shortcut icon" href="http://ukserver.activfinancial.com/npm/-/static/favicon.ico"><link href="http://ukserver.activfinancial.com/npm/-/static/0.style.026be7a5bc0c57143eb2.css" rel="stylesheet"><link href="http://ukserver.activfinancial.com/npm/-/static/2.style.92647ec0a7beb8b2898d.css" rel="stylesheet"></head>
+<link rel="shortcut icon" href="/-/static/favicon.ico"><link href="/-/static/0.style.2ea8a5d1276179958242.css" rel="stylesheet"><link href="/-/static/2.style.92647ec0a7beb8b2898d.css" rel="stylesheet"></head>
 
 <body class="body">
     <div id="root"></div>
-<script type="text/javascript" src="http://ukserver.activfinancial.com/npm/-/static/manifest.36047715e70284b71dcd.js"></script><script type="text/javascript" src="http://ukserver.activfinancial.com/npm/-/static/vendors.36047715e70284b71dcd.js"></script><script type="text/javascript" src="http://ukserver.activfinancial.com/npm/-/static/main.36047715e70284b71dcd.js"></script></body>
+<script type="text/javascript" src="/-/static/manifest.64e04f9f5e62cc8e0fd4.js"></script><script type="text/javascript" src="/-/static/vendors.64e04f9f5e62cc8e0fd4.js"></script><script type="text/javascript" src="/-/static/main.64e04f9f5e62cc8e0fd4.js"></script></body>
 
 </html>

As you can see, scripted sources are relative in 4.2.2. I can't see anything in the changelog that would indicate a config change is required or what else might have caused this (maybe it should never have worked like I have it configured?).

A quick diff of the 4.2.1 and 4.2.2 tags shows few changes to verdaccio so I guess it's one of the dependencies, but I've no idea where ...

There are a few other issues referencing url_prefix, but they seem to predate 4.2.2 so presumably aren't related. Apologies if this is just noise, but I am a bit stumped...

Regards

@juanpicado
Copy link
Member

juanpicado commented Oct 17, 2019

@lukebelliott I was testing https://github.com/verdaccio/docker-examples/tree/master/reverse_proxy/nginx with all v4 versions, no difference at all. Unfortunately I have no apache example for relative paths, only a normal setup from root. If you are able to reproduce it with any example in that repo let me know.

I 4.2.2 we fixed https://github.com/verdaccio/ui/issues/108 and still works in our examples, I'd double check https://verdaccio.org/docs/en/reverse-proxy see whether you comply with all required fields.

@lukebelliott
Copy link
Author

lukebelliott commented Oct 18, 2019

I tried to get the reverse_proxy/nginx/relative_path example working, but it fails with fatal--- cannot open config file /verdaccio/conf/config.yaml so I guess I'm missing something, just not sure what. Sadly I'm not a docker person but If anyone could give me a pointer I'd be grateful and happy to try again.

Instead I tried a nginx setup on my server using:

        location ~ ^/npm/(.*)$ {
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $host:$server_port;
            proxy_set_header X-NginX-Proxy true;
            proxy_pass http://127.0.0.1:4873/$1;
            proxy_redirect off;

#           proxy_pass http://127.0.0.1:4873/$1;
#           proxy_set_header Host            $host:$server_port;
#           proxy_set_header X-Forwarded-For $remote_addr;
#           proxy_set_header X-Forwarded-Proto $scheme;
        }

And it fails the same way as apache for me (with either version). That initial GET from verdaccio has, for example:

<link rel="shortcut icon" href="/-/static/favicon.ico"><link href="/-/static/0.style.2ea8a5d1276179958242.css" rel="stylesheet"><link href="/-/static/2.style.92647ec0a7beb8b2898d.css" rel="stylesheet"></head>

which unless the proxy is going to start rewriting bodies surely can't work?

Looking at the nginx config in the repo, isn't it serving from both / and /verdaccio? So the non-prefixed hrefs in the initial GET response will still work?

If I add in / to my nginx setup:

        location / {
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              proxy_set_header Host $host:$server_port;
              proxy_set_header X-NginX-Proxy true;
              proxy_pass http://127.0.0.1:4873;
              proxy_redirect off;
        }

to look like the example in the repo, then it does indeed work, but everything is served off /.

Like I say, happy to try with the docker example if someone could let me know what I'm missing!

Thanks

@juanpicado
Copy link
Member

I'm not super expert in Apache unfortunately, but please provide a repo with examples of your configuration, so anyone can try to reproduce it. Let's see wether someone with Apache skills can help here.

@lukebelliott
Copy link
Author

Sorry if it wasn't clear from my previous message, I don't think it's anything to do with apache as I get the exact same behaviour with nginx on my server.

Also, since then, I managed to get docker-examples/reverse_proxy/nginx/relative_path running, and that shows the issue too if the location / section is removed.

With the default config from the example (location / still there), then you can see a bunch of requests don't have the url_prefix. Here's a quick summary of the URLs (as seen from the browser in this case):

... and so on ...

Regards

@chrisbertrandsagecom
Copy link

chrisbertrandsagecom commented Oct 22, 2019

I am experiencing the exact same problem. Only the favicon is correctly retrieved from the url_prefix. Everything else is served from root, which is not where the files reside.
The favicon in the template uses: htmlWebpackPlugin.options.verdaccioURL to retreive the correct URL for the config.

image

I think it may be the rootURL in the env.js. https://github.com/verdaccio/ui/blob/master/config/env.js

The API is still working correctly and a comparison of the two shows they resolve this path differently. This looks to have changed in the UI here: verdaccio/ui@6b5d0b7#diff-8cc96276187f94a8094f05846514a3a7

@krrishh-org
Copy link

I am also experiencing the same issue here. We have an internal reverse proxy similar to nginx. The static files are not getting resolved as they were in 4.2.1

@chrisbertrandsagecom
Copy link

A workaround for those that are using Nginx, and have this problem.

Amend your config to rewrite those paths back in, there were some additional changes that were needed.

proxy_set_header Accept-Encoding "";
proxy_set_header X-NginX-Proxy 
sub_filter '/-/static/' '/npm/-/static/';
sub_filter_types text/html text/css;
sub_filter_once off;

@krrishh-org
Copy link

Ok. For now I have rebuilt the ui with this change reverted and replaced it in the verdaccio installation. It is working fine for now. Need a permanent fix for this.

@a666
Copy link

a666 commented Nov 21, 2019

We also just updated, and fell on this issue. We did the same than @chrisbertrandsagecom.

Also this issue also requires the nginx tag.

@d42ohpaz
Copy link

d42ohpaz commented Dec 10, 2019

I'm having the same problem. Brand new install today. Looking at the webpack.config.js in the ui repo, it looks like it might be because of the publicPath: '/-/static',, which looks to be related to removing the ToReplaceByVerdaccio as denoted by this comment.

This would mean it's not a web server configuration problem. It's a code problem. I'm going to take others' advice and downgrade to 4.2.1 until this gets fixed. ✌️

Edit: FWIW, here is verdaccio -i

Environment Info:

  System:
    OS: Linux 3.10 Red Hat Enterprise Linux Server 7.7 (Maipo)
    CPU: (2) x64 Intel(R) Xeon(R) CPU E5-2670 v3 @ 2.30GHz
  Binaries:
    Node: 8.16.1 - /bin/node
    Yarn: 1.21.0 - /bin/yarn
    npm: 6.4.1 - /bin/npm
Server version: Apache/2.4.6 (Red Hat Enterprise Linux)
Server built:   Jun  9 2019 13:01:04
Server's Module Magic Number: 20120211:24
Server loaded:  APR 1.4.8, APR-UTIL 1.5.2
Compiled using: APR 1.4.8, APR-UTIL 1.5.2
Architecture:   64-bit
Server MPM:     worker
  threaded:     yes (fixed thread count)
    forked:     yes (variable process count)
Server compiled with....
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=256
 -D HTTPD_ROOT="/etc/httpd"
 -D SUEXEC_BIN="/usr/sbin/suexec"
 -D DEFAULT_PIDLOG="/run/httpd/httpd.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="conf/mime.types"
 -D SERVER_CONFIG_FILE="conf/httpd.conf"
storage: /var/lib/verdaccio/storage
plugins: /var/lib/verdaccio/plugins

web:
  gravatar: true
  logo: /var/lib/verdaccio/logo.png
  title: Verdaccio

url_prefix: /npm/
http_proxy: https://my.url.internal/
https_proxy: https://my.url.internal/

uplinks:
  npmjs:
    url: https://registry.npmjs.org/

auth:
  htpasswd:
    file: /var/lib/verdaccio/.htpasswd

packages:
  '@*/*':
    # scoped packages
    access: $all
    publish: $authenticated
    unpublish: $authenticated
    proxy: npmjs

  '**':
    # allow all users (including non-authenticated users) to read and
    # publish all packages
    #
    # you can specify usernames/groupnames (depending on your auth plugin)
    # and three keywords: "$all", "$anonymous", "$authenticated"
    access: $all

    # allow all known users to publish/publish packages
    # (anyone can register by default, remember?)
    publish: $authenticated
    unpublish: $authenticated

    # if package is not available locally, proxy requests to 'npmjs' registry
    proxy: npmjs

server:
  keepAliveTimeout: 60

middlewares:
  audit:
    enabled: true

# log settings
logs:
  - {type: file, path: /var/log/verdaccio/verdaccio.log, level: info}
<VirtualHost *:80>
    ServerName my.url.internal

    RequestHeader set Host "my.url.internal"

    DocumentRoot /var/www/html/web
    Alias "/github" "/var/www/html/callback.php"

    <Location /npm/>
        ProxyPreserveHost on
        ProxyPass http://127.0.0.1:4873/ nocanon
        ProxyPassReverse http://127.0.0.1:4873/
    </Location>

    AllowEncodedSlashes NoDecode

    <Directory /var/www/html/web>
        Options None
    </Directory>
</VirtualHost>

@nsainaney
Copy link

I can confirm this issue on Kubernetes as well (using Istio for reverse proxy).

@juanpicado
Copy link
Member

I can confirm this issue on Kubernetes as well (using Istio for reverse proxy).

I appreciate the feedback, but, I think each of you is having this issue, please, share your configuration, context, etc, otherwise would be hard to narrow down the issue. If it is the same as above, confirm it 🙏 also would be helpful for triage this. As much context, the better.

@taffarel-gaivota
Copy link

taffarel-gaivota commented Apr 27, 2020

@nsainaney you can fix this issue using Istio as reverse proxy forcing Istio to add the X-Forwarded-Proto and X-Forwarded-Port headers

Example

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: npm
spec:
  hosts:
    - 'npm.my-server.com'
  gateways:
    - istio-gateway
  http:
    - route:
      - destination:
          host: verdaccio
          port:
            number: 4873
      headers:
        request:
          set:
            X-Forwarded-Proto: "https"
            X-Forwarded-Port: "443"

@nsainaney
Copy link

Thanks @taffarel-gaivota. We opted to route based on verdaccio being its own host (verdaccio.xxx.example.com) and it's working fine now but we'll test the above and circle back with a config that can reliably reproduce the issue.

@taffarel-gaivota
Copy link

For those who are using Apache server you can do some as this

<Location /npm/>
        ProxyPreserveHost on
        ProxyPass http://127.0.0.1:4873/ nocanon
        ProxyPassReverse http://127.0.0.1:4873/
        RequestHeader   setIfEmpty      X-Forwarded-Proto    "https"
        RequestHeader   setIfEmpty      X-Forwarded-Port    "443"
    </Location>

and for Nginx you can do something like this:

location /some/path/ {
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto "https"
    proxy_set header X-Forwarded-Port 443
    proxy_pass http://localhost:8000;
}

@Vivapercuore
Copy link

confirm this issue on 4.6.2
html temple should add

@harty911
Copy link

harty911 commented Jun 15, 2020

With the default config from the example (location / still there), then you can see a bunch of requests don't have the url_prefix. Here's a quick summary of the URLs (as seen from the browser in this case):

... and so on ...

I can confirm the issue when loading the index.html page on my side too.
Looking at the code, this is a problem comming from index.hml template in @verdaccio/ui-theme package.

index.hml page template is loaded and modified according to this replace statement (were base is the root public url including url_prefix):

template.replace(/ToReplaceByVerdaccio/g, base)

But in ìndex.html` template there is:

...
<link rel="icon" type="image/png" href="ToReplaceByVerdaccio/-/static/favicon.ico" />
...
<link rel="shortcut icon" href="/-/static/favicon.ico">
<link href="/-/static/0.style.b3d2b69b057068c678ca.css" rel="stylesheet">
...
<script type="text/javascript" src="/-/static/manifest.23e9430e154f72ad4c9c.js"></script>
<script type="text/javascript" src="/-/static/vendors.23e9430e154f72ad4c9c.js"></script>
<script type="text/javascript" src="/-/static/main.23e9430e154f72ad4c9c.js"></script>
...

=> not all URL are prefixed with base

Replacing all "/-/static/..." by ToReplaceByVerdaccio/-/static/..." in template worked for me !

Is it possible to fix template ? (I don't know where is this repo)

@jsiedentop
Copy link

@harty911 explained the problem very acurate. The reason, why @juanpicado can't reproduce the problem is, that the example (https://github.com/verdaccio/docker-examples/tree/master/reverse_proxy/nginx) is serving an instance on http://localhost/ and http://localhost/verdaccio. So the broken links from the second instance are served from the first instance. As @harty911 already mentioned, a deeper look into the browser tools disclose the bug.

I think it would be a good idea to also fix the example to something like that:

Thanks for all your efford 👍

@bsh-ableton
Copy link

bsh-ableton commented Aug 29, 2020

It looks like this was introduced when the prefix was removed in verdaccio/ui#122.

So, to link in the relevant GitHub issues:

@juanpicado
Copy link
Member

juanpicado commented Mar 24, 2021

You can start to test the branch pulling this.

docker pull verdaccio/verdaccio:proxy_fix_1523

It will update automatically when new commits are pushed. No npm version ready yet.

On this version you can use the env variable VERDACCIO_PUBLIC_URL to define specific public URL instead relay on the host header, also will ignore url_prefix` #2129.

⚠️ Regarding VERDACCIO_PUBLIC_URL there is an open question whether should override url_prefix or just contain the domain + take in account the url_prefix. I'd love know your opinions.

The url_prefix does not require any changes in your side, verdacio will generate full public url instead rely on relative paths.

Screenshot from 2021-03-24 19-44-06

Furthermore, the UI does not contain CSS, svg and reduce to minimum the HTTP requests.

@juanpicado
Copy link
Member

FYI, fix for this is on verdaccio 5.

@juanpicado juanpicado modified the milestones: Next major, v6 release Nov 3, 2021
@juanpicado juanpicado modified the milestones: v6 release, Next major Aug 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.