Skip to content

Conversation

@elavol
Copy link

@elavol elavol commented Jan 5, 2026

This fix issue Swetrix/swetrix#460, by using nginx to proxy request then forward to either API or FE. It help Swetrix can be deploy on single domain with API is on /api/ instead of separate domain

Summary by CodeRabbit

  • Chores

    • Added a dedicated reverse proxy so app and API are served from a single public port and direct service port exposure was removed.
    • Consolidated routing: frontend served at / and backend available under /api.
  • Documentation

    • Updated environment variable name to BASE_URL and adjusted setup script and README to reflect the new configuration.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Jan 5, 2026

📝 Walkthrough

Walkthrough

Added an nginx reverse-proxy service to Docker Compose, removed host port mappings from swetrix and swetrix-api, replaced swetrix's API_URL with BASE_URL, and merged nginx routing into one server block proxying /apiswetrix-api:5005 and /swetrix:3000.

Changes

Cohort / File(s) Summary
Docker Compose
compose.yaml
Added nginx-proxy service (nginx:1.29.4-alpine, restart: always) with depends_on health conditions, links to swetrix/swetrix-api, ports: 80:80, and volume mapping ./nginx/config:/etc/nginx/conf.d/default.conf; removed host port mappings 80:3000 (swetrix) and 8080:5005 (swetrix-api); changed swetrix env key from API_URLBASE_URL.
Nginx config
nginx/config
Consolidated two server blocks into a single server listening on port 80; added /api/ location proxying to swetrix-api:5005 with proxy_http_version 1.1 and standard proxy headers; / location proxies to swetrix:3000 with similar headers; removed previous alternate server.
Env / Scripts / Docs
./.env.example, configure.sh, README.md
Replaced API_URL references with BASE_URL and updated example/default value to http://localhost (no port); configure.sh prompt and output now use BASE_URL and trim trailing slashes; README updated to reflect BASE_URL usage and access URL change.

Sequence Diagram

sequenceDiagram
    participant Client
    participant nginx as nginx-proxy<br/>(port 80)
    participant api as swetrix-api<br/>(port 5005)
    participant app as swetrix<br/>(port 3000)

    Client->>nginx: HTTP request (port 80)
    
    rect rgba(200,220,240,0.5)
        Note over nginx: Route decision
        alt Path starts with /api
            nginx->>api: proxy_pass to swetrix-api:5005 (HTTP/1.1)
            api-->>nginx: response
        else Other paths (root)
            nginx->>app: proxy_pass to swetrix:3000 (HTTP/1.1)
            app-->>nginx: response
        end
    end
    
    nginx-->>Client: HTTP response
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped in with a tiny nudge,
Ports tucked in, a proxy to judge,
/api finds the backend gate,
Root greets the frontend—no more wait,
A rabbit's hop: config snug and judged.

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: introducing nginx to handle and proxy requests to both the API and Web UI services.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Fix all issues with AI Agents 🤖
In @nginx/config:
- Around line 6-12: The /api/ location block is missing several proxy headers
and operational directives; inside the location /api/ block add proxy_set_header
X-Forwarded-Proto $scheme and proxy_set_header Upgrade $http_upgrade along with
proxy_set_header Connection $connection_upgrade (and ensure you add the
top-level map $http_upgrade -> $connection_upgrade if WebSocket support is
required), and also add client_max_body_size with an appropriate limit plus
timeout directives proxy_connect_timeout, proxy_send_timeout, and
proxy_read_timeout to make the proxy resilient.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
nginx/config (1)

14-20: Add missing proxy headers and consider operational directives.

The root location has the same gaps as the /api/ location:

Major concerns:

  • X-Forwarded-Proto header missing (critical for HTTPS setups)
  • Connection and Upgrade headers missing (required if the frontend uses WebSockets for real-time updates)

Recommended improvements:

  • Add client_max_body_size directive
  • Add timeout configurations for better reliability
🔎 Proposed enhancements
  location / {
    proxy_pass http://swetrix:3000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+   proxy_set_header X-Forwarded-Proto $scheme;
+   proxy_set_header X-Forwarded-Host $host;
+   
+   # WebSocket support (if needed)
+   proxy_set_header Upgrade $http_upgrade;
+   proxy_set_header Connection $connection_upgrade;
+   
+   # Operational settings
+   client_max_body_size 10M;
+   proxy_connect_timeout 60s;
+   proxy_send_timeout 60s;
+   proxy_read_timeout 60s;
  }
🧹 Nitpick comments (2)
compose.yaml (2)

117-119: Replace deprecated links with depends_on.

The links directive is deprecated in Docker Compose v2+. Use depends_on instead for service dependencies, which provides the same networking functionality with clearer semantics.

🔎 Proposed refactor
  nginx-proxy:
    image: nginx:1.29.4-alpine
    restart: always
-   links:
-     - "swetrix-api"
-     - "swetrix"
+   depends_on:
+     swetrix:
+       condition: service_healthy
+     swetrix-api:
+       condition: service_healthy
    ports:
      - "80:80"

114-123: Consider adding a health check for the nginx-proxy service.

Adding a health check improves service orchestration and enables better monitoring of the reverse proxy.

🔎 Proposed enhancement
  nginx-proxy:
    image: nginx:1.29.4-alpine
    restart: always
    links:
      - "swetrix-api"
      - "swetrix"
    ports:
      - "80:80"
    volumes:
      - ./nginx/config:/etc/nginx/conf.d/default.conf
+   healthcheck:
+     test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1"]
+     interval: 30s
+     timeout: 10s
+     retries: 3
+     start_period: 10s
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b3c8db and f9af660.

📒 Files selected for processing (2)
  • compose.yaml
  • nginx/config
🔇 Additional comments (3)
nginx/config (1)

2-3: LGTM! Standard listen configuration.

The IPv4 and IPv6 listen directives on port 80 are correctly configured for the single-domain architecture.

compose.yaml (2)

9-9: LGTM! API_URL correctly configured for single-domain setup.

The hardcoded /api value aligns with the nginx routing configuration that proxies /api/ requests to the backend API service.


115-115: No action required. The image version nginx:1.29.4-alpine is valid—nginx 1.29.4 (mainline) was released on December 9, 2025. If using a mainline release in production is a concern, consider pinning to the latest stable version (1.28.1 as of January 2026) instead, but the current version specification itself is not invalid.

Comment on lines +6 to 12
location /api/ {
proxy_pass http://swetrix-api:5005/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add missing proxy headers and consider operational directives.

The /api/ location is missing several important proxy headers and operational configurations:

Major concerns:

  • X-Forwarded-Proto header is missing, which is critical for HTTPS awareness if SSL termination is added in the future (e.g., behind a load balancer or when adding TLS)
  • Connection and Upgrade headers are missing, which are required for WebSocket support—verify whether the API uses WebSockets for real-time features

Recommended improvements:

  • Add client_max_body_size directive to control upload limits (prevents large payload attacks)
  • Add timeout configurations (proxy_connect_timeout, proxy_send_timeout, proxy_read_timeout) for better resilience
🔎 Proposed enhancements
  location /api/ {
    proxy_pass http://swetrix-api:5005/;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+   proxy_set_header X-Forwarded-Proto $scheme;
+   proxy_set_header X-Forwarded-Host $host;
+   
+   # WebSocket support (if needed)
+   proxy_set_header Upgrade $http_upgrade;
+   proxy_set_header Connection $connection_upgrade;
+   
+   # Operational settings
+   client_max_body_size 10M;
+   proxy_connect_timeout 60s;
+   proxy_send_timeout 60s;
+   proxy_read_timeout 60s;
  }

If WebSocket support is needed, also add this map directive at the top level (outside server block):

map $http_upgrade $connection_upgrade {
  default upgrade;
  '' close;
}
🤖 Prompt for AI Agents
In @nginx/config around lines 6-12, The /api/ location block is missing several
proxy headers and operational directives; inside the location /api/ block add
proxy_set_header X-Forwarded-Proto $scheme and proxy_set_header Upgrade
$http_upgrade along with proxy_set_header Connection $connection_upgrade (and
ensure you add the top-level map $http_upgrade -> $connection_upgrade if
WebSocket support is required), and also add client_max_body_size with an
appropriate limit plus timeout directives proxy_connect_timeout,
proxy_send_timeout, and proxy_read_timeout to make the proxy resilient.

@Blaumaus
Copy link
Member

Blaumaus commented Jan 5, 2026

wow that look fantastic! thanks for the PR, will be merged before the v5 release soon!

@Blaumaus Blaumaus self-assigned this Jan 13, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@compose.yaml`:
- Line 9: The frontend is configured with API_URL=/backend but nginx only
proxies location /api/ to the API service, causing requests to /backend to hit
the frontend; fix by either changing API_URL to "/api" in the compose
environment (update the API_URL value) or add a matching nginx location block
(add location /backend { proxy_pass http://swetrix-api:5005/; } in nginx/config)
so that requests to /backend are forwarded to swetrix-api:5005.

compose.yaml Outdated
- "80:3000"
environment:
- API_URL=${API_URL}
- API_URL=/backend
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

cd /tmp && find . -name "compose.yaml" -o -name "compose.yml" 2>/dev/null | head -5

Repository: Swetrix/selfhosting

Length of output: 45


🏁 Script executed:

# List structure to understand the repository layout
git ls-files | head -20

Repository: Swetrix/selfhosting

Length of output: 287


🏁 Script executed:

# Find nginx configuration files
fd -t f -i 'nginx' | head -20
fd -t f 'config' | grep -i nginx
ls -la nginx/ 2>/dev/null || echo "No nginx directory at root"

Repository: Swetrix/selfhosting

Length of output: 239


🏁 Script executed:

# Search for nginx configuration content
rg -n 'location|proxy_pass' --type-list | head -5
rg -n 'location|proxy_pass' 2>/dev/null | head -30

Repository: Swetrix/selfhosting

Length of output: 882


🏁 Script executed:

cat -n nginx/config

Repository: Swetrix/selfhosting

Length of output: 731


🏁 Script executed:

cat -n compose.yaml | grep -A 5 -B 5 "API_URL"

Repository: Swetrix/selfhosting

Length of output: 423


Fix nginx configuration to proxy /backend path or change API_URL to /api.

The API_URL is hardcoded to /backend, but the nginx config only proxies /api/ to the API service. There is no location /backend block in nginx/config. This mismatch will cause API requests from the frontend to /backend to be caught by the catch-all location / directive and proxied to the frontend container itself, resulting in API failures.

Either update nginx/config to add location /backend { proxy_pass http://swetrix-api:5005/; } or change API_URL to /api.

🤖 Prompt for AI Agents
In `@compose.yaml` at line 9, The frontend is configured with API_URL=/backend but
nginx only proxies location /api/ to the API service, causing requests to
/backend to hit the frontend; fix by either changing API_URL to "/api" in the
compose environment (update the API_URL value) or add a matching nginx location
block (add location /backend { proxy_pass http://swetrix-api:5005/; } in
nginx/config) so that requests to /backend are forwarded to swetrix-api:5005.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@compose.yaml`:
- Line 9: In the swetrix-fe container environment block in compose.yaml, replace
the unsupported environment key BASE_URL with API_URL so the frontend can locate
the backend (i.e., change the mapping from BASE_URL=${BASE_URL} to
API_URL=${BASE_URL} or set API_URL to the public Swetrix API base URL); update
the environment entry for the swetrix-fe service accordingly.

In `@README.md`:
- Around line 23-25: Replace the non-descriptive link text "here" that points to
https://docs.swetrix.com/selfhosting/configuring with a descriptive phrase like
"Self-hosting configuration guide" (or "Swetrix self-hosting configuration
guide") so the sentence "A table explaining what each value means can be found
here" becomes accessible and lint-compliant; update the markdown link text while
keeping the same URL and leave the surrounding sentences about BASE_URL and
docker unchanged to satisfy MD059.
🧹 Nitpick comments (1)
compose.yaml (1)

114-128: Consider mounting the nginx config read-only.
Prevents accidental writes in the container and signals intent.

🔒 Suggested change
-      - ./nginx/config:/etc/nginx/conf.d/default.conf
+      - ./nginx/config:/etc/nginx/conf.d/default.conf:ro

- "80:3000"
environment:
- API_URL=${API_URL}
- BASE_URL=${BASE_URL}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

swetrix-fe v4.1.0 BASE_URL environment variable support documentation

💡 Result:

Swetrix’s self-hosting docs for the frontend container do not document (or list) any BASE_URL environment variable. The only frontend env var currently documented is:

  • API_URL (URL of your self-hosted Swetrix API instance) [1]

So, if you’re looking for “swetrix-fe v4.1.0 BASE_URL support documentation”, it doesn’t appear to exist in the official Swetrix self-hosting documentation at this time; BASE_URL is not mentioned as a supported/configurable frontend env var there [1].

Source(s)
[1] Swetrix Docs — Self-hosting “Configuring” (Frontend env vars table) https://docs.swetrix.com/selfhosting/configuring


🌐 Web query:

swetrix-fe v4.1.0 release notes API_URL API endpoints configuration

💡 Result:

I couldn’t find any official Swetrix/swETRIX-frontend (“swetrix-fe”) v4.1.0 release notes; the public Swetrix Community Edition releases shown in the main repo go up to v4.0.6 (Oct 31, 2025), so v4.1.0 doesn’t appear to be a published OSS release/tag. [1]

API_URL (frontend) configuration

For self-hosting, the frontend container’s API_URL must point to the publicly reachable base URL of your swetrix-api backend, e.g. https://swetrix-api.mydomain.com (docs show default http://localhost:8080/). It must be reachable from users’ browsers (don’t use a Docker-internal hostname). [2]

API endpoints (what the frontend / clients call)

Swetrix’s APIs are documented as:

  • Events ingestion API (pageviews/custom/heartbeat): POST /log, POST /log/custom, POST /log/hb (cloud examples use https://api.swetrix.com/...; for self-hosting, these are on your own backend base URL). [3]
  • Statistics API: GET /v1/log, GET /v1/log/sessions, etc. [4]
  • Admin API (project/org management): GET /v1/project, POST /v1/project, etc. [5]

If you share where you saw “swetrix-fe v4.1.0” (Git tag, Docker tag, changelog link), I can trace the exact change that impacted API_URL/endpoints.

References:
[1] (github.com) [2] (docs.swetrix.com) [3] (docs.swetrix.com) [4] (docs.swetrix.com) [5] (docs.swetrix.com)

Citations:


Use API_URL instead of BASE_URL for the swetrix-fe container.
Official Swetrix self-hosting documentation only documents API_URL as the supported frontend environment variable. BASE_URL is not recognized and will cause the frontend to fail to resolve API endpoints. Change line 9 to API_URL=${BASE_URL} (or set the value directly to the publicly reachable base URL of your Swetrix API instance).

🤖 Prompt for AI Agents
In `@compose.yaml` at line 9, In the swetrix-fe container environment block in
compose.yaml, replace the unsupported environment key BASE_URL with API_URL so
the frontend can locate the backend (i.e., change the mapping from
BASE_URL=${BASE_URL} to API_URL=${BASE_URL} or set API_URL to the public Swetrix
API base URL); update the environment entry for the swetrix-fe service
accordingly.

Comment on lines +23 to +25
3. Configure the environment variables for your Swetrix instance. It can be easily done by running `./configure.sh` script, which will ask you to provide the necessary values (including `BASE_URL`) and generate a `.env` file with them. A table explaining what each value means can be found [here](https://docs.swetrix.com/selfhosting/configuring).
4. Run `docker compose up -d` to start the Swetrix services.
5. After that, you will be able to access Swetrix web portal on the port you specified in `swetrix` category in `compose.yaml` (by default, it's set to `80`).
5. After that, you will be able to access Swetrix web portal at the URL you set in `BASE_URL` (by default, `http://localhost`).
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use descriptive link text instead of “here.”
Improves accessibility and lint compliance while keeping the same destination.

✏️ Proposed doc tweak
-3. Configure the environment variables for your Swetrix instance. It can be easily done by running `./configure.sh` script, which will ask you to provide the necessary values (including `BASE_URL`) and generate a `.env` file with them. A table explaining what each value means can be found [here](https://docs.swetrix.com/selfhosting/configuring).
+3. Configure the environment variables for your Swetrix instance. It can be easily done by running `./configure.sh` script, which will ask you to provide the necessary values (including `BASE_URL`) and generate a `.env` file with them. See the [configuration variable reference](https://docs.swetrix.com/selfhosting/configuring).

As per static analysis hints, this addresses MD059.

📝 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
3. Configure the environment variables for your Swetrix instance. It can be easily done by running `./configure.sh` script, which will ask you to provide the necessary values (including `BASE_URL`) and generate a `.env` file with them. A table explaining what each value means can be found [here](https://docs.swetrix.com/selfhosting/configuring).
4. Run `docker compose up -d` to start the Swetrix services.
5. After that, you will be able to access Swetrix web portal on the port you specified in `swetrix` category in `compose.yaml` (by default, it's set to `80`).
5. After that, you will be able to access Swetrix web portal at the URL you set in `BASE_URL` (by default, `http://localhost`).
3. Configure the environment variables for your Swetrix instance. It can be easily done by running `./configure.sh` script, which will ask you to provide the necessary values (including `BASE_URL`) and generate a `.env` file with them. See the [configuration variable reference](https://docs.swetrix.com/selfhosting/configuring).
4. Run `docker compose up -d` to start the Swetrix services.
5. After that, you will be able to access Swetrix web portal at the URL you set in `BASE_URL` (by default, `http://localhost`).
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

23-23: Link text should be descriptive

(MD059, descriptive-link-text)

🤖 Prompt for AI Agents
In `@README.md` around lines 23 - 25, Replace the non-descriptive link text "here"
that points to https://docs.swetrix.com/selfhosting/configuring with a
descriptive phrase like "Self-hosting configuration guide" (or "Swetrix
self-hosting configuration guide") so the sentence "A table explaining what each
value means can be found here" becomes accessible and lint-compliant; update the
markdown link text while keeping the same URL and leave the surrounding
sentences about BASE_URL and docker unchanged to satisfy MD059.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants