Preventing requests for / from infinitely redirecting

1. Caddy version (caddy version):

v2.4.2 h1:chB106RlsIaY4mVEyq9OQM5g/9lHYVputo/LAX2ndFg=

2. How I run Caddy:

I’m running it through Docker using the caddy:2-alpine Docker image. Here’s the Caddyfile I’m using:

The Docker container is behind a load balancer that handles SSL termination, hence why there’s no hostname and it’s just running on port 80 with no HTTPS.

This is working fine except for requests to the root, where it redirects infinitely with a 308 Permanent Redirect. Changing it to /index.html manually works as expected, as do other URLs in our PWA.

a. System environment:

Running in Docker on Linux. Docker version 20.10.7, build f0df350.

b. Command:

docker run -it -p 8080:80 web:latest

c. Service/unit/compose file:

Dockerfile

FROM node:12 as build
WORKDIR /usr/src/app

# Build arguments
ARG SENTRY_RELEASE_TOKEN
ARG REACT_APP_API_URL
ARG REACT_APP_COGNITO_USER_POOL_ID
ARG REACT_APP_COGNITO_URI
ARG REACT_APP_COGNITO_CLIENT_ID
ARG REACT_APP_COGNITO_REDIRECT_URI
ARG FONTAWESOME_NPM_AUTH_TOKEN

COPY package.json yarn.lock .npmrc ./
RUN yarn
COPY . ./
RUN NODE_OPTIONS=--max_old_space_size=8192 yarn build

FROM caddy:2-alpine
# Bash is needed for the script that generates the config based on runtime env vars
RUN apk update && apk add bash
COPY Caddyfile /etc/caddy/Caddyfile
COPY .config /srv/.config
COPY config.sh /srv/config.sh
COPY entrypoint.sh /srv/entrypoint.sh
COPY --from=build /usr/src/app/build /srv
EXPOSE 80

CMD ["/bin/bash", "-c", "/srv/entrypoint.sh"]

Entrypoint

#!/bin/bash

cd /srv
# Generate the config based on runtime env vars
./config.sh ./config.js
caddy run --config /etc/caddy/Caddyfile --adapter caddyfile

d. My complete Caddyfile or JSON config:

{
	admin :2019
}

:80

# Set this path to your site's directory.
root * /srv

try_files {path} /index.html

header /images/* Cache-Control max-age=31536000
header /js/* Cache-Control max-age=31536000
header /static/* Cache-Control max-age=31536000

encode gzip

# Enable the static file server.
file_server

3. The problem I’m having:

When running the app fetching the root URL resulted in a 308 Permanent Redirect. Fetching other routes works correctly.

To reproduce, I run the docker image with

docker run -it -p 8080:80 web:latest

Then using CURL:

~ via 💎 v3.0.1 on ☁️  (us-east-1)
❯ curl -v localhost:8080/submissions
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /submissions HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Accept-Ranges: bytes
< Content-Length: 4503
< Content-Type: text/html; charset=utf-8
< Etag: "qwxcga3h3"
< Last-Modified: Tue, 27 Jul 2021 22:14:34 GMT
< Server: Caddy
< Date: Tue, 27 Jul 2021 22:51:44 GMT
<
<!doctype html><html lang="en"><head><script src="/config.js"></script><script src="//fast.appcues.com/62154.js"></script><meta charset="utf-8"><link rel="shortcut icon" href="/favicon.png"><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta name="theme-color" content="#000000"><link rel="manifest" href="/manifest.json"><title>Relay</title><script src="https://polyfill.io/v3/polyfill.min.js?features=smoothscroll%2Cfetch%2Cconsole.warn%2Cconsole.table%2Cconsole.log%2Cconsole.info%2Cconsole.groupEnd%2Cconsole.group%2Cconsole.exception%2Cconsole.error%2Cconsole%2CResizeObserver%2Ces7%2Ces6%2Ces2019%2Ces2018%2Ces2017%2Ces2016%2Ces2015%2Cdefault%2Cblissfuljs%2Ces5%2Ces2021"></script><script defer="defer" src="https://js.chargebee.com/v2/chargebee.js" data-cb-site="%REACT_APP_CHARGEBEE_SITE%"></script><link href="/static/css/4.c3aead2b.chunk.css" rel="stylesheet"><link href="/static/css/main.6d8b0bdd.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function t(t){for(var n,o,c=t[0],i=t[1],l=t[2],f=0,d=[];f<c.length;f++)o=c[f],Object.prototype.hasOwnProperty.call(a,o)&&a[o]&&d.push(a[o][0]),a[o]=0;for(n in i)Object.prototype.hasOwnProperty.call(i,n)&&(e[n]=i[n]);for(s&&s(t);d.length;)d.shift()();return u.push.apply(u,l||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,o=1;o<r.length;o++){var i=r[o];0!==a[i]&&(n=!1)}n&&(u.splice(t--,1),e=c(c.s=r[0]))}return e}var n={},o={3:0},a={3:0},u=[];function c(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,c),r.l=!0,r.exports}c.e=function(e){var t=[];o[e]?t.push(o[e]):0!==o[e]&&{5:1,6:1}[e]&&t.push(o[e]=new Promise((function(t,r){for(var n="static/css/"+({}[e]||e)+"."+{0:"31d6cfe0",1:"31d6cfe0",5:"cacc27b1",6:"f524e9ed",7:"31d6cfe0"}[e]+".chunk.css",a=c.p+n,u=document.getElementsByTagName("link"),i=0;i<u.length;i++){var l=(s=u[i]).getAttribute("data-href")||s.getAttribute("href");if("stylesheet"===s.rel&&(l===n||l===a))return t()}var f=document.getElementsByTagName("style");for(i=0;i<f.length;i++){var s;if((l=(s=f[i]).getAttribute("data-href"))===n||l===a)return t()}var d=document.createElement("link");d.rel="stylesheet",d.type="text/css",d.onload=t,d.onerror=function(t){var n=t&&t.target&&t.target.src||a,u=new Error("Loading CSS chunk "+e+" failed.\n("+n+")");u.code="CSS_CHUNK_LOAD_FAILED",u.request=n,delete o[e],d.parentNode.removeChild(d),r(u)},d.href=a,document.getElementsByTagName("head")[0].appendChild(d)})).then((function(){o[e]=0})));var r=a[e];if(0!==r)if(r)t.push(r[2]);else{var n=new Promise((function(t,n){r=a[e]=[t,n]}));t.push(r[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,c.nc&&i.setAttribute("nonce",c.nc),i.src=function(e){return c.p+"static/js/"+({}[e]||e)+"."+{0:"9c29a685",1:"2a802b0a",5:"beb3deb5",6:"fb725f4c",7:"51163e9f"}[e]+".chunk.js"}(e);var l=new Error;u=function(t){i.onerror=i.onload=null,clearTimeout(f);var r=a[e];if(0!==r){if(r){var n=t&&("load"===t.type?"missing":t.type),o=t&&t.target&&t.target.src;l.message="Loading chunk "+e+" failed.\n("+n+": "+o+")",l.name="ChunkLoadError",l.type=n,l.request=o,r[1](l)}a[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(t)},c.m=e,c.c=n,c.d=function(e,t,r){c.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},c.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},c.t=function(e,t){if(1&t&&(e=c(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(c.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)c.d(r,n,function(t){return e[t]}.bind(null,n));return r},c.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return c.d(t,"a",t),t},c.o=f* Connection #0 to host localhost left intact
unction(e,t){return Object.prototype.hasOwnProperty.call(e,t)},c.p="/",c.oe=function(e){throw console.error(e),e};var i=this["webpackJsonprelay-web"]=this["webpackJsonprelay-web"]||[],l=i.push.bind(i);i.push=t,i=i.slice();for(var f=0;f<i.length;f++)t(i[f]);var s=l;r()}([])</script><script src="/static/js/4.93dced44.chunk.js"></script><script src="/static/js/main.3325c584.chunk.js"></script></body></html>%      
~ via 💎 v3.0.1 on ☁️  (us-east-1)
❯ curl -v localhost:8080/
*   Trying 127.0.0.1:8080...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET / HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.74.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 308 Permanent Redirect
< Content-Type: text/html; charset=utf-8
< Location: /
< Server: Caddy
< Date: Tue, 27 Jul 2021 22:53:37 GMT
< Content-Length: 37
<
<a href="/">Permanent Redirect</a>.

* Connection #0 to host localhost left intact

The first request (to /submissions correctly returns the PWA). The second redirects to itself, which is incorrect.

4. Error messages and/or full log output:

No error, just the CURL output above.

5. What I already tried:

I tried adding a specific rewrite for the root URL above the try_files directive, but it didn’t change anything.

rewrite / /index.html

6. Links to relevant resources:

None (yet)

You’re running into a regression introduced in v2.4.2 and fixed in v2.4.3. Please upgrade to v2.4.3!

3 Likes

That’s fixed it. Thanks!

1 Like

This topic was automatically closed after 30 days. New replies are no longer allowed.