Nginx reverse proxy configuration problem

Hi,

I’m trying to use baserow with nginx as a reverse proxy but with many tries i still can’t figure it out (i can’t use caddy because i have a few other apps configured in nginx with certbot for ssl)
I’m using docker-compose.
Port 4443 is free for use.

This is my docker-compose.yml right now:
(i changed domain and pass data for example)

version: "3.4"

x-backend-required-variables: &backend-required-variables
  SECRET_KEY: ${SECRET_KEY:?password}
  DATABASE_PASSWORD: ${DATABASE_PASSWORD:?password}
  REDIS_PASSWORD: ${REDIS_PASSWORD:?password}

x-common-important-variables: &common-important-variables
  BASEROW_PUBLIC_URL: ${BASEROW_PUBLIC_URL-https://subdomain.domain.pl}
  WEB_FRONTEND_PORT: ${WEB_FRONTEND_PORT:-3500}
  WEB_FRONTEND_SSL_PORT: ${WEB_FRONTEND_SSL_PORT:-4443}
  HOST_PUBLISH_IP: ${HOST_PUBLISH_IP:-0.0.0.0}
  BASEROW_ENABLE_SECURE_PROXY_SSL_HEADER: ${BASEROW_ENABLE_SECURE_PROXY_SSL_HEADER:-yes}

x-common-variables: &common-variables
  <<: *common-important-variables
  PRIVATE_BACKEND_URL: http://backend:8500
  PRIVATE_WEB_FRONTEND_URL: http://web-frontend:3500
  FEATURE_FLAGS:

x-common-backend-variables: &common-backend-variables
  <<: *backend-required-variables
  <<: *common-variables
  MIGRATE_ON_STARTUP: ${MIGRATE_ON_STARTUP:-true}
  SYNC_TEMPLATES_ON_STARTUP: ${SYNC_TEMPLATES_ON_STARTUP:-true}
  DATABASE_USER: ${DATABASE_USER:-baserow}
  DATABASE_NAME: ${DATABASE_NAME:-baserow}
  ADDITIONAL_APPS:
  EMAIL_SMTP:
  EMAIL_SMTP_HOST:
  EMAIL_SMTP_PORT:
  EMAIL_SMTP_USE_TLS:
  EMAIL_SMTP_USER:
  EMAIL_SMTP_PASSWORD:
  FROM_EMAIL:
  DISABLE_ANONYMOUS_PUBLIC_VIEW_WS_CONNECTIONS:
  MEDIA_URL:
  BASEROW_EXTRA_ALLOWED_HOSTS:
  • other lines with services where i only delete caddy lines.

I see all containers running from baserow healty but strange is that they dont have established ports so i think problem is with baserow ports and proxy pass ports.

env file:

SECRET_KEY=password
DATABASE_PASSWORD=password
REDIS_PASSWORD=password
BASEROW_PUBLIC_URL=https://subdomain.domain.pl
WEB_FRONTEND_PORT=80
WEB_FRONTEND_SSL_PORT=4443
HOST_PUBLISH_IP=127.0.0.1:4443

and this is my nginx config file

server {
    server_name  subdomain.domain.pl;

location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_pass http://localhost:4443;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/subdomain.domain.pl/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/subdomain.domain.pl/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = subdomain.domain.pl) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    server_name  subdomain.domain.pl;
    listen 80;
    return 404; # managed by Certbot
}

Sadly official documentation does not have configuration sample for nginx.

Does anyone of you use nginx as reverse proxy and willing to help?

Hey @rafuru ,

Sorry for the lack of helpful docs/examples. This month we are working on adding more examples and simplifying the self-hosting process so it will hopefully be much smoother soon. To fix your problems I’ve gone into detail below:

The default docker-compose.yml currently only exposes the Caddy service ports and then uses that service to route requests to the internal services on the internal docker-compose default network. This is why you don’t see any of the other services exposing ports. If you instead want to use your own reverse proxy after removing Caddy I’ve provided a simplified docker-compose.yml below:

You need to pick a folder on your server to place files uploaded into Baserow, in the compose file below i’ve hardcoded this to /home/your_user/baserow_media in two places. Please change both places in the docker-compose.yml and also the in the example nginx.conf provided below.

version: "3.4"

# MAKE SURE YOU HAVE SET THE REQUIRED VARIABLES IN the .env FILE.configs:


services:
  backend:
    image: baserow/backend:1.10.0
    ports:
      - "${HOST_PUBLISH_IP:-127.0.0.1}:8000:8000"
    env_file:
      - .env
    depends_on:
      - db
      - redis
    volumes:
      - /home/your_user/baserow_media:/baserow/media

  web-frontend:
    image: baserow/web-frontend:1.10.0
    ports:
      - "${HOST_PUBLISH_IP:-127.0.0.1}:3000:3000"
    env_file:
      - .env
    depends_on:
      - backend

  celery:
    image: baserow/backend:1.10.0
    env_file:
      .env
    command: celery-worker
    # The backend image's baked in healthcheck defaults to the django healthcheck
    # override it to the celery one here.
    healthcheck:
      test: [ "CMD-SHELL", "/baserow/backend/docker/docker-entrypoint.sh celery-worker-healthcheck" ]
    depends_on:
      - backend
    volumes:
      - /home/your_user/baserow_media:/baserow/media

  celery-export-worker:
    image: baserow/backend:1.10.0
    command: celery-exportworker
    # The backend image's baked in healthcheck defaults to the django healthcheck
    # override it to the celery one here.
    healthcheck:
      test: [ "CMD-SHELL", "/baserow/backend/docker/docker-entrypoint.sh celery-exportworker-healthcheck" ]
    depends_on:
      - backend
    env_file:
      .env

  celery-beat-worker:
    image: baserow/backend:1.10.0
    command: celery-beat
    # See https://github.com/sibson/redbeat/issues/129#issuecomment-1057478237
    stop_signal: SIGQUIT
    env_file:
      - .env
    depends_on:
      - backend

  db:
    image: postgres:11.3
    restart: unless-stopped
    env_file:
      - .env
    environment:
      - POSTGRES_USER=${DATABASE_USER:-baserow}
      - POSTGRES_PASSWORD=${DATABASE_PASSWORD:?}
      - POSTGRES_DB=${DATABASE_NAME:-baserow}
    healthcheck:
      test: [ "CMD-SHELL", "su postgres -c \"pg_isready -U ${DATABASE_USER:-baserow}\"" ]
      interval: 10s
      timeout: 5s
      retries: 5
    volumes:
      - pgdata:/var/lib/postgresql/data

  redis:
    image: redis:6.0
    command: redis-server --requirepass ${REDIS_PASSWORD:?}
    env_file:
      - .env
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]

volumes:
  pgdata:

Next, because you are using nginx I believe the following config will work, however I haven’t tested it and so it might contain typos etc, but hopefully gives an idea of what you need to change. The changes I’ve made are:

  1. We need to route /api/ requests to the :8000 backend api container, now exposed on port 8000
  2. We need to route /ws/ requests to the :8000 backend api port which handles ws connections also. We also need to upgrade this to support ws.
  3. We need to route /media/ requests to the folder you have configured for Baserow file uploads to be placed.
  4. We need to route all other requests to the web-frontend container now exposed at port :3000
server {
    server_name  subdomain.domain.pl;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header Host $http_host;
        proxy_http_version 1.1;
        proxy_pass http://localhost:3000;
    }

    location ~ ^/(api|ws)/ {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://localhost:8000;
    }

    location /media/ {
        if ($arg_dl) {
            add_header Content-disposition "attachment; filename=$arg_dl";
        }
        # TODO CHANGE TO THE MEDIA FOLDER USED IN THE docker-compose.yml
        root /home/your_user/baserow_media;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/subdomain.domain.pl/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/subdomain.domain.pl/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
    if ($host = subdomain.domain.pl) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    server_name  subdomain.domain.pl;
    listen 80;
    return 404; # managed by Certbot
}
3 Likes

@nigel

Wow! Thanks to your help baserow works perfectly.
There were no errors at all.
Your solution sounds ready for nginx :slight_smile:

Kudos for you

1 Like