Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions apps/admin/Dockerfile.admin
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,26 @@ RUN --mount=type=cache,id=pnpm-store,target=/pnpm/store CI=true pnpm install --o
# Build only the admin package
RUN pnpm turbo run build --filter=admin

# =========================================================================== #
# *****************************************************************************
# STAGE 3: Serve with Caddy
# *****************************************************************************

FROM nginx:1.29-alpine AS production
FROM caddy:2.11-builder-alpine AS caddy-builder

COPY apps/admin/nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=installer /app/apps/admin/build/client /usr/share/nginx/html/god-mode
RUN xcaddy build \
--with github.com/mholt/caddy-ratelimit

EXPOSE 3000
FROM caddy:2.11-alpine AS production

COPY --from=caddy-builder /usr/bin/caddy /usr/bin/caddy

COPY apps/admin/caddy/Caddyfile /etc/caddy/Caddyfile

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -fsS http://127.0.0.1:3000/ >/dev/null || exit 1
CMD curl -fsS http://127.0.0.1:3000/god-mode >/dev/null || exit 1

COPY --from=installer /app/apps/admin/build/client /usr/share/caddy/html/god-mode

EXPOSE 3000

CMD ["nginx", "-g", "daemon off;"]
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
17 changes: 17 additions & 0 deletions apps/admin/caddy/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
servers {
trusted_proxies static 0.0.0.0
}
}

:3000 {
root * /usr/share/caddy/html
try_files {path} /index.html
file_server

# Access logs to stdout (default in Caddy)
log {
output stdout
format console
}
}
Comment on lines +1 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Find relevant Dockerfile and Caddyfile configurations
find . -type f -name "Dockerfile*" | grep -E "(admin|web)" | head -20

Repository: makeplane/plane

Length of output: 174


🏁 Script executed:

# Check the admin build copy destination
find . -path "*/admin/*" -name "Dockerfile*" -exec cat {} \;

Repository: makeplane/plane

Length of output: 174


🏁 Script executed:

# Look at the web Caddyfile for comparison
find . -type f -name "Caddyfile" | head -10

Repository: makeplane/plane

Length of output: 114


🏁 Script executed:

cat -n ./apps/admin/caddy/Caddyfile

Repository: makeplane/plane

Length of output: 400


🏁 Script executed:

cat -n ./apps/web/caddy/Caddyfile

Repository: makeplane/plane

Length of output: 400


🏁 Script executed:

# Find admin Dockerfile and examine the COPY instructions
find ./apps/admin -name "Dockerfile*" -exec cat -n {} +

Repository: makeplane/plane

Length of output: 4143


Admin SPA fallback for /god-mode is broken — requests to nested routes will fail

With root * /usr/share/caddy/html and the admin build copied to /usr/share/caddy/html/god-mode, requests like /god-mode/projects/123 will attempt to fall back to /usr/share/caddy/html/index.html instead of /usr/share/caddy/html/god-mode/index.html. Since the latter directory exists but the former does not in this container, deep-linked admin routes will fail. Fix this by updating the fallback path:

-	try_files {path} /index.html
+	try_files {path} /god-mode/index.html

Additional issues:

  • trusted_proxies static 0.0.0.0 effectively trusts all IPv4 client addresses. Constrain this to your actual proxy/load-balancer IP ranges or remove it if not needed.
  • The ratelimit plugin is compiled into Caddy (via xcaddy) but no rate_limit directive is configured in the Caddyfile, leaving it unused.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
servers {
trusted_proxies static 0.0.0.0
}
}
:3000 {
root * /usr/share/caddy/html
try_files {path} /index.html
file_server
# Access logs to stdout (default in Caddy)
log {
output stdout
format console
}
}
{
servers {
trusted_proxies static 0.0.0.0
}
}
:3000 {
root * /usr/share/caddy/html
try_files {path} /god-mode/index.html
file_server
# Access logs to stdout (default in Caddy)
log {
output stdout
format console
}
}
🤖 Prompt for AI Agents
In apps/admin/caddy/Caddyfile around lines 1 to 17, the SPA fallback currently
always serves /usr/share/caddy/html/index.html which breaks deep links under
/god-mode (e.g. /god-mode/projects/123) because the admin build lives in
/usr/share/caddy/html/god-mode; update the fallback so requests under the
/god-mode path return /usr/share/caddy/html/god-mode/index.html (use a
conditional or a separate site block/route that sets try_files {path}
/god-mode/index.html for paths starting with /god-mode). Also tighten or remove
the overly broad trusted_proxies static 0.0.0.0 entry to only include your
proxy/load-balancer CIDRs (or delete it if not needed) and either configure the
rate_limit directive where required or remove the unused rate-limit plugin from
the build to avoid confusion.

29 changes: 0 additions & 29 deletions apps/admin/nginx/nginx.conf

This file was deleted.

19 changes: 13 additions & 6 deletions apps/web/Dockerfile.web
Original file line number Diff line number Diff line change
Expand Up @@ -73,16 +73,23 @@ ENV TURBO_TELEMETRY_DISABLED=1
RUN pnpm turbo run build --filter=web

# *****************************************************************************
# STAGE 3: Serve with nginx
# STAGE 3: Serve with Caddy
# *****************************************************************************
FROM nginx:1.27-alpine AS production

COPY apps/web/nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=installer /app/apps/web/build/client /usr/share/nginx/html
FROM caddy:2.11-builder-alpine AS caddy-builder

EXPOSE 3000
RUN xcaddy build \
--with github.com/mholt/caddy-ratelimit

FROM caddy:2.11-alpine AS production

COPY --from=caddy-builder /usr/bin/caddy /usr/bin/caddy

COPY apps/web/caddy/Caddyfile /etc/caddy/Caddyfile

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -fsS http://127.0.0.1:3000/ >/dev/null || exit 1

CMD ["nginx", "-g", "daemon off;"]
COPY --from=installer /app/apps/web/build/client /usr/share/caddy/html

CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile"]
17 changes: 17 additions & 0 deletions apps/web/caddy/Caddyfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
servers {
trusted_proxies static 0.0.0.0
}
}

:3000 {
root * /usr/share/caddy/html
try_files {path} /index.html
file_server

# Access logs to stdout (default in Caddy)
log {
output stdout
format console
}
}
Comment on lines +1 to +17
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, check if the Caddyfile exists and view its content
find . -name "Caddyfile" -type f

Repository: makeplane/plane

Length of output: 114


🏁 Script executed:

# Search for Docker build configurations that might contain xcaddy with ratelimit
find . -name "Dockerfile*" -type f | head -20

Repository: makeplane/plane

Length of output: 399


🏁 Script executed:

# Look for any rate_limit directives in the codebase
rg "rate_limit" --type-list

Repository: makeplane/plane

Length of output: 448


🏁 Script executed:

# Correct search for rate_limit directives
rg "rate_limit" --type caddy

Repository: makeplane/plane

Length of output: 88


🏁 Script executed:

# View the Caddyfile being reviewed
cat -n ./apps/web/caddy/Caddyfile

Repository: makeplane/plane

Length of output: 400


🏁 Script executed:

# Check the Docker build config for the web app
cat -n ./apps/web/Dockerfile.web | head -50

Repository: makeplane/plane

Length of output: 2194


🏁 Script executed:

# Look for xcaddy or ratelimit references in Docker files
rg "xcaddy|ratelimit|caddy-ratelimit" Dockerfile

Repository: makeplane/plane

Length of output: 109


🏁 Script executed:

# Search for xcaddy or ratelimit in all Dockerfiles
rg "xcaddy|ratelimit|caddy-ratelimit" ./apps/web/

Repository: makeplane/plane

Length of output: 177


🏁 Script executed:

# Check the full web Dockerfile.web
cat -n ./apps/web/Dockerfile.web | tail -50

Repository: makeplane/plane

Length of output: 1817


🏁 Script executed:

# Search the admin Caddyfile for comparison
cat -n ./apps/admin/caddy/Caddyfile

Repository: makeplane/plane

Length of output: 400


🏁 Script executed:

# Search for any rate_limit in all files
rg "rate_limit"

Repository: makeplane/plane

Length of output: 998


🏁 Script executed:

# Check Caddy documentation or configuration context - look for comments or related config
rg "trusted_proxies|X-Forwarded" --context 3

Repository: makeplane/plane

Length of output: 1770


🏁 Script executed:

# Check if there's any rate_limit usage or configuration elsewhere in the web app
rg "rate_limit" ./apps/web/

Repository: makeplane/plane

Length of output: 41


🏁 Script executed:

# Check if the PR or any related docs mention rate limiting intent
find . -name "*.md" -type f | xargs rg -l "rate" 2>/dev/null | head -10

Repository: makeplane/plane

Length of output: 432


🏁 Script executed:

# Check for any rate_limit directives in Caddyfiles
rg "rate_limit" ./apps/*/caddy/

Repository: makeplane/plane

Length of output: 41


🏁 Script executed:

# Check git history or comments around the xcaddy ratelimit addition
git log --oneline --all -- "**/Dockerfile.web" | head -20

Repository: makeplane/plane

Length of output: 1365


🏁 Script executed:

# Look at proxy Caddyfile to understand the architecture better
cat -n ./apps/proxy/Caddyfile.ce

Repository: makeplane/plane

Length of output: 1099


Revisit trusted_proxies scope and consider wiring the ratelimit module

  • trusted_proxies static 0.0.0.0 treats all clients as trusted proxies, allowing any source to supply X-Forwarded-For / related headers that Caddy will trust. While the web app is behind the proxy layer, this setting is unnecessarily permissive; restrict it to your actual proxy ranges (e.g., trusted_proxies static 127.0.0.1).
  • The Docker image builds Caddy with github.com/mholt/caddy-ratelimit, but no rate_limit directives are configured in this Caddyfile. Either add rate limiting if needed or remove the unused module from the build to reduce image size.
🤖 Prompt for AI Agents
In apps/web/caddy/Caddyfile around lines 1–17, the trusted_proxies setting is
overly permissive (static 0.0.0.0) and the caddy-ratelimit module is built but
not used; restrict trusted_proxies to only your actual proxy ranges (for example
127.0.0.1 and any internal Docker/CNI subnet or load‑balancer CIDRs) so Caddy
only trusts X-Forwarded-* from those sources, and either add appropriate
rate_limit directives (site or global scope) to throttle abusive requests using
the built-in ratelimit syntax or remove the github.com/mholt/caddy-ratelimit
build tag from the Docker build to avoid shipping an unused module — update the
Caddyfile to reflect restricted CIDRs and, if adding rate limiting, configure
sensible limits and scopes for your app endpoints.

30 changes: 0 additions & 30 deletions apps/web/nginx/nginx.conf

This file was deleted.

Loading