Skip to main content

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
90009000MinIO S3 API
90909090gRPC 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_PORT variable 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_backend catch-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_URL and KC_HOSTNAME_ADMIN_URL don't include :443 in the URL
  • Check that your reverse proxy properly forwards the Host header

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=true and AP_SERVICES_S3_DATA_USE_SSL_INTERNAL=false are set in the docker-compose.override.yaml
  • Check that your reverse proxy correctly forwards port 9000