# Production Guide ## Build Windows: ```powershell $version = "1.0.0" $commit = git rev-parse --short HEAD $date = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ") go generate ./... go test ./... go build -trimpath -ldflags "-s -w -X ipecho/internal/buildinfo.Version=$version -X ipecho/internal/buildinfo.Commit=$commit -X ipecho/internal/buildinfo.Date=$date" -o bin\ipecho.exe .\cmd\ipecho ``` Linux: ```bash version=1.0.0 commit="$(git rev-parse --short HEAD)" date="$(date -u +%Y-%m-%dT%H:%M:%SZ)" go generate ./... go test ./... go build -trimpath -ldflags "-s -w -X ipecho/internal/buildinfo.Version=$version -X ipecho/internal/buildinfo.Commit=$commit -X ipecho/internal/buildinfo.Date=$date" -o bin/ipecho ./cmd/ipecho ``` `go generate ./...` refreshes: - `assets/icon.svg` - `assets/favicon.svg` - `assets/ipecho.ico` - `assets/favicon.ico` - `internal/httpapi/static/favicon.ico` - `cmd/ipecho/rsrc_windows_amd64.syso` The `.syso` file is used by Go when building `cmd/ipecho` on Windows amd64, so `bin\ipecho.exe` gets the application icon. The HTML does not include a favicon link; browsers request `/favicon.ico` automatically, and the service serves the embedded favicon. ## Configuration | Variable | Default | Description | | --- | --- | --- | | `ADDR` | `:8080` | TCP address for the Go server. In production behind nginx, use `127.0.0.1:8080`. | | `TRUST_PROXY_HEADERS` | `false` | Enables `Forwarded`, `X-Forwarded-For`, and `X-Real-IP` parsing. | | `TRUSTED_PROXY_CIDRS` | `127.0.0.1/32,::1/128` | Proxy IP ranges allowed to supply forwarded client IP headers. | | `READ_HEADER_TIMEOUT` | `5s` | Time allowed to read request headers. | | `READ_TIMEOUT` | `10s` | Time allowed to read the whole request. | | `WRITE_TIMEOUT` | `10s` | Time allowed to write the response. | | `IDLE_TIMEOUT` | `60s` | Keep-alive idle timeout. | | `SHUTDOWN_TIMEOUT` | `5s` | Graceful shutdown deadline after SIGINT/SIGTERM. | | `MAX_HEADER_BYTES` | `1048576` | Maximum request header size. | | `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, or `error`. | | `LOG_FORMAT` | `text` | `text` or `json`. Use `json` for production log collectors. | Example behind nginx on the same host: ```powershell $env:ADDR = "127.0.0.1:8080" $env:TRUST_PROXY_HEADERS = "true" $env:TRUSTED_PROXY_CIDRS = "127.0.0.1/32,::1/128" $env:LOG_FORMAT = "json" .\bin\ipecho.exe ``` Do not enable `TRUST_PROXY_HEADERS` while exposing the Go server directly to the internet. A direct client can spoof those headers. ## Production Checklist - Run the Go service on loopback or a private network, not directly on a public interface, when proxy headers are trusted. - Terminate TLS at nginx or another reverse proxy. - Use `LOG_FORMAT=json` in production. - Keep `/healthz` available for uptime checks. - Build with `-trimpath` and release metadata through `-ldflags`. - Regenerate icons with `go generate ./...` after changing `tools/icongen`.