Portabase Logo
Advanced Configuration

Reverse Proxy

Expose your Dashboard to the internet securely with HTTPS.

By default, the Portabase Dashboard listens on http://localhost:8887. To make it accessible from the outside (e.g. backup.my-company.com) and secure it with HTTPS, use a Reverse Proxy.


This setup assumes you already run a Traefik instance on your server and it watches the Docker network (commonly traefik_network or proxy).

Docker Compose changes

Modify your docker-compose.yml to:

  1. Remove direct host port exposure (no 8887:3000).
  2. Connect the container to Traefik's network.
  3. Add Traefik labels.
docker-compose.yml
name: portabase-dashboard

services:
    portabase:
        container_name: portabase-app
        image: solucetechnologies/portabase:latest
        restart: always
        env_file: .env
        # We no longer expose ports on the host; Traefik handles that
        expose:
            - 3000
        volumes:
            - portabase-private:/app/private
        depends_on:
            db:
                condition: service_healthy
        networks:
            - traefik_network # Network where Traefik lives
            - default # To talk to the local database
        labels:
            - "traefik.enable=true"
            - "traefik.http.routers.portabase.entrypoints=web,websecure"
            - "traefik.http.routers.portabase.rule=Host(`backup.example.com`)"
            - "traefik.http.routers.portabase.tls.certresolver=myresolver"
            - "traefik.http.services.portabase.loadbalancer.server.port=3000"

    db:
        container_name: portabase-pg
        image: postgres:17-alpine
        restart: always
        volumes:
            - postgres-data:/var/lib/postgresql/data
        environment:
            - POSTGRES_DB=${POSTGRES_DB}
            - POSTGRES_USER=${POSTGRES_USER}
            - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
        healthcheck:
            test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
            interval: 10s
            timeout: 5s
            retries: 5
        networks:
            - default

volumes:
    postgres-data:
    portabase-private:

networks:
    traefik_network:
        external: true

Name conflicts

If you host multiple dashboards on the same Traefik server, change the router name in labels to unique values:

  • Instance 1: traefik.http.routers.portabase-prod...
  • Instance 2: traefik.http.routers.portabase-dev...

If you use a traditional web server like Nginx, Apache or Caddy on the host:

1. Portabase configuration

Keep the default config that binds the service to localhost.

ports:
    - "127.0.0.1:8887:3000" # Listen only on localhost

2. Nginx example

Create a server block that proxies requests to the local port 8887.

/etc/nginx/sites-available/portabase
server {
    server_name backup.example.com;

    location / {
        proxy_pass http://127.0.0.1:8887;
        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_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

PROJECT_URL environment variable

Whatever reverse proxy you use, update the .env file so generated links and emails use the correct public URL.

.env
# Before
PROJECT_URL=http://localhost:8887

# After (your public domain)
PROJECT_URL=https://backup.example.com

Restart the dashboard after changing this:

portabase restart . 
docker-compose down && docker-compose up -d 

On this page