I'm using zuul for routing traffic on my project and when I check Swagger file on one of my services I can see that context path is duplicated.
Here is my zuul config:
zuul:
routes:
myservice:
path: /myservice/**
url: http://<host>:<port>/
Then it doesn't work for zuul but myservice is running fine..
The question has been asked a while ago and you probably found the problem but maybe someone else lands on this page too so...
Your context path being duplicated might be due to the fact that you are not stripping the path with Zuul.
Your route is matched based on the path you specify but if your client services already pass this path when querying the downstream service (the one behind your api gateway) you will end up with:
host/myService/myService?queryParams
To resolve just set stripPrefix to true as such:
zuul:
stripPrefix: true
routes:
myservice:
path: /myservice/**
url: http://<host>:<port>/
Hope this helps.
Related
I'm attempting to run Apache in Docker, behind a Traefik reverse proxy for https. Everything works, except that when I access a folder URL without a trailing slash, Apache redirects me to non-https (i.e. https://www.example.com/folder -> http://www.example.com/folder/). This is caused Apache mod_dir DirectorySlash, as described here & here. The solution is to use a rewrite rule, which kicks in before DirectorySlash, like this:
# Redirect to HTTPS before Apache mod_dir DirectorySlash redirect to HTTP
RewriteCond %{HTTP:X-Forwarded-Proto} =https
RewriteCond %{LA-U:REQUEST_FILENAME} -d
RewriteRule ^/(.*[^/])$ https://%{HTTP_HOST}/$1/ [R=301,L,QSA]
However, the issue is Traefik seems not to be setting the X-Forwarded-* headers. Here's a screenshot of the headers I'm getting:
Here are the labels I'm using in my Apache docker-compose file:
labels:
- traefik.enable=true
- traefik.port=80
- traefik.frontend.rule=PathPrefix:/web #Apache is accessible under https://example.com/web/
I've tried various combinations of labels, but no matter what I do, the x-forwarded-* headers always seem to be missing. For example (ref, ref):
- "traefik.frontend.headers.SSLProxyHeaders=X-Forwarded-Proto:https"
- "traefik.frontend.headers.SSLRedirect=true"
I've even tried just getting Traefik to add my own custom headers and can't get those to show up (ref):
- "traefik.https.middlewares.testHeader.Headers.CustomRequestHeaders.X-Script-Name=test"
...However, just to convince myself that I'm not crazy & this is actually running behind Traefik, & Traefik can add headers that I can see, this does work & cause the X-Frame-Options header to appear in Firefox:
- traefik.frontend.headers.frameDeny=true
So in summary, the question is: why isn't Traefik setting the x-forwarded-* headers (which I can then use in my Apache RewriteRules) - and how can I get it to do so?
For anyone who finds this & is wondering, my issue was twofold:
1) X-Forwarded-* headers are not viewable in the browser. You can see them on the server with i.e. phpinfo(), or by dumping the $_SERVER variable:
2) The reason the redirects weren't working (to fix the DirectorySlash issue) is because in addition to the RewriteRules listed above, your htaccess must include RewriteOptions AllowNoSlash. From the Apache documentation:
By default, mod_rewrite will ignore URLs that map to a directory on disk but lack a trailing slash, in the expectation that the mod_dir module will issue the client with a redirect to the canonical URL with a trailing slash. [...] the AllowNoSlash option can be enabled to ensure that rewrite rules are no longer ignored. This option makes it possible to apply rewrite rules within .htaccess files that match the directory without a trailing slash, if so desired.
Have you tried
traefik.frontend.passHostHeader: true
If it's possible, I'd recommend to let the http to https redirection to be sorted by traefik:
[entryPoints]
[entryPoints.http]
address = ":80"
[entryPoints.http.redirect]
entryPoint = "https"
[entryPoints.https]
address = ":443"
[entryPoints.https.tls]
I have my service worker installed on a staging directory
Main Website is on: https:example.com
Staging is on: https:example.com/test/
Service Worker path: https:example.com/test/serviceworker.js
This is how I register service worker:
navigator.serviceWorker.register('https:example.com/test/serviceworker.js', {scope: '/test/'})
.then(registration => {
console.log(`Service Worker registered! Scope: ${registration.scope}`);
})
Service worker works just fine, and is installed.
My concern is that inside serviceworker.js I want to use the / to point to the path of the current directory automatically, which is in this case: /staging/
For example when I want to cache the homepage in my staging site
/**
* Cache the homepage.
*/
workbox.routing.registerRoute('/', workbox.strategies.staleWhileRevalidate();
Here its caching https:example.com not https:example.com/test/
I know I can simply change registerRoute('/') to registerRoute('/staging/)'
But that is not efficient, and will make me need to have different version of the serviceworker for localhost, staging, and deployment.
I want to know what's the right way to do it here, so I can set the scope '/' to the current directory that the serviceworker.js is in.
Thank you.
Ok I think I figured how to do it the right way.
How to point to current directory: simply './' Instead of '/'
/**
* Cache the homepage.
*/
workbox.routing.registerRoute('./', workbox.strategies.staleWhileRevalidate();
How to cache files and images in current path: './image/' instead of '/image/'
const urlsToCache = [
'./image/fallback.png',
'./offline/'
];
Now the same file works the same locally and on staging.
This is such a newbie mistake, I need to be more clever :)
Edit:
I found this in Google documentation (The Service Worker Lifecycle):
The default scope of a service worker registration is ./ relative to
the script URL. This means if you register a service worker at
//example.com/foo/bar.js it has a default scope of //example.com/foo/.
in your case
you will need a flag to wether decide in the service worker registration if it's staging or production.
having the staging on a sub path of your production domain is not optimal at all.
I'm have following (abstract) project structure:
src/brands
src/admin
src/home
Brands & admin are a pure vue project, home is a nuxt project. I'm trying to get the brands & admin project to run on their own subdomain (brands.website.com & admin.website.com, respectively), and home on the main domain. The deploy to production/staging happens via docker (with an nginx image), and I was thinking to just copy a nginx config file from my project to the docker image to point the files in the dist folder to the correct html file (not sure how yet, I need to research that first).
For development, I used vue.config.js (since I'm using v3 of the vue cli) and I have setup the following:
index: {
entry: 'src/index/main.js',
filename: 'index.html',
},
brands: {
entry: 'src/brands/main.js',
filename: 'brands/index.html',
},
admin: {
entry: 'src/admin/main.js',
filename: 'admin/index.html',
},
I can reach the brands module via localhost:8080/brands, admin module via localhost:8080/admin and the homepage via localhost:8080, but the problem is that on my index page I'm gonna have a route that is /brands, so that would probably overwrite the brands module route with the page from nuxt (or vice versa). Now is my question if there is a better way of doing this (for example to enable subdomains in vue / localhost) and if not, is the way I'm wanting to copy the nginx config to my docker image a good practice? Or not?
Thanks in advance!
I have a similar project architecture. I have a single repo with multiple vue/nuxt projects. Each of my projects is its own npm/webpack project and is accessed by subdomain when developing locally.
Based on your example, this is how I would setup the projects.
Modify your hosts file:
127.0.0.1 website.localhost brands.website.localhost admin.website.localhost
Using localhost as the TLD was my personal decision, feel free to name the domains anyway you like.
Configure webpack dev server to serve each project at the corresponding subdomain + port.
src/brands: https://brands.website.localhost:8080
src/admin: https://admin.website.localhost:8081
src/home: https://website.localhost:8082
Whats nice about this configuration is that your dev URLs match your production URLs. https://brands.website.localhost:8080 -> https://brands.website.com
Each project will have complete control over the domain's subpaths and won't clobber other project's routes, which you alluded to with the /brands route.
I would like to redirect invalid URL to a 404 error with traefik and Docker
Example :
https://sub1.domain.com is a valid doamin referenced in traefik, so nothing happen
https://invalid.domain.com doesn't exist in Traefik configuration, so it will redirect to https://error.domain.com
I have searched in the official documentation and the only thing I found was about redirection , but I don't know how to use them to do my purpose.
You should be able to do this by specifying a redirect and a replacement. You'll also need to make sure that the Host rule matches any subdomains. Here's a config for docker-compose:
services:
traefik:
# ...existing config
sub1:
# ...existing config
error:
# ...existing config
labels:
# Match all subdomains
- traefik.frontend.rule=HostRegexp:{subdomain:[a-z]+}.domain.com
- traefik.frontend.redirect.regex=^https?://(.*).domain.com
- traefik.frontend.redirect.replacement=https://error.domain.com
# Set priority to low number so matches after other rules
- traefik.frontend.priority=1
It's even easier if you don't mind about the domain changing but instead just want to show an error as you don't need the traefik.frontend.redirect labels
I have successfully deployed my Rails app to the Google App Engine (my domain is also hosted by Google), and now I would like to redirect anyone going to my http:// address to my https:// address.
I have found the documentation to do so for a Python app here using the handlers element in the app.yaml file, and have attempted to replicate it in my own.
My app.yaml file now contains this:
handlers:
- url: /.*
script: config/application.rb
secure: always
redirect_http_response_code: 301
However I can still visit http:// without being redirected, and I think that it's because of the script: config/application.rb option that I've passed. I have no idea which file I should use or what that file should contain in a Rails app. Deployment breaks if I do not pass the script option.
Let me know if you need any more info, and thanks in advance for your help!
Well you can enforce SSL through your app's config/environments/production.rb file, you just need to add one line:
Rails.application.configure do
# Other code...
config.force_ssl = true # add this line to force HTTPS on production
end
This will do 3 things for your application, actually:
TLS redirect
Secure cookies: Sets the secure flag on cookies
HTTP Strict Transport Security (HSTS)
Read more about your application's configuration at http://guides.rubyonrails.org/configuring.html