Using a Reverse Proxy or Load Balancer
If you want to deploy the Anchorpoint stack behind a reverse proxy or load balancer that handles SSL termination, you need to configure the stack to work with the external proxy. This setup is common when you want to centralize SSL certificate management or integrate Anchorpoint into an existing infrastructure.
Architecture Overview
In this setup, you have two separate machines:
- Machine 1: Your reverse proxy or load balancer (e.g., Traefik, nginx, HAProxy) that handles SSL termination
- Machine 2: The Anchorpoint Self-Hosted stack
The reverse proxy terminates SSL connections and forwards traffic to the Anchorpoint stack using internal HTTP connections.
Port Mapping Requirements
Your reverse proxy needs to forward the following ports from the external domain to the Anchorpoint stack:
| External (Proxy) | Internal (Anchorpoint) | Purpose |
|---|---|---|
| 443 (HTTPS) | 8080 (HTTP) | Main HTTP traffic |
| 9000 | 9000 | MinIO S3 API |
| 9090 | 9090 | gRPC traffic |
Configuration Steps
1. Run the CLI install command with SSL disabled
Since your reverse proxy handles SSL termination, configure the stack without SSL:
./selfhost-cli install
When prompted:
- Domain: Enter your public domain (e.g.,
anchorpoint.example.com) - the domain that users will access through your reverse proxy - Enable SSL: Select No (SSL is handled by your reverse proxy)
- MinIO: Select Yes (or No if using another S3 provider)
- Postgres: Select Yes (or No if using another PostgreSQL server)
2. Modify the .env file
After installation, edit the .env file in your install directory to add the internal port configuration:
# Domain Configuration
DOMAIN_NAME=anchorpoint.example.com
HTTP_PORT=443 # External port users connect to
HTTP_INTERNAL_PORT=8080 # Internal port for proxy forwarding
GRPC_PORT=9090
HTTP_SCHEME=https # External scheme (proxy uses HTTPS)
ℹ️ The
HTTP_INTERNAL_PORTvariable is not generated by the CLI tool by default. You need to add it manually to separate the external port (443) from the internal port (8080) used for the proxy mapping.
3. Create a docker-compose override file
Create a file named docker-compose.override.yaml in your install directory:
services:
ap_backend:
environment:
# Fix Keycloak realm URL to use external domain without custom port
- AP_SERVICES_KEYCLOAK_REALM_URL=${HTTP_SCHEME}://${DOMAIN_NAME}/auth/realms/anchorpoint
# Configure MinIO SSL for external/internal connections (if using MinIO)
- AP_SERVICES_S3_DATA_USE_SSL=true
- AP_SERVICES_S3_DATA_USE_SSL_INTERNAL=false
grafana:
labels:
# Fix Grafana routing to check for the correct hostname
- traefik.enable=true
- traefik.http.services.grafana-srvc.loadbalancer.server.port=3000
- traefik.http.routers.grafana-rt.entrypoints=web
- traefik.http.routers.grafana-rt.rule=Host(`${DOMAIN_NAME}`) && (PathPrefix(`/grafana`))
- traefik.http.routers.grafana-rt.service=grafana-srvc
keycloak:
environment:
# Configure Keycloak to use external URLs without custom port
- KC_HOSTNAME_ADMIN_URL=${HTTP_SCHEME}://${DOMAIN_NAME}/auth
- KC_HOSTNAME_URL=${HTTP_SCHEME}://${DOMAIN_NAME}/auth
traefik:
ports:
# Expose internal port instead of external port
- ${HTTP_INTERNAL_PORT}:80
Why these overrides are necessary:
- Keycloak URLs: Remove the port from Keycloak URLs since port 443 is the default for HTTPS and including it can cause issues with Keycloak's redirect URLs
- MinIO SSL Configuration (if using MinIO): Configure the backend to use HTTPS for external MinIO connections (through the reverse proxy) while using HTTP for internal connections (no SSL overhead between containers)
- Grafana routing: Add hostname matching to prevent the
ap_backendcatch-all rule from intercepting Grafana requests - Traefik port: Expose the internal port (8080) instead of the external port (443) since your reverse proxy forwards traffic to 8080
4. Start the stack
Once all configurations are in place, start the stack using the CLI tool:
./selfhost-cli start
The override file will be automatically applied by the CLI tool when starting the stack.
Reverse Proxy Configuration Examples
Here are example configurations for common reverse proxy solutions. Adjust these examples based on your specific reverse proxy setup.
Traefik Example
http:
routers:
anchorpoint-http:
rule: "Host(`anchorpoint.example.com`)"
service: anchorpoint-service
entryPoints:
- websecure
tls:
certResolver: letsencrypt
anchorpoint-minio:
rule: "Host(`anchorpoint.example.com`) && PathPrefix(`/minio`)"
service: minio-service
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
anchorpoint-service:
loadBalancer:
servers:
- url: "http://<anchorpoint-machine-ip>:8080"
minio-service:
loadBalancer:
servers:
- url: "http://<anchorpoint-machine-ip>:9000"
tcp:
routers:
anchorpoint-grpc:
rule: "HostSNI(`anchorpoint.example.com`)"
service: grpc-service
entryPoints:
- grpc
tls:
certResolver: letsencrypt
services:
grpc-service:
loadBalancer:
servers:
- address: "<anchorpoint-machine-ip>:9090"
Important Notes
- Ensure your reverse proxy supports HTTP/2 for gRPC traffic (port 9090)
- Configure proper SSL certificates on your reverse proxy
- Verify that your firewall allows traffic between the reverse proxy and the Anchorpoint stack on ports 8080, 9000, and 9090
Troubleshooting
Keycloak redirect errors
- Verify that
KC_HOSTNAME_URLandKC_HOSTNAME_ADMIN_URLdon't include:443in the URL - Check that your reverse proxy properly forwards the
Hostheader
Grafana shows 404 error
- Ensure the Grafana router rule includes hostname matching:
Host($\{DOMAIN_NAME\}\) && (PathPrefix(/grafana)) - Verify that Grafana labels are properly set in the override file
gRPC connection failures
- Ensure your reverse proxy supports HTTP/2
- Verify that port 9090 is properly forwarded and not blocked by firewalls
MinIO connection errors
- Confirm that
AP_SERVICES_S3_DATA_USE_SSL=trueandAP_SERVICES_S3_DATA_USE_SSL_INTERNAL=falseare set in thedocker-compose.override.yaml - Check that your reverse proxy correctly forwards port 9000