Budibase: Self-Hosted Low-Code Platform With SSO & Automatic HTTPS
This article explains how to set up Budibase in a Docker container with automatic HTTPS via Caddy. This post is part of my series on home automation, networking & self-hosting that shows how to install, configure, and run a home server & network with dockerized or virtualized services.
About Budibase
What is Budibase?
Budibase is an open-source low-code platform that is available on a free plan suitable for self-hosting.
My Take on Budibase
I ended up not using Budibase for the following reasons:
- Steep learning curve
- Not targeted at end users but at developers
- Very high memory usage
Preparation
I’m assuming that you’ve set up Docker as described in the previous articles in this series.
Enable Memory Overcommit
Redis requires larger buffers than are normally available in Linux (source). Add the following to /etc/sysctl.conf
:
vm.overcommit_memory=1
Reboot and check the values with the following commands:
sysctl vm.overcommit_memory
Budibase Installation in a Docker Container
Dockerized Budibase Directory Structure
This is what the directory structure will look like when we’re done:
rpool/
└── encrypted/
└── docker/
└── budibase/
├── data/
├── couchdb/
├── minio/
└── redis/
├── container-vars.env
├── container-vars-couchdb.env
├── container-vars-minio.env
├── container-vars-proxy.env
├── container-vars-redis.env
└── docker-compose.yml
We’re placing the configuration on the encrypted ZFS dataset (rpool/encrypted
).
Create the directories:
mkdir -p /rpool/encrypted/docker/budibase/data/couchdb
mkdir -p /rpool/encrypted/docker/budibase/data/minio
mkdir -p /rpool/encrypted/docker/budibase/data/redis
Budibase Docker Compose File
We’re following the official Docker Compose documentation while keeping the architecture notes about the product’s services in mind.
Create docker-compose.yml
with the following content:
services:
budibase-app:
container_name: budibase-app
hostname: budibase-app
image: budibase.docker.scarf.sh/budibase/apps
restart: unless-stopped
networks:
backend:
expose:
- 4002
environment:
PORT: 4002
env_file:
- container-vars-couchdb.env
- container-vars-minio.env
- container-vars-redis.env
- container-vars.env
depends_on:
- budibase-worker
- budibase-redis
budibase-worker:
container_name: budibase-worker
hostname: budibase-worker
image: budibase.docker.scarf.sh/budibase/worker
restart: unless-stopped
networks:
backend:
expose:
- 4003
environment:
PORT: 4003
env_file:
- container-vars-couchdb.env
- container-vars-minio.env
- container-vars-redis.env
- container-vars.env
depends_on:
- budibase-redis
- budibase-minio
budibase-minio:
container_name: budibase-minio
hostname: budibase-minio
image: minio/minio
restart: unless-stopped
networks:
backend:
expose:
- 4003
env_file:
- container-vars-minio.env
volumes:
- ./data/minio:/data
command: server /data --console-address ":9001"
healthcheck:
test: "timeout 5s bash -c ':> /dev/tcp/127.0.0.1/9000' || exit 1"
interval: 30s
timeout: 20s
retries: 3
budibase-proxy:
container_name: budibase-proxy
hostname: budibase-proxy
image: budibase/proxy
restart: unless-stopped
networks:
backend:
caddy_caddynet:
expose:
- 10000
env_file:
- container-vars-couchdb.env
- container-vars-minio.env
- container-vars-proxy.env
- container-vars.env
depends_on:
- budibase-minio
- budibase-worker
- budibase-app
- budibase-couchdb
budibase-couchdb:
container_name: budibase-couchdb
hostname: budibase-couchdb
image: budibase/couchdb
restart: unless-stopped
networks:
backend:
expose:
- 5984
env_file:
- container-vars-couchdb.env
volumes:
- ./data/couchdb:/opt/couchdb/data
budibase-redis:
container_name: budibase-redis
hostname: budibase-redis
image: redis
restart: unless-stopped
networks:
backend:
expose:
- 6379
volumes:
- ./data/redis:/data
networks:
caddy_caddynet:
external: true
backend:
driver: bridge
Budibase Environment Files
Generate Passwords and Secrets
Generate random alphanumeric strings and store them as container environment variables in container-vars.env
:
cd /rpool/encrypted/docker/budibase/
echo "# Secrets" >> container-vars.env
echo "API_ENCRYPTION_KEY=$(tr -cd '[:alnum:]' < /dev/urandom | fold -w "64" | head -n 1)" >> container-vars.env
echo "JWT_SECRET=$(tr -cd '[:alnum:]' < /dev/urandom | fold -w "64" | head -n 1)" >> container-vars.env
echo "INTERNAL_API_KEY=$(tr -cd '[:alnum:]' < /dev/urandom | fold -w "64" | head -n 1)" >> container-vars.env
Generate random alphanumeric strings and store them as container environment variables in container-vars-minio.env
:
echo "# Secrets" >> container-vars-minio.env
echo "MINIO_ACCESS_KEY=budibase" >> container-vars-minio.env
echo "MINIO_SECRET_KEY=$(tr -cd '[:alnum:]' < /dev/urandom | fold -w "64" | head -n 1)" >> container-vars-minio.env
echo "MINIO_ROOT_USER=\${MINIO_ACCESS_KEY}" >> container-vars-minio.env
echo "MINIO_ROOT_PASSWORD=\${MINIO_SECRET_KEY}" >> container-vars-minio.env
Generate random alphanumeric strings and store them as container environment variables in container-vars-couchdb.env
:
echo "# Secrets" >> container-vars-couchdb.env
echo "COUCH_DB_USER=budibase" >> container-vars-couchdb.env
echo "COUCH_DB_USERNAME=\${COUCH_DB_USER}" >> container-vars-couchdb.env
echo "COUCHDB_USER=\${COUCH_DB_USER}" >> container-vars-couchdb.env
echo "COUCH_DB_PASSWORD=$(tr -cd '[:alnum:]' < /dev/urandom | fold -w "64" | head -n 1)" >> container-vars-couchdb.env
echo "COUCHDB_PASSWORD=\${COUCH_DB_PASSWORD}" >> container-vars-couchdb.env
Additional Container Environment Variables
Edit container-vars.env
so that it looks like the following:
# Secrets
API_ENCRYPTION_KEY=YOUR_PASSWORD_HERE
JWT_SECRET=YOUR_PASSWORD_HERE
INTERNAL_API_KEY=YOUR_PASSWORD_HERE
# Ports
CLUSTER_PORT=10000
# Budibase
SELF_HOSTED=1
APPS_URL=http://budibase-app:4002
WORKER_URL=http://budibase-worker:4003
BUDIBASE_ENVIRONMENT=PRODUCTION
LOG_LEVEL=info
ENABLE_ANALYTICS=false # Disable telemetry
# For the proxy
APPS_UPSTREAM_URL=${APPS_URL}
WORKER_UPSTREAM_URL=${WORKER_URL}
Edit container-vars-minio.env
so that it looks like the following:
# Secrets
MINIO_ACCESS_KEY=budibase
MINIO_SECRET_KEY=YOUR_PASSWORD_HERE
# Minio
MINIO_BROWSER=off # disable web access
MINIO_URL=http://budibase-minio:9000
# For the proxy
MINIO_UPSTREAM_URL=${MINIO_URL}
Edit container-vars-couchdb.env
so that it looks like the following:
# Secrets
COUCH_DB_USER=budibase
COUCH_DB_USERNAME=${COUCH_DB_USER}
COUCHDB_USER=${COUCH_DB_USER}
COUCH_DB_PASSWORD=YOUR_PASSWORD_HERE
COUCHDB_PASSWORD=${COUCH_DB_PASSWORD}
# CouchDB
COUCH_DB_URL=http://${COUCH_DB_USER}:${COUCH_DB_PASSWORD}@budibase-couchdb:5984
TARGETBUILD=docker-compose
# For the proxy
COUCHDB_UPSTREAM_URL=http://budibase-couchdb:5984
Create container-vars-redis.env
so that it looks like the following:
REDIS_URL=budibase-redis:6379
Create container-vars-proxy.env
so that it looks like the following:
RESOLVER=127.0.0.11
Start the Budibase Container
Navigate into the directory with docker-compose.yml
and run:
docker compose up -d
Inspect the container logs for errors with the command docker compose logs --tail 100 --timestamps
.
Budibase Let’s Encrypt Certificate via Caddy
Caddyfile
Add the following to Caddyfile
(details):
budibase.{$MY_DOMAIN} {
reverse_proxy budibase-proxy:10000 {
}
tls {
dns cloudflare {env.CLOUDFLARE_API_TOKEN}
}
}
DNS A Record
Add the following A record to your DNS domain:
budibase.home.yourdomain.com 192.168.0.4 # replace with your Docker host's IP address
Try to resolve the name on a machine in your network (e.g., nslookup budibase.home.yourdomain.com
).
Reload Caddy’s Configuration
Instruct Caddy to reload its configuration by running:
docker exec -w /etc/caddy caddy caddy reload
You should now be able to access the Portelia web interface at https://budibase.home.yourdomain.com
without getting a certificate warning from your browser.
Initial Budibase Configuration
Open https://budibase.home.yourdomain.com
in your browser. You’re asked to create an admin user and your first app (select any name, e.g., Test
).
Navigate to Settings > Organisation. Choose a name for your organization (e.g., Home
) and set the Platform URL to the actual URL you use to access Budibase (e.g., https://budibase.home.yourdomain.com
).
SSO via Authelia: Budibase OAuth Authentication
This section describes how to set up single sign-on to ownCloud via OpenID Connect authentication to Authelia. It is based on the Authelia Budibase integration guide.
Authelia: Configure OpenID Connect IdP
Client Secret
The shared secret between Budibase and Authelia is entered as plaintext in the Budibase UI but as a hash of the plaintext in Authelia’s configuration. Create a new secret by running the following command (docs):
docker run authelia/authelia:latest authelia crypto hash generate pbkdf2 --random --random.length 32 --random.charset alphanumeric
The command’s output looks as follows:
Random Password: v0e1zWJhvKQYud1lVUx4XhLibOwp0zyd
Digest: $pbkdf2-sha512$310000$vFbvgWgmhAIdZCbcLsrrXA$yRENW40rZpWLUP2ABQglEAhIHgpl7QAJ3eq8ZDEMmEHDL9Rro3eGwQ/4u05JsSLsEO5NIw.iAWVbo7EsiL8V1w
From the above output, the following two strings are required:
- Plaintext secret: v0e1zWJhvKQYud1lVUx4XhLibOwp0zyd
- Hashed secret: $pbkdf2-sha512$310000$vFbvgWgmhAIdZCbcLsrrXA$yRENW40rZpWLUP2ABQglEAhIHgpl7QAJ3eq8ZDEMmEHDL9Rro3eGwQ/4u05JsSLsEO5NIw.iAWVbo7EsiL8V1w
Note: do not use the above values. Create your own!
YAML Configuration File
Add the following to Authelia’s configuration file config/configuration.yml
(details):
clients:
- client_id: budibase
client_name: Budibase
client_secret: '$pbkdf2-sha512$310000$vFbvgWgmhAIdZCbcLsrrXA$yRENW40rZpWLUP2ABQglEAhIHgpl7QAJ3eq8ZDEMmEHDL9Rro3eGwQ/4u05JsSLsEO5NIw.iAWVbo7EsiL8V1w' # Replace with your own hashed secret
redirect_uris:
- budibase.home.yourdomain.com/api/global/auth/oidc/callback # Replace with your proper URL
scopes:
- openid
- profile
- email
- offline_access
response_types:
- code
token_endpoint_auth_method: client_secret_post
userinfo_signed_response_alg: none
Restart Authelia
We changed the container’s environment, which makes it necessary to recreate the container (stopping and starting is not enough). Navigate into the authelia
directory and run:
docker compose down
docker compose up -d
Inspect the container logs for errors with the command docker compose logs --tail 30 --timestamps
.
Budibase: Enable OAuth Authentication
In Budibase’s UI, navigate to Settings > Auth > OpenID Connect and set the following values:
- Config URL:
https://auth.home.yourdomain.com/.well-known/openid-configuration
- Client ID: budibase
- Client secret: [paste the plaintext secret you generated above]
- Scopes:
openid profile email offline_access
- Activated: [enabled]
Save the settings.
Log In via OAuth
In a different browser, access https://budibase.home.yourdomain.com
. Click Login with OIDC.
Automatic Provisioning
Note that OIDC users are auto-provisioned in Budibase (docs).