Instant features
Self Hosting
#Localhost Setup
Use this setup if you want to self-host InstantDB while developing on your own machine. In most cases, it's more convenient to use our cloud service to spin up unlimited free apps.
git clone https://github.com/instantdb/instant.gitcd instant/self-hostingdocker compose --env-file .env.example up
The dashboard will be available on http://localhost:3000.
The server will be available on http://localhost:8888.
If you are developing an app and would like to use port 3000 (for example: NextJS), you can modify the port assignment in the docker-compose.yml file like so:
www:ports:- '3001:3000'
Then you will need to change the value for INSTANT_DASHBOARD_URL in .env.example
Apply changes with:
docker compose --env-file .env.example up -d
#Full Hetzner Setup Guide
Create a new server on Hetzner. We tested on a server with 4 vCPU, 8 GB RAM. This guide also shows how to set up TLS. For memory-constrained environments, set the JAVA_OPTIONS environment variable to limit the memory the server container uses.
This setup guide assumes that you have a domain name and can set DNS A records.
If you do not have a domain name, you can use sslip.io to create a domain name on the fly that points to the IP address of your server.
#Install Docker (optional if docker is already installed)
The following Docker install instructions come from docs.docker.com
apt updatesudo apt install ca-certificates curlsudo install -m 0755 -d /etc/apt/keyringssudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.ascsudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOFTypes: debURIs: https://download.docker.com/linux/ubuntuSuites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")Components: stableArchitectures: $(dpkg --print-architecture)Signed-By: /etc/apt/keyrings/docker.ascEOFsudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
#Clone the Instant DB Repo
git clone https://github.com/instantdb/instant.git
#Edit Environment Variables
cd instant/self-hostingcp .env.example .envnano .env
Example:
# Public URLs. Change these when deploying behind a domain or proxy.INSTANT_BACKEND_URL=https://api.myinstant.comINSTANT_DASHBOARD_URL=https://dash.myinstant.comS3_PUBLIC_ENDPOINT=https://files.myinstant.com# Domains used by the Caddy file. For production, point DNS at this host# and update the public URLs above to use these domains with https://.DASHBOARD_DOMAIN=dash.myinstant.comBACKEND_DOMAIN=api.myinstant.comSTORAGE_DOMAIN=files.myinstant.com
The _DOMAIN variables are only used by the Caddy reverse proxy, so if you are bringing your own reverse proxy, you can ignore them.
The MinIO bucket is private by default. Files are accessed through Instant-generated signed URLs.
#DNS
Before running Instant, make sure that you have pointed the subdomain DNS records to the IP address of the server so that when the Caddy reverse proxy starts, it is able to set up TLS certificates automatically.
#Start Command
docker compose -f docker-compose.with-caddy.yml --env-file .env up --build
After everything starts up, the dashboard will be available at whatever you set INSTANT_DASHBOARD_URL to.
#Memory Limits
By default, the backend server container can use a lot of resources. We recommend setting a maximum memory limit on the server container using the JAVA_OPTS environment variable like so:
server:depends_on:postgres:condition: service_healthycreatebuckets:condition: service_completed_successfullyimage: 'ghcr.io/instantdb/server:latest'environment:JAVA_OPTS: -Xmx8g -Xms8g
This example sets the minimum and maximum heap memory usage to 8GB.
#Using Self-Hosted InstantDB
Without a POSTMARK_TOKEN environment variable set, OTP codes will not be emailed. You must read the console output of the server container, which will print the body of any emails that would get sent.
You can use this command to print out recent logs from the server (last 50 lines):
docker compose logs server -n 50
#Using the self-hosted instance with instant-cli
To use the Instant CLI with your local backend, you can set the INSTANT_CLI_API_URI environment variable to http://localhost:8888. For example:
# Local Machine DeploymentINSTANT_CLI_API_URI=http://localhost:8888 npx instant-cli@latest init# Server DeploymentINSTANT_CLI_API_URI=https://api.myinstant.com npx instant-cli@latest init
#Horizontal Scaling With Docker Swarm
Docker Swarm allows one or more machines to distribute Docker containers between them. The InstantDB repo includes a deploy-swarm.sh script designed to easily deploy InstantDB across multiple machines.
This setup guide does not constitute a full production-ready deployment. You are still responsible for backups, observability, monitoring, etc. Every self-hosting situation is different so this is intended to get you started in the right direction.
#Prerequisite
One or more servers with Docker installed. See above guide or the Official Docker Install Guide for instructions.
#Setup Guide
Set up a Docker swarm using:
docker swarm init
This will output a command that you can run on the other servers to join the swarm.
Create an overlay network
docker network create -d overlay --attachable caddy
This will create an overlay network called "caddy" that we will use for the reverse proxy. --attachable is provided so that if needed in the future, a standalone container can be attached for debugging / monitoring purposes.
Assign labels to stabilize machine assignments
docker node update --label-add caddy=true --label-add storage=true
For each machine that you would like to accept requests, make sure you assign the "caddy=true" output and point your DNS at that IP address.
Choose one machine that is responsible for file storage and assign the "storage=true" label. This ensures that the Postgres and MinIO containers will always run on that node, preserving your data.
The 'www', 'createbuckets', and 'server' containers can move freely between nodes since they don't have persistent storage requirements.
#Creating The Encryption Keys
The InstantDB backend server requires the presence of a file at /app/resources/config/override.edn to provide keys for encrypting various secrets in the backend. In the single-container self-hosted setup, this is accomplished via a startup script that creates a file persisted to a volume. Since the backend service will be running on multiple machines without shared storage, we instead use Docker Secrets to mount this file.
The easiest way to register this secret is to run the following on a leader machine.
docker run --rm \-v "$PWD:/out" \ghcr.io/instantdb/server:latest \/app/start.sh generate-override-config /out/override.edndocker secret create server_config ./override.edn
#Configuring Environment Variables
Rather than cloning the repo on a server and filling out a .env file, we have provided a script that you can modify and execute to easily deploy the services with the proper configuration.
To get started: clone the repo on your local computer and edit the ./self-hosting/deploy-swarm.sh file.
SSH_HOST=root@ipDASHBOARD_URL="https://dashboard@example.com"SERVER_URL="https://backend.example.com"S3_PUBLIC_ENDPOINT="https://files.example.com"stack_config() {env -i \PATH="$PATH" \DASHBOARD_URL="$DASHBOARD_URL" \SERVER_URL="$SERVER_URL" \S3_PUBLIC_ENDPOINT="$S3_PUBLIC_ENDPOINT" \docker stack config --compose-file swarm.yml}stack_config | (ssh $SSH_HOST 'docker stack deploy -c - instant')
Docker Swarm/Stack doesn't support loading environment variables from .env files so we use the docker stack config command to fill out a completed yaml specification and send that to the docker stack deploy command on the swarm's manager node by using stdin over ssh.
SSH_HOST is the username and IP address of the manager node to the swarm you are deploying to.
For DASHBOARD_URL, SERVER_URL, and S3_PUBLIC_ENDPOINT, modify the domain/subdomains to match what you assigned in the DNS for your domain.
To configure other environment variables such as a Postmark token to send emails, add another row in the env -i command. Adding the variables outside of stack_config() will not work in order to prevent accidental leakage of environment variables not meant for the deployment.