Self-Hosting
Run Kitbase on your own server in minutes with our interactive setup script.
Prerequisites
- A server running Ubuntu (the setup script is only tested on Ubuntu)
- At least 4 GB of RAM
Quick Start
Run the setup script
git clone https://github.com/scr2em/kitbase-sdk.git
cd kitbase-sdk/self-host
sudo bash setup.shWhy sudo?
The setup script installs Docker and Docker Compose if they're not already present, which requires root privileges. Running with sudo ensures the script can install dependencies and manage Docker without permission errors.
The script will check and install dependencies (Docker, Docker Compose), walk you through the configuration, generate your .env file, and start all services.
Open Kitbase
Once the script finishes, open your configured domain in the browser.
Architecture
Everything runs behind Caddy, which handles SSL automatically:
Routing
| Path | Service |
|---|---|
/ | Dashboard (SPA) |
/api/ | Backend API |
Services
| Container | Purpose |
|---|---|
kitbase_caddy | Caddy — reverse proxy with automatic HTTPS |
kitbase_dashboard | Serves the dashboard SPA |
kitbase_backend | Java/Spring API server |
kitbase_mysql | MySQL 8.3 database |
kitbase_clickhouse | ClickHouse analytics database |
kitbase_redis | Redis cache |
Configuration
All configuration is done through environment variables in your .env file (generated by the setup script). The setup script handles the essentials — you can fine-tune everything else later.
| Variable | Default | Description |
|---|---|---|
JWT_SECRET | — | Required. Secret key for JWT tokens. Generate with openssl rand -base64 32 |
DATABASE_PASSWORD | — | Required. MySQL root password |
APP_DOMAIN | localhost | Your domain name (without protocol) |
APP_PROTOCOL | http | http or https |
For the full list of variables (email, OAuth, Stripe, storage, logging, and more), see the Environment Variables reference.
Email
The setup script lets you choose between three email providers:
- SMTP — any SMTP server (Mailgun, SendGrid SMTP, Postmark, your own server, etc.)
- AWS SES — send via the AWS SES API using an access key and secret (no SMTP needed)
- Resend — send via the Resend API using an API key
You can skip email during setup and configure it later. See the Email Providers guide for detailed setup and switching instructions.
Billing
Self-hosted instances have unlimited usage with no plan restrictions.
Changing Configuration
The setup script generates two files: .env (environment variables) and Caddyfile (reverse proxy). To change anything after the initial setup, edit these files directly and restart:
# Edit configuration
nano .env
# Apply changes
docker compose up -dIf you changed the Caddyfile, restart Caddy specifically:
docker compose restart caddyTIP
You can also re-run sudo bash setup.sh to go through the interactive setup again. This will overwrite your .env and Caddyfile with the new values.
Custom Domain
Point your domain's DNS to your server's IP, then re-run the setup script with https://yourdomain.com as the domain. Caddy will automatically provision an SSL certificate from Let's Encrypt.
Alternatively, update the files manually:
- Update your
.env:
APP_DOMAIN=kitbase.example.com
APP_PROTOCOL=https
MAIL_BASE_URL=https://kitbase.example.com- Update your
Caddyfile:
kitbase.example.com {
encode gzip
handle /api/* {
reverse_proxy backend:8100
}
handle {
reverse_proxy dashboard:80
}
}- If using OAuth, update the redirect URIs in
.env:
OAUTH_GOOGLE_REDIRECT_URI=https://kitbase.example.com/api/auth/oauth/google/callback
OAUTH_GITHUB_REDIRECT_URI=https://kitbase.example.com/api/auth/oauth/github/callback- Restart:
docker compose restart caddyTIP
Make sure ports 80 and 443 are open in your firewall / security group. Caddy needs port 80 for the ACME challenge and HTTP → HTTPS redirect, and port 443 for HTTPS.
External Databases
By default, the Docker Compose setup includes MySQL, ClickHouse, and Redis containers. If you prefer to use managed or external instances (e.g., Amazon RDS, ClickHouse Cloud, ElastiCache), you can point Kitbase to them instead.
External MySQL
- Add the connection details to your
.env:
DATABASE_URL=jdbc:mysql://your-mysql-host:3306/flyway_db?createDatabaseIfNotExist=true&useSSL=true
DATABASE_USERNAME=kitbase
DATABASE_PASSWORD=your-password- Remove the
mysqlservice fromdocker-compose.ymland removemysqlfrom the backend'sdepends_on.
TIP
The database must be MySQL 8.0+. Kitbase runs migrations automatically on startup, so the database can be empty.
External ClickHouse
- Add the connection details to your
.env:
CLICKHOUSE_URL=jdbc:clickhouse://your-clickhouse-host:8123/analytics
CLICKHOUSE_USERNAME=default
CLICKHOUSE_PASSWORD=your-password- Remove the
clickhouseservice fromdocker-compose.ymland removeclickhousefrom the backend'sdepends_on.
External Redis
- Add the connection details to your
.env:
REDIS_HOST=your-redis-host
REDIS_PORT=6379- Remove the
redisservice fromdocker-compose.ymland removeredisfrom the backend'sdepends_on.
WARNING
When removing a service from docker-compose.yml, make sure to also remove it from the depends_on section of the backend service, otherwise Docker Compose will fail to start.
SDK Configuration
When using the Kitbase SDK with a self-hosted instance, point baseUrl to your server's /api path:
import { init } from '@kitbase/analytics';
const kitbase = init({
sdkKey: '<YOUR_SDK_KEY>',
baseUrl: 'https://kitbase.example.com/api',
});For the tracking script:
<script>
window.KITBASE_CONFIG = {
sdkKey: 'YOUR_SDK_KEY',
baseUrl: 'https://kitbase.example.com/api',
};
</script>
<script defer src="https://kitbase.dev/lite.js"></script>TIP
The lite.js script itself is a lightweight loader hosted on the Kitbase CDN. It sends all data to the baseUrl you configure — your self-hosted server receives all the analytics data directly.
Managing Data
Backups
Back up your data by dumping the Docker volumes:
# MySQL
docker exec kitbase_mysql mysqldump -u root -p flyway_db > backup.sql
# ClickHouse
docker exec kitbase_clickhouse clickhouse-client --query "SELECT * FROM analytics.custom_events FORMAT Native" > events.backupData Volumes
| Volume | Contents |
|---|---|
mysql_data | User accounts, projects, feature flags, settings |
clickhouse_data | Analytics events, sessions, pageviews |
redis_data | Cache and rate limiting data |
Updating
When a new version of Kitbase is released, update your self-hosted instance by pulling the latest images and restarting:
cd ~/kitbase-sdk/self-host
# Pull latest changes (e.g. docker-compose.yml, setup script)
git pull
# Pull latest images
docker compose pull
# Restart with new images
docker compose up -dYour data is stored in Docker volumes and is preserved across updates. To update a specific service only:
# Update just the dashboard
docker compose pull dashboard
docker compose up -d dashboard
# Update just the backend
docker compose pull backend
docker compose up -d backendTIP
The backend may take up to a minute to start while it runs database migrations and loads resources. During this time, API requests will return 502. The dashboard will remain accessible.
Troubleshooting
Checking logs
# All services
docker compose logs -f
# Specific service
docker compose logs -f backendBackend won't start
The backend waits for MySQL, ClickHouse, and Redis to be healthy before starting. Check their health:
docker compose psReset everything
docker compose down -v
docker compose up -dWARNING
This deletes all data. Only use this if you want a fresh start.