Skip to content

feat(pprof): add net/http/pprof endpoint behind nginx#5

Merged
afa7789 merged 3 commits into
mainfrom
pprof
May 8, 2026
Merged

feat(pprof): add net/http/pprof endpoint behind nginx#5
afa7789 merged 3 commits into
mainfrom
pprof

Conversation

@afa7789
Copy link
Copy Markdown
Owner

@afa7789 afa7789 commented May 8, 2026

  • separate pprof http.Server in main.go (PPROF_ENABLED/BIND/PORT)
  • proxy /debug/pprof/ via nginx to backend:6060
  • enable in docker-compose with bind 0.0.0.0 inside the container

Summary by CodeRabbit

  • New Features
    • Added an optional performance profiling service that can be enabled or disabled and configured with custom bind address and port.
    • The profiling endpoint is proxied through the web server with timeout protection.
    • Access controls are applied so the endpoint can be restricted in production or exposed in development.

- separate pprof http.Server in main.go (PPROF_ENABLED/BIND/PORT)
- proxy /debug/pprof/ via nginx to backend:6060
- enable in docker-compose with bind 0.0.0.0 inside the container
@afa7789 afa7789 requested a review from Copilot May 8, 2026 13:35
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ff79930b-ccd6-485f-bcbb-23b4a8e665b1

📥 Commits

Reviewing files that changed from the base of the PR and between 6fabede and b24e441.

📒 Files selected for processing (2)
  • backend/cmd/server/main.go
  • nginx/default.conf
🚧 Files skipped from review as they are similar to previous changes (2)
  • nginx/default.conf
  • backend/cmd/server/main.go

📝 Walkthrough

Walkthrough

Adds optional pprof profiling: new config fields and env vars, registers stdlib pprof handlers, starts a standalone net/http pprof server when enabled, and exposes it via Nginx reverse-proxy.

Changes

Pprof Profiling Support

Layer / File(s) Summary
Config Schema
backend/pkg/config/config.go
Config adds PprofEnabled, PprofBind, and PprofPort fields with inline default-value comments.
Config Loading
backend/pkg/config/config.go
Load() reads PPROF_ENABLED, PPROF_BIND, PPROF_PORT and sets the new pprof fields with defaults false, 127.0.0.1, 6060.
Server Imports
backend/cmd/server/main.go
Adds net/net/http imports and registers net/http/pprof handlers on the default ServeMux.
Pprof Server Implementation
backend/cmd/server/main.go
When cfg.PprofEnabled is true, starts a separate http.Server on cfg.PprofBind:cfg.PprofPort with ReadHeaderTimeout and goroutine-based ListenAndServe; logs errors except ErrServerClosed.
Deployment & Network Routing
docker-compose.yml, nginx/default.conf
docker-compose sets PPROF env vars; nginx adds /debug/pprof redirect and /debug/pprof/ reverse-proxy to backend:6060 with access controls and 120s timeout.

Sequence Diagram(s):

sequenceDiagram
  participant Client
  participant Nginx
  participant BackendPprof
  Client->>Nginx: GET /debug/pprof
  Nginx->>Nginx: redirect to /debug/pprof/
  Client->>Nginx: GET /debug/pprof/
  Nginx->>BackendPprof: proxy to http://backend:6060/debug/pprof/
  BackendPprof-->>Nginx: pprof HTML / handlers
  Nginx-->>Client: proxied response
Loading

🎯 2 (Simple) | ⏱️ ~12 minutes

🐰 A pprof server hops in with grace,
Profiling metrics find their place,
Nginx routes them far and wide,
Config keeps the tunnel open bright,
Debugging now shines with light! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding a pprof endpoint behind nginx with http/pprof integration.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch pprof

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
Copy Markdown
Contributor

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nginx/default.conf`:
- Around line 37-46: The pprof location block (location /debug/pprof/) is
publicly exposed with no access controls; restrict it by adding IP allow/deny
rules (e.g., allow 127.0.0.1; allow internal CIDRs like 10.0.0.0/8 or
192.168.0.0/16; deny all;) and/or require basic auth so only trusted clients can
reach proxy_pass http://backend:6060/debug/pprof/; update location /debug/pprof/
to include the allow/deny directives and an auth_basic/auth_basic_user_file
reference (or both) to prevent anonymous internet access while keeping the proxy
settings (proxy_http_version, proxy_set_header, proxy_buffering,
proxy_read_timeout) intact.
🪄 Autofix (Beta)

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6551b6b4-57ec-46aa-b037-965211999fc3

📥 Commits

Reviewing files that changed from the base of the PR and between b31ee38 and 6fabede.

📒 Files selected for processing (4)
  • backend/cmd/server/main.go
  • backend/pkg/config/config.go
  • docker-compose.yml
  • nginx/default.conf

Comment thread nginx/default.conf
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds an optional Go net/http/pprof profiling endpoint served by a separate HTTP server in the backend, and routes it through nginx so it can be accessed via /debug/pprof/ when enabled via environment variables.

Changes:

  • Add PPROF_ENABLED/PPROF_BIND/PPROF_PORT configuration and load them into backend config.
  • Start a dedicated pprof http.Server in the backend when enabled.
  • Proxy /debug/pprof/ from nginx to the backend’s pprof port and enable pprof in docker-compose.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
nginx/default.conf Adds nginx reverse-proxy rule for /debug/pprof/ to backend pprof server.
docker-compose.yml Enables pprof env vars for the backend container in compose.
backend/pkg/config/config.go Introduces pprof config fields and env loading.
backend/cmd/server/main.go Starts a separate pprof HTTP server when enabled.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread nginx/default.conf
Comment on lines +40 to +44
location /debug/pprof/ {
proxy_pass http://backend:6060/debug/pprof/;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_buffering off;
Comment thread nginx/default.conf

# pprof (Go runtime profiles) — backend:6060
# NOTE: expose only in dev / behind auth in prod (leaks runtime info,
# CPU/trace profiles consume resources).
Comment on lines +433 to +435
if cfg.PprofEnabled {
addr := cfg.PprofBind + ":" + cfg.PprofPort
go func() {
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 8, 2026

Note

Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

Files modified:

  • nginx/default.conf

Commit: 0f4778b563ae34c3839e8d883adf6b9e9c29a3c1

The changes have been pushed to the pprof branch.

Time taken: 1m 41s

@afa7789
Copy link
Copy Markdown
Owner Author

afa7789 commented May 8, 2026

@copilot apply changes based on the comments in this thread

coderabbitai Bot and others added 2 commits May 8, 2026 15:04
Fixed 1 file(s) based on 1 unresolved review comment.

Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Copy link
Copy Markdown
Contributor

Copilot AI commented May 8, 2026

@copilot apply changes based on the comments in this thread

Applied all three changes in commit b24e441:

  1. backend/cmd/server/main.go: Added "net" import and replaced string concatenation with net.JoinHostPort(cfg.PprofBind, cfg.PprofPort) for correct IPv6 address formatting.

  2. nginx/default.conf: Added location = /debug/pprof { return 301 /debug/pprof/; } so the URL without the trailing slash redirects instead of falling through to the SPA.

  3. nginx/default.conf: Added IP-based access controls to the /debug/pprof/ block — allows localhost and RFC-1918 private ranges (covering Docker networking), denies all other sources.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 127.0.0.11
    • Triggering command: REDACTED, pid is -1 (packet block)
  • grafana.com
    • Triggering command: /usr/share/grafana/bin/grafana grafana server --homepath=/usr/share/grafana --config=/etc/grafana/grafana.ini --packaging=docker cfg:default.log.mode=console cfg:default.paths.data=/var/lib/grafana cfg:default.paths.logs=/var/log/grafana cfg:default.paths.plugins=/var/lib/grafana/plugins cfg:default.paths.provisioning=/etc/grafana/provisioning t pkg/mod/golang.o/usr/local/go/src/hash/fnv/fnv.go -plu�� 3&#43;afa7789@users.noreply.github.c-I t fg -plugin-opt=-pasbash -plugin-opt=-pas/usr/bin/runc t pkg/mod/golang.o/var/run/docker/runtime-runc/moby (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot finished work on behalf of afa7789 May 8, 2026 15:07
@afa7789 afa7789 merged commit 923bfc2 into main May 8, 2026
1 check passed
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.

3 participants