somratpro Claude Opus 4.7 commited on
Commit
c63d0d1
Β·
1 Parent(s): 0394ebe

Fix ERR_TOO_MANY_REDIRECTS: add trailingSlash:true + config-hash rebuild guard

Browse files

Root cause: nginx proxy_pass adds trailing slash (β†’ /app/), Next.js with
basePath="/app" and trailingSlash:false (default) redirects /app/ β†’ /app,
which loops forever through the same nginx path.

Fix 1 (Dockerfile): add `trailingSlash: true` to next.config.js patch so
/app/ becomes the canonical form β€” nginx always sends it, Next.js serves
directly with no redirect.

Fix 2 (start.sh): hash next.config.js at startup and compare against
.next/.config-hash written after each frontend build. If the hash differs
(new image with patched config) the frontend is rebuilt even when .next
is restored from the HF Dataset backup. Without this, the old .next built
with trailingSlash:false would be reused after the next restore.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Files changed (2) hide show
  1. Dockerfile +2 -1
  2. start.sh +24 -10
Dockerfile CHANGED
@@ -53,11 +53,12 @@ RUN git clone --depth=1 --branch v2.11.3 https://github.com/gitroomhq/postiz-app
53
  # 4. swcMinify: false β†’ Terser (pure JS) instead of native SWC binary;
54
  # avoids extra RSS outside the V8 heap
55
  # 5. experimental.cpus=1 + workerThreads=false β†’ single-thread webpack
56
- RUN sed -i "s|const nextConfig = {|const nextConfig = {\n basePath: '/app',\n assetPrefix: '/app',\n swcMinify: false,|" apps/frontend/next.config.js \
57
  && sed -i "s|productionBrowserSourceMaps: true|productionBrowserSourceMaps: false|" apps/frontend/next.config.js \
58
  && sed -i "s|disable: false,|disable: true,|" apps/frontend/next.config.js \
59
  && sed -i "s|experimental: {|experimental: {\n cpus: 1,\n workerThreads: false,|" apps/frontend/next.config.js \
60
  && grep -q "basePath: '/app'" apps/frontend/next.config.js \
 
61
  && grep -q "productionBrowserSourceMaps: false" apps/frontend/next.config.js \
62
  && grep -q "swcMinify: false" apps/frontend/next.config.js \
63
  && grep -q "cpus: 1" apps/frontend/next.config.js \
 
53
  # 4. swcMinify: false β†’ Terser (pure JS) instead of native SWC binary;
54
  # avoids extra RSS outside the V8 heap
55
  # 5. experimental.cpus=1 + workerThreads=false β†’ single-thread webpack
56
+ RUN sed -i "s|const nextConfig = {|const nextConfig = {\n basePath: '/app',\n assetPrefix: '/app',\n trailingSlash: true,\n swcMinify: false,|" apps/frontend/next.config.js \
57
  && sed -i "s|productionBrowserSourceMaps: true|productionBrowserSourceMaps: false|" apps/frontend/next.config.js \
58
  && sed -i "s|disable: false,|disable: true,|" apps/frontend/next.config.js \
59
  && sed -i "s|experimental: {|experimental: {\n cpus: 1,\n workerThreads: false,|" apps/frontend/next.config.js \
60
  && grep -q "basePath: '/app'" apps/frontend/next.config.js \
61
+ && grep -q "trailingSlash: true" apps/frontend/next.config.js \
62
  && grep -q "productionBrowserSourceMaps: false" apps/frontend/next.config.js \
63
  && grep -q "swcMinify: false" apps/frontend/next.config.js \
64
  && grep -q "cpus: 1" apps/frontend/next.config.js \
start.sh CHANGED
@@ -157,20 +157,33 @@ else
157
  echo " Add HF_TOKEN as a Space secret to enable DB+uploads backup."
158
  fi
159
 
160
- # ── Build Next.js frontend (first boot or after a fresh deploy) ───────────────
161
  # next build is NOT run during docker build β€” the HF builder's ~4 GB cgroup
162
  # limit is less than what next build needs. We run it here where the runtime
163
  # has 16 GB. On subsequent starts the .next directory is restored from the
164
- # HF Dataset backup, so this block only executes once (or after a version bump).
 
 
 
 
165
  FRONTEND_NEXT="${POSTIZ_DIR}/apps/frontend/.next"
166
- if [ ! -f "${FRONTEND_NEXT}/BUILD_ID" ]; then
167
- echo ""
168
- echo " β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”"
169
- echo " β”‚ Building Next.js frontend (first boot β€” takes ~5 min) β”‚"
170
- echo " β”‚ Dashboard is live at ${PUBLIC_URL}/ β”‚"
171
- echo " β”‚ Postiz will start automatically when the build finishes. β”‚"
172
- echo " β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜"
173
- echo ""
 
 
 
 
 
 
 
 
 
174
  cd "${POSTIZ_DIR}"
175
  SENTRY_DSN="" \
176
  SENTRY_AUTH_TOKEN="" \
@@ -181,6 +194,7 @@ if [ ! -f "${FRONTEND_NEXT}/BUILD_ID" ]; then
181
  NEXT_PRIVATE_SKIP_SIZE_MINIMIZATION=true \
182
  NODE_OPTIONS="--max-old-space-size=8192" \
183
  pnpm run build:frontend 2>&1 | sed 's/^/[frontend-build] /'
 
184
  echo "Frontend build complete."
185
  cd /
186
  fi
 
157
  echo " Add HF_TOKEN as a Space secret to enable DB+uploads backup."
158
  fi
159
 
160
+ # ── Build Next.js frontend (first boot or after next.config.js change) ───────
161
  # next build is NOT run during docker build β€” the HF builder's ~4 GB cgroup
162
  # limit is less than what next build needs. We run it here where the runtime
163
  # has 16 GB. On subsequent starts the .next directory is restored from the
164
+ # HF Dataset backup, so this block only executes once per config version.
165
+ #
166
+ # Config-hash check: if next.config.js changed (new image deploy), the stored
167
+ # hash inside .next won't match β€” we rebuild automatically even if BUILD_ID
168
+ # exists. This avoids serving a .next compiled with stale settings.
169
  FRONTEND_NEXT="${POSTIZ_DIR}/apps/frontend/.next"
170
+ CONFIG_HASH=$(md5sum "${POSTIZ_DIR}/apps/frontend/next.config.js" 2>/dev/null | cut -d' ' -f1 || echo "none")
171
+ STORED_HASH=$(cat "${FRONTEND_NEXT}/.config-hash" 2>/dev/null || echo "")
172
+
173
+ if [ ! -f "${FRONTEND_NEXT}/BUILD_ID" ] || [ "${CONFIG_HASH}" != "${STORED_HASH}" ]; then
174
+ if [ "${CONFIG_HASH}" != "${STORED_HASH}" ] && [ -f "${FRONTEND_NEXT}/BUILD_ID" ]; then
175
+ echo ""
176
+ echo " next.config.js changed β€” rebuilding frontend (~5 min)..."
177
+ echo ""
178
+ else
179
+ echo ""
180
+ echo " β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”"
181
+ echo " β”‚ Building Next.js frontend (first boot β€” takes ~5 min) β”‚"
182
+ echo " β”‚ Dashboard is live at ${PUBLIC_URL}/ β”‚"
183
+ echo " β”‚ Postiz will start automatically when the build finishes. β”‚"
184
+ echo " β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜"
185
+ echo ""
186
+ fi
187
  cd "${POSTIZ_DIR}"
188
  SENTRY_DSN="" \
189
  SENTRY_AUTH_TOKEN="" \
 
194
  NEXT_PRIVATE_SKIP_SIZE_MINIMIZATION=true \
195
  NODE_OPTIONS="--max-old-space-size=8192" \
196
  pnpm run build:frontend 2>&1 | sed 's/^/[frontend-build] /'
197
+ echo "${CONFIG_HASH}" > "${FRONTEND_NEXT}/.config-hash"
198
  echo "Frontend build complete."
199
  cd /
200
  fi