Varnish stops waiting after 1 second - timeout

this problem is gonna make me crazy: my varnish istance stops waiting for a backend response after exactly 1 second.
Every first call to a page is a 503 Backend
Daemon is configured this way:
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-p thread_pool_add_delay=2 \
-p thread_pools=4 \
-p thread_pool_min=200 \
-p thread_pool_max=4000 \
-p timeout_linger=50 \
-p connect_timeout=300 \
-p first_byte_timeout=300 \
-p between_bytes_timeout=300 \
-p send_timeout=900 \
-s malloc,3G"
and the VCL backend:
backend default { # Define one backend
.host = "127.0.0.1"; # IP or Hostname of backend
.port = "8080"; # Port Apache or whatever is listening
.probe = {
.url = "/";
.timeout = 1s;
.interval = 1s;
.window = 10;
.threshold = 8;
}
.first_byte_timeout = 60s; # How long to wait before we receive a first byte from our backend?
.connect_timeout = 60s; # How long to wait for a backend connection?
.between_bytes_timeout = 60s; # How long to wait between bytes received from our backend?
}
Here is the one call in the log:
* << Request >> 3440734
- Begin req 3440733 rxreq
- Timestamp Start: 1462781837.623325 0.000000 0.000000
- Timestamp Req: 1462781837.623325 0.000000 0.000000
- ReqStart 10.20.129.118 58572
- ReqMethod GET
- ReqURL xxxxx.html
- ReqProtocol HTTP/1.1
- ReqHeader Accept: image/jpeg, application/x-ms-application, image/gif, application/xaml+xml, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, image/pjpeg, application/x-shockwave-flash, */*
- ReqHeader Referer: http://xxxxxx.html
- ReqHeader Accept-Language: it-IT
- ReqHeader User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
- ReqHeader Accept-Encoding: gzip, deflate
- ReqHeader Host: xxxxxx
- ReqHeader DNT: 1
- ReqHeader Connection: Keep-Alive
- ReqHeader Cookie: fc_uid=p; __utma=127650066.830977012.1423064118.1426582505.1426588086.20; _ga=GA1.3.830977012.1423064118; _gat_UA-13041322-1=1; ZNPCQ003-38303300=71a0f671; ff607e18ab6c715f4bb35b5bbcbe1c56=d82989olp2v0ur3gpl2ouprko6; _ga=GA1.2.830977012.142306411
- ReqHeader X-Forwarded-For: 10.20.129.118
- VCL_call RECV
- ReqUnset Host: xxx
- ReqHeader Host: xxx
- ReqURL /xxxx.html
- ReqUnset Cookie: fc_uid=p; __utma=127650066.830977012.1423064118.1426582505.1426588086.20; _ga=GA1.3.830977012.1423064118; _gat_UA-13041322-1=1; ZNPCQ003-38303300=71a0f671; ff607e18ab6c715f4bb35b5bbcbe1c56=d82989olp2v0ur3gpl2ouprko6; _ga=GA1.2.830977012.142306411
- ReqHeader Cookie: fc_uid=p; __utma=127650066.830977012.1423064118.1426582505.1426588086.20; _ga=GA1.3.830977012.1423064118; _gat_UA-13041322-1=1; ZNPCQ003-38303300=71a0f671; ff607e18ab6c715f4bb35b5bbcbe1c56=d82989olp2v0ur3gpl2ouprko6; _ga=GA1.2.830977012.142306411
- ReqUnset Cookie: fc_uid=p; __utma=127650066.830977012.1423064118.1426582505.1426588086.20; _ga=GA1.3.830977012.1423064118; _gat_UA-13041322-1=1; ZNPCQ003-38303300=71a0f671; ff607e18ab6c715f4bb35b5bbcbe1c56=d82989olp2v0ur3gpl2ouprko6; _ga=GA1.2.830977012.142306411
- ReqHeader Cookie: fc_uid=p; __utma=127650066.830977012.1423064118.1426582505.1426588086.20; _ga=GA1.3.830977012.1423064118; _gat_UA-13041322-1=1; ZNPCQ003-38303300=71a0f671; ff607e18ab6c715f4bb35b5bbcbe1c56=d82989olp2v0ur3gpl2ouprko6; _ga=GA1.2.830977012.142306411
- ReqHeader Surrogate-Capability: key=ESI/1.0
- VCL_return hash
- ReqUnset Accept-Encoding: gzip, deflate
- ReqHeader Accept-Encoding: gzip
- VCL_call HASH
- VCL_return lookup
- VCL_call MISS
- VCL_return fetch
- Link bereq 3440735 fetch
- Timestamp Fetch: 1462781838.492085 0.868760 0.868760
- Timestamp Process: 1462781838.492101 0.868776 0.000016
- RespHeader Date: Mon, 09 May 2016 08:17:18 GMT
- RespHeader Server: Varnish
- RespHeader X-Varnish: 3440734
- RespProtocol HTTP/1.1
- RespStatus 503
- RespReason Service Unavailable
- RespReason Service Unavailable
- VCL_call SYNTH
- VCL_return deliver
- RespHeader Content-Length: 0
- Storage malloc Transient
- Debug "RES_MODE 2"
- RespHeader Connection: keep-alive
- Timestamp Resp: 1462781838.492145 0.868820 0.000044
- ReqAcct 985 0 985 153 0 153
- End
Any precious help? Suggestion?

Pretty sure the issue is here:
.timeout = 1s;
.interval = 1s;
Notice that all of them have a time of 1s = 1 second.
I think what's happening is the backend's probe timeouts so varnish flags it as "unhealthy" until your backend respond in a second or less.
Try modifying those values to check whether thats the issue or not

Related

Cannot access Docker container from another

Using this docker-compose file:
version: '3'
services:
hello:
image: nginxdemos/hello
ports:
- 7080:80
tool:
image: wbitt/network-multitool
tty: true
networks:
default:
name: test-network
If I curl from the host, it works.
❯ curl -s -o /dev/null -v http://192.168.1.102:7080
* Expire in 0 ms for 6 (transfer 0x8088b0)
* Trying 192.168.1.102...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x8088b0)
* Connected to 192.168.1.102 (192.168.1.102) port 7080 (#0)
> GET / HTTP/1.1
> Host: 192.168.1.102:7080
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.23.1
< Date: Sun, 10 May 2071 00:06:00 GMT
< Content-Type: text/html
< Transfer-Encoding: chunked
< Connection: keep-alive
< Expires: Sun, 10 May 2071 00:05:59 GMT
< Cache-Control: no-cache
<
{ [6 bytes data]
* Connection #0 to host 192.168.1.102 left intact
If I try to contact another container from within the network, it fails.
❯ docker exec -it $(gdid tool) curl -s -o /dev/null -v http://hello
* Could not resolve host: hello
* Closing connection 0
Is this intended behaviour? I thought networks within the same network (and using docker-compose) are meant to be able to talk by their service name?
I am bringing the containers up with docker-compose up -d

Why I can't enable gzip compression with Traefik?

I don't have any idea, but I can't enable gzip compression...
My infra is small :
NGINX <-> Traefik <-> internet
docker-compose.yml of nginx
version: "3"
services:
p12:
image: nginx:alpine
volumes:
- ./src:/usr/share/nginx/html
networks:
- traefik
labels:
- traefik.enable=true
- traefik.http.routers.p12.entrypoints=web, websecure
- traefik.http.routers.p12.rule=Host(`p12.sysdraw.fr`)
- traefik.http.routers.p12.middlewares=chain-secure#file
- traefik.http.routers.p12.tls=true
- traefik.http.services.p12.loadbalancer.server.port=80
- traefik.http.routers.p12.tls.certresolver=production
- traefik.http.middlewares.p12.compress=true
restart: unless-stopped
networks:
traefik:
external: true
My rules in Traefik :
chains.yml
http:
middlewares:
chain-secure:
chain:
middlewares:
- middlewares-secure-headers
chain-authelia:
chain:
middlewares:
- middlewares-secure-headers
- authelia#docker
middlewares.yml
http:
middlewares:
test-compress:
compress: {}
middlewares-rate-limit:
rateLimit:
average: 100
burst: 50
middlewares-sslheader:
headers:
customResponseHeaders:
X-Forwarded-Proto:
- "https"
latency-check:
circuitBreaker:
expression: "LatencyAtQuantileMS(50.0) > 100"
test-retry:
retry:
attempts: 4
initialInterval: 100ms
middlewares-secure-headers:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
- POST
addVaryHeader: true
#accessControlAllowHeaders:
# - origin
hostsProxyHeaders:
- "X-Forwarded-Host"
#sslRedirect: true # Not used in Version 2.5
# stsSeconds: 63072000 # Uncomment later
stsSeconds: 10
stsIncludeSubdomains: true
stsPreload: true
forceSTSHeader: true
frameDeny: true #overwritten by customFrameOptionsValue
contentTypeNosniff: true
# browserXssFilter: false # Recently became unsafe in a way.
customBrowserXssValue: 0
referrerPolicy: "same-origin"
permissionsPolicy: "camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';"
customResponseHeaders:
X-Robots-Tag: "none,noarchive,nosnippet,notranslate,noimageindex,"
server: ""
I have read the documentation of Trafik, for me all is ok, but when I try with curl :
curl -H "Accept-Encoding: gzip" -i https://mywebsite.com 2>/dev/null | head -n 13
HTTP/2 200
accept-ranges: bytes
content-type: text/html
date: Thu, 19 May 2022 11:33:23 GMT
etag: "62091d80-bcb"
last-modified: Sun, 13 Feb 2022 15:02:24 GMT
permissions-policy: camera 'none'; geolocation 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none';
referrer-policy: same-origin
strict-transport-security: max-age=10; includeSubDomains; preload
vary: Origin
x-content-type-options: nosniff
x-frame-options: DENY
x-robots-tag: none,noarchive,nosnippet,notranslate,noimageindex,
If you have an idea, share with me :)

Ory Hydra 403 With Reverse Proxy

I am trying to get Ory Hydra working in Docker-Compose with Nginx. Due to my iterative approach, I already had a working system before adding Nginx. In other words, it was working, now it isn't.
The changes which I think might affect this process are: Nginx, Hydra's host name, oauth2 config in my demo application. Also, my setup is based on the Kratos-Hydra integration demo. Of course Kratos and the UI are now also accessed from Nginx, so that obviously has changed as well, but I don't think that's causing problems.
So here's what happens when I try to access a secured endpoint in my demo app:
Redirect to kratos-ui for login
Enter details and send request
Login succeeds
Hydra returns 403: You are not allowed to perform this action.
Nginx:
# kratos-selfservice-ui-node
server {
server_name self.localhost;
proxy_set_header Host self.localhost;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://self:3000;
}
}
# kratos
server {
server_name login.localhost;
#proxy_set_header Host ...;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://kratos:4433;
}
}
#hydra
server {
server_name oidc.localhost;
#proxy_set_header Host 127.0.0.1:4444;
#proxy_set_header Host oidc.localhost;
#proxy_set_header X-Real-IP $remote_addr;
#proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://hydra:4444;
}
}
Request:
GET /oauth2/auth?client_id=auth-code-client&login_verifier=8b5f6d3f964c4470ab2e42fac90ae1c2&nonce=XTr2FJETXFsr6kxw3SlZsbh7rbQ_RMw8SdK3MeMCAs0&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin%2Foauth2%2Fcode%2Fhydra&response_type=code&scope=openid+profile&state=4OSX7C_A84-u-6MlUZOlzjAAXiBYIzbKGfGwcAp1n1M%3D HTTP/1.1
Host: hydra:4444
User-Agent: <stuff>
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Referer: http://self.localhost/
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Pragma: no-cache
Cache-Control: no-cache
Hydra entry in docker-compose:
# OIDC Server
# Configured to use Kratos for identities
hydra:
image: oryd/hydra:v1.6.0-alpine
container_name: hydra
depends_on:
- hydra-migrate
#ports:
#- 4444:4444 # Public port
#- 4445:4445 # Admin port
#- 5555:5555 # Port for hydra token user
command:
serve all --dangerous-force-http
volumes:
-
type: bind
source: ./config/hydra
target: /home/ory
environment:
- DSN=postgres://pguser:secret#postgres:5432/hydra?sslmode=disable
- OIDC_SUBJECT_IDENTIFIERS_SUPPORTED_TYPES=public,pairwise
- LOG_LEAK_SENSITIVE_VALUES=true
##- URLS_SELF_ISSUER=http://127.0.0.1:4444
##- URLS_SELF_PUBLIC=http://127.0.0.1:4444
#- URLS_SELF_ISSUER=http://hydra:4444
#- URLS_SELF_PUBLIC=http://hydra:4444
- URLS_SELF_ISSUER=http://oidc.localhost
- URLS_SELF_PUBLIC=http://oidc.localhost
- URLS_CONSENT=http://self.localhost/auth/hydra/consent
- URLS_LOGIN=http://self.localhost/auth/hydra/login
- URLS_LOGOUT=http://self.localhost/logout
- SECRETS_SYSTEM=youReallyNeedToChangeThis
- OIDC_SUBJECT_IDENTIFIERS_PAIRWISE_SALT=youReallyNeedToChangeThis
- OAUTH2_EXPOSE_INTERNAL_ERRORS=true;
- OAUTH2_INCLUDE_LEGACY_ERROR_FIELDS=true
restart: on-failure
networks:
- <ory>
Spring Boot App config:
spring:
security:
oauth2:
client:
registration:
hydra:
client-name: Demo OIDC Client with Spring Boot :D
client-id: auth-code-client
client-secret: secret
provider:
hydra:
issuer-uri: http://oidc.localhost/
And here's the client that I created:
docker exec hydra \
hydra clients create \
--endpoint http://127.0.0.1:4445 \
--id auth-code-client \
--secret secret \
--grant-types authorization_code,refresh_token \
--response-types code,id_token \
--scope openid,profile \
--callbacks http://localhost:8080/login/oauth2/code/hydra
/etc/hosts stuff I added:
# Dev stuff
127.0.0.1 self.localhost
127.0.0.1 login.localhost
127.0.0.1 oidc.localhost
127.0.0.1 oidc-demo.localhost
127.0.0.1 hello.localhost
Hydra logs:
< THIS IS FROM THE INITIAL REQUEST TO THE KRATOS UI >
time=2022-01-24T12:49:00Z level=info msg=started handling request http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 cache-control:no-cache user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0] host:127.0.0.1:4444 method:GET path:/oauth2/auth query:response_type=code&client_id=auth-code-client&state=-__end_skoEpW7KSAfzng1yZyOdJoF2-Cfzls-dccD4%3D&redirect_uri=http://localhost:8080/login/oauth2/code/hydra remote:192.168.16.11:43608 scheme:http]
time=2022-01-24T12:49:00Z level=info msg=access allowed audience=audit http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 cache-control:no-cache user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0] host:127.0.0.1:4444 method:GET path:/oauth2/auth query:response_type=code&client_id=auth-code-client&state=-__end_skoEpW7KSAfzng1yZyOdJoF2-Cfzls-dccD4%3D&redirect_uri=http://localhost:8080/login/oauth2/code/hydra remote:192.168.16.11:43608 scheme:http] service_name=ORY Hydra service_version=v1.6.0
time=2022-01-24T12:49:00Z level=info msg=completed handling request http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 cache-control:no-cache user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0] host:127.0.0.1:4444 method:GET path:/oauth2/auth query:response_type=code&client_id=auth-code-client&state=-__end_skoEpW7KSAfzng1yZyOdJoF2-Cfzls-dccD4%3D&redirect_uri=http://localhost:8080/login/oauth2/code/hydra remote:192.168.16.11:43608 scheme:http] http_response=map[status:302 text_status:Found took:15.9869ms]
time=2022-01-24T12:49:00Z level=info msg=started handling request http_request=map[headers:map[accept:application/json] host:hydra:4445 method:GET path:/oauth2/auth/requests/login query:login_challenge=3a6891edb669434f821a0d5413519bfe remote:192.168.16.2:54218 scheme:http]
time=2022-01-24T12:49:00Z level=info msg=completed handling request http_request=map[headers:map[accept:application/json] host:hydra:4445 method:GET path:/oauth2/auth/requests/login query:login_challenge=3a6891edb669434f821a0d5413519bfe remote:192.168.16.2:54218 scheme:http] http_response=map[status:200 text_status:OK took:3.034ms]
< THIS IS AFTER LOGIN >
time=2022-01-24T12:49:59Z level=info msg=started handling request http_request=map[headers:map[accept:application/json] host:hydra:4445 method:GET path:/oauth2/auth/requests/login query:login_challenge=3a6891edb669434f821a0d5413519bfe remote:192.168.16.2:54292 scheme:http]
time=2022-01-24T12:49:59Z level=info msg=completed handling request http_request=map[headers:map[accept:application/json] host:hydra:4445 method:GET path:/oauth2/auth/requests/login query:login_challenge=3a6891edb669434f821a0d5413519bfe remote:192.168.16.2:54292 scheme:http] http_response=map[status:200 text_status:OK took:3.7631ms]
time=2022-01-24T12:49:59Z level=info msg=started handling request http_request=map[headers:map[accept:application/json] host:hydra:4445 method:PUT path:/oauth2/auth/requests/login/accept query:login_challenge=3a6891edb669434f821a0d5413519bfe remote:192.168.16.2:54296 scheme:http]
time=2022-01-24T12:49:59Z level=info msg=completed handling request http_request=map[headers:map[accept:application/json] host:hydra:4445 method:PUT path:/oauth2/auth/requests/login/accept query:login_challenge=3a6891edb669434f821a0d5413519bfe remote:192.168.16.2:54296 scheme:http] http_response=map[status:200 text_status:OK took:8.8812ms]
time=2022-01-24T12:49:59Z level=info msg=started handling request http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 cache-control:no-cache referer:http://self.localhost/ user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0] host:127.0.0.1:4444 method:GET path:/oauth2/auth query:client_id=auth-code-client&login_verifier=fedb596a040648b8b626e0f7e4f3f04a&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin%2Foauth2%2Fcode%2Fhydra&response_type=code&state=-__end_skoEpW7KSAfzng1yZyOdJoF2-Cfzls-dccD4%3D remote:192.168.16.11:43694 scheme:http]
time=2022-01-24T12:49:59Z level=info msg=access denied audience=audit error=map[message:request_forbidden reason:You are not allowed to perform this action. status:Forbidden status_code:403] http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 cache-control:no-cache referer:http://self.localhost/ user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0] host:127.0.0.1:4444 method:GET path:/oauth2/auth query:client_id=auth-code-client&login_verifier=fedb596a040648b8b626e0f7e4f3f04a&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin%2Foauth2%2Fcode%2Fhydra&response_type=code&state=-__end_skoEpW7KSAfzng1yZyOdJoF2-Cfzls-dccD4%3D remote:192.168.16.11:43694 scheme:http] service_name=ORY Hydra service_version=v1.6.0
time=2022-01-24T12:49:59Z level=info msg=completed handling request http_request=map[headers:map[accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8 accept-encoding:gzip, deflate accept-language:en-US,en;q=0.5 cache-control:no-cache referer:http://self.localhost/ user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:96.0) Gecko/20100101 Firefox/96.0] host:127.0.0.1:4444 method:GET path:/oauth2/auth query:client_id=auth-code-client&login_verifier=fedb596a040648b8b626e0f7e4f3f04a&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Flogin%2Foauth2%2Fcode%2Fhydra&response_type=code&state=-__end_skoEpW7KSAfzng1yZyOdJoF2-Cfzls-dccD4%3D remote:192.168.16.11:43694 scheme:http] http_response=map[status:302 text_status:Found took:8.6448ms]
Update
In the course of trying out everything before posting this question to stackoverflow.com, I went back to an older git commit which was working.
Bad news, it doesn't work anymore. I have the official kratos-hydra integration checked out and built ($ git status -> On branch hydra-integration \n Your branch is up to date with 'origin/hydra-integration'.), and I did the required steps, and now I get this:
$ docker exec hydra_hydra_1 \
hydra token user \
--client-id auth-code-client \
--client-secret secret \
--endpoint http://127.0.0.1:4444/ \
--port 5555 \
--scope openid,offline
Config file not found because "Config File ".hydra" Not Found in "[/home/ory]""
Setting up home route on http://127.0.0.1:5555/
Setting up callback listener on http://127.0.0.1:5555/callback
Press ctrl + c on Linux / Windows or cmd + c on OSX to end the process.
If your browser does not open automatically, navigate to:
http://127.0.0.1:5555/
< then I navigate to 127.0.0.1:5555, click on authorize application, I have to enter log in details, and then I get redirected to an error page >
Got error: The request is not allowed
http: Server closed
The browser doesn't add much info to that:
An error occurred
request_forbidden
The request is not allowed
You are not allowed to perform this action.
I've tried deleting all containers, images, volumes, and networks, browser cookies, using a different browser, restarting docker, restarting my computer. Same problem.
Something that seems odd is that the app always asks me to log in, even if I am logged in already when I go to the UI url manually. I remember that if I was already logged in, it wouldn't ask me to log in again?
Update
I was on the hydra-integration branch for some reason, instead of the hydra-integration-2021, which is why going to back to the basics didn't work. That's my mistake.
The actual project is not working, but after reevaluating the work required and benefits/drawbacks/requirements I decided to switch from Kratos to werther.
To bring some sanity to this I would first update to good internal and external URLs. The crux of the problem feels like you need to configure Ory Hydra (running inside the cluster) with an internet URL used in browsers etc, and this will be different to Ory Hydra's physical URL.
SIMILAR CURITY EXAMPLE
This feels like a similar setup to yours - it's worth taking a little time to understand resources:
Docker Compose
Tutorial Article
Authorization Server Configuration
Look at the base-url property at the top of the third link above, which is what internet clients such as browsers use to connect to the Authorization Server. There will be a property like this that you can set in Hydra.

I got problem while using Nginx to direct requests to services defined in docker-compose.yml

I'm setting up an app with multiple containers, and use nginx to redirect requests to correct container. However, I got stuck with the 502 Bad Gateway error.
Actually, the code is from a course on Udemy: Docker and Kubernetes.
I just copy and paste the code, it ran on instructor machine, but not mine. I tried on my windows and my macbook, restart docker, but still no hope. I looked for solutions on other stackoverflow posts, some other articles, but none of them tell me why it works on others' machines, but not mine.
Here is the repo of the code.
docker-compose.yml (full code):
version: "3"
services:
postgres:
...
redis:
...
nginx:
restart: always
build:
dockerfile: Dockerfile.dev
context: ./nginx
ports:
- "3050:80"
api:
...
client:
...
worker:
...
nginx/Dockerfile.dev
FROM nginx
COPY ./default.conf /etc/nginx/conf.d/default.conf
nginx/default.conf
upstream client {
server client:3000;
}
upstream api {
server api:5000;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://client;
}
location /api {
rewrite /api/(.*) /$1 break;
proxy_pass http://api;
}
}
It runs just fine on instructor's machine and other learners', but not on my machines. I got error when connecting http://localhost:3050 and http://localhost:3050/api:
nginx_1 | 2019/07/08 02:52:35 [error] 6#6: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.25.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://125.235.4.59:3000/", host: "localhost:3050"
nginx_1 | 172.25.0.1 - - [08/Jul/2019:02:52:35 +0000] "GET / HTTP/1.1" 502 559 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "-"
nginx_1 | 2019/07/08 02:52:57 [error] 6#6: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.25.0.1, server: , request: "GET /favicon.ico HTTP/1.1", upstream: "http://125.235.4.59:3000/favicon.ico", host: "localhost:3050", referrer: "http://localhost:3050/"
nginx_1 | 172.25.0.1 - - [08/Jul/2019:02:52:57 +0000] "GET /favicon.ico HTTP/1.1" 502 559 "http://localhost:3050/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36" "-"
Any help is appreciated.
Needed to amend the docker-compose.yml:
the upstream services should expose their ports so that the nginx service can connect i.e.:
api:
expose:
- '5000'
client:
expose:
- '3000'
the nginx service depends_on the upstream services:
nginx:
depends_on:
- 'client'
- 'api'

Nginx Reverse Proxy not redirecting?

Update
The details in this question are getting long, but I think it narrows down to this:
For some reason the host name matters to Nginx when it's trying to figure out whether to proxy the request. If the host name is set to git.example.com the request does not seem to go through, but if it's set to 203.0.113.2 then it goes through. Why does the host name matter?
Filed an issue with Nginx here
And docker compose
Start of original question
When I type in the IP address of the reverse proxy directly into my browser bar, it does perform the redirect.
When using a URL that is resolved via the /etc/hosts entry 203.0.113.2 git.example.com the "Welcome to Ngnix page" is shown. Any ideas? This is the configuration:
server {
listen 203.0.113.2:80 default_server;
server_name 203.0.113.2 git.example.com;
proxy_set_header X-Real-IP $remote_addr; # pass on real client IP
location / {
proxy_pass http://203.0.113.1:3000;
}
}
This is the docker-compose.yml file that is used to launch the whole thing:
version: '3'
services:
gogs-nginx:
build: ./proxy
ports:
- "80:80"
networks:
mk1net:
ipv4_address: 203.0.113.2
gogs:
image: gogs/gogs
ports:
- "3000:3000"
volumes:
- gogs-data:/data
networks:
mk1net:
ipv4_address: 203.0.113.3
volumes:
gogs-data:
external: true
networks:
mk1net:
ipam:
config:
- subnet: 203.0.113.0/24
One interesting thing is that I can navigate to for example:
http://203.0.113.2/issues
The log for the above URL is:
gogs-nginx_1 | 203.0.113.1 - - [07/Oct/2018:11:28:06 +0000] "GET / HTTP/1.1" 200 38825 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" "-"
If I then change 203.0.113.2 with git.example.com (So that the url ends up being git.example.com I get Nginxs "404 not found" page, and the log says:
gogs-nginx_1 | 2018/10/07 11:31:34 [error] 8#8: *10 open() "/usr/share/nginx/html/issues" failed (2: No such file or directory), client: 203.0.113.1, server: localhost, request: "GET /issues HTTP/1.1", host: "git.example.com"
If I only use http://git.example.com as the URL I get the NGINX welcome page, and the following log:
gogs-nginx_1 | 203.0.113.1 - - [07/Oct/2018:11:34:39 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36" "-"
It looks like Nginx understands that the request is for the proxy because it logs the IP of the proxy, but it does not redirect to the proxy and returns a 304 ...
Using Curl to perform requests
Using curl with a host name parameter that targets the proxy like this:
curl -H 'Host: git.example.com' -si http://203.0.113.2
Results in the Nginx welcome page:
ole#mki:~/Gogs/.gogs/docker$ curl -H 'Host: git.example.com' -si http://203.0.113.2
HTTP/1.1 200 OK
Server: nginx/1.15.1
Date: Sun, 07 Oct 2018 17:09:11 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 03 Jul 2018 13:27:08 GMT
Connection: keep-alive
ETag: "5b3b79ac-264"
Accept-Ranges: bytes
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
nginx.org.<br/>
Commercial support is available at
nginx.com.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
But if I change the host name to the ip address like this:
Using curl with a host name parameter that targets the proxy like this:
curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
Then the proxy works as it should:
ole#mki:~/Gogs/.gogs/docker$ curl -H 'Host: 203.0.113.2' -si http://203.0.113.2
HTTP/1.1 302 Found
Server: nginx/1.15.1
Date: Sun, 07 Oct 2018 17:14:46 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 34
Connection: keep-alive
Location: /user/login
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=845bb09d69587b81; Path=/; HttpOnly
Set-Cookie: _csrf=neGgBfG4LdOcdrdeA0snHjVGz4s6MTUzODkzMjQ4NjE5MzEzNzI3OQ%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 17:14:46 GMT; HttpOnly
Set-Cookie: redirect_to=%252F; Path=/
Found.
I am sorry, I failed to realize what's happening on your side because the information is sometimes confusing and sometimes incomplete. But Stackoverflow provides a great explanation on what is considered a good question: How to create a Minimal, Complete, and Verifiable example and so I have just tried to implement a minimal example of a system you are likely going to build.
Below I am providing all the files and will show you a test run as well.
File #1: docker-compose.yml
gogs:
image: gogs/gogs
web:
build: .
ports:
- 8000:80
links:
- gogs
I have outdated Docker at my computer and I do not want to bother with Docker networking, so I have just linked both containers using Docker links. This is the most important part and the link will ensure that (1) our web container depends on gogs; (2) we are able to reference gogs IP from inside web as just gogs. Docker will resolve the name to an IP assigned to the container.
Since I want a minimal example, I've skipped everything else as irrelevant. For example, volume.
File #2: Dockerfile
Newer Compose versions support config options specified right in docker-compose.yml, but I need a custom Dockerfile instead. It's trivial:
FROM nginx:stable-alpine
COPY gogs.conf /etc/nginx/conf.d
File #3: gogs.conf
And finally we need Nginx configuration for proxy:
server {
listen 80 default_server;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
location / {
proxy_pass http://gogs:3000;
}
}
You may notice here we are referring another container simply by name gogs and we need to know what port number it is exposes. We know: 3000.
Running
$ docker-compose build
$ docker-compose up
It's up and running:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1f74293df630 g_web "nginx -g 'daemon off" 2 minutes ago Up 26 seconds 0.0.0.0:8000->80/tcp g_web_1
dfa2dbaa6074 gogs/gogs "/app/gogs/docker/sta" 2 minutes ago Up 26 seconds 22/tcp, 3000/tcp g_gogs_1
web container is exposed to the world at port number 8000.
Tests
by IP
Let's request it by IP:
$ curl -si http://192.168.99.100:8000/
HTTP/1.1 302 Found
Server: nginx/1.14.0
Date: Sun, 07 Oct 2018 15:13:55 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 31
Connection: keep-alive
Location: /install
Set-Cookie: lang=en-US; Path=/; Max-Age=2147483647
Set-Cookie: i_like_gogits=50411f542e2ae8f8; Path=/; HttpOnly
Set-Cookie: _csrf=ZJxRPqnqayIbpAYgZ22zrPIOaSo6MTUzODkyNTIzNTQ2NTg5MDE1NA%3D%3D; Path=/; Expires=Mon, 08 Oct 2018 15:13:55 GMT; HttpOnly
Found.
Corresponding log file:
web_1 | 192.168.99.1 - - [07/Oct/2018:15:14:24 +0000] "GET / HTTP/1.1" 302 31 "-" "curl/7.61.1" "-"
gogs_1 | [Macaron] 2018-10-07 15:14:24: Started GET / for 192.168.99.1
gogs_1 | [Macaron] 2018-10-07 15:14:24: Completed GET / 302 Found in 199.519µs
gogs_1 | 2018/10/07 15:14:24 [TRACE] Session ID: 38d06d393a9e9d21
gogs_1 | 2018/10/07 15:14:24 [TRACE] CSRF Token: Xth986dFWhhj8w8vBdIqRZu4SbI6MTUzODkyNTI2NDYxMDYzNzAyNA==
I can see from the log that (1) both containers work and they were used to process the request; (2) 192.168.99.1 is my host's IP address, which means "gogs" successfully gets a real request IP via X-Forwarded-For.
by domain name
OK, let's request using a domain name:
$ curl -H 'Host: g.example.com' -si http://192.168.99.100:8000/
Trust me, this is just sufficient. Host is an HTTP protocol header to pass domain name. And any browser will do the same under the hood.
and the corresponding log file is --
gogs_1 | [Macaron] 2018-10-07 15:32:49: Started GET / for 192.168.99.1
gogs_1 | [Macaron] 2018-10-07 15:32:49: Completed GET / 302 Found in 618.701µs
gogs_1 | 2018/10/07 15:32:49 [TRACE] Session ID: 81f64d97e9c3dd1e
gogs_1 | 2018/10/07 15:32:49 [TRACE] CSRF Token: X5QyHM4LMIfn8OSJD1gwSSEyXV46MTUzODkyNjM2OTgyODQyMjExMA==
web_1 | 192.168.99.1 - - [07/Oct/2018:15:32:49 +0000] "GET / HTTP/1.1" 302 31 "-" "curl/7.61.1" "-"
No changes, everything works as expected.

Resources