Self-Hosting
Run Tindra on your own infrastructure. One binary, one Postgres database.
Requirements
- Docker 20.10+
- 512 MB RAM minimum, 1 GB recommended
Install script
The fastest way to get up and running. Run this on the server you want to host Tindra on:
bash -c "$(curl -sSL https://install.tindra.sh)"
The script asks a few questions, then writes a docker-compose.yml, pulls the images, and optionally starts the stack:
Tindra self-hosted install
→ Checking prerequisites
✓ docker found
✓ docker compose found
→ Install directory
Path [/opt/tindra]:
→ Public URL
URL (e.g. https://tindra.example.com): https://tindra.yourcompany.com
→ Host port
Port [8080]:
→ First account
Email: you@yourcompany.com
Name: Your Name
Password: (hidden)
Confirm: (hidden)
→ Generating database password
✓ 48-character random password generated
→ Writing docker-compose.yml
✓ Written to /opt/tindra/docker-compose.yml
→ Pulling images
→ Starting
→ Creating your account
✓ Account created: you@yourcompany.com
Tindra is running.
Open https://tindra.yourcompany.com and log in.
The database password is auto-generated and written into docker-compose.yml. There is no sign-up page. The installer creates your admin account directly via the CLI.
Reverse proxy: The installer binds Tindra to port 8080 by default. It does not configure a reverse proxy or TLS for you. See Reverse proxy below.
Manual install
If you prefer to set things up yourself, or need to integrate with existing infrastructure:
# docker-compose.yml
services:
postgres:
image: postgres:18-alpine
restart: unless-stopped
environment:
POSTGRES_DB: tindra
POSTGRES_USER: tindra
POSTGRES_PASSWORD: 26a676d924141700f615f0b381c84f5e
volumes:
- postgres_data:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U tindra -d tindra"]
interval: 5s
timeout: 5s
retries: 5
tindra:
image: ghcr.io/blendbyte/tindra:latest
restart: unless-stopped
ports:
- "8080:8080"
environment:
DATABASE_URL: "postgres://tindra:26a676d924141700f615f0b381c84f5e@postgres:5432/tindra?sslmode=disable"
PUBLIC_URL: https://your-hostname.example.com
BIND_ADDR: ":8080"
DATA_DIR: /data
COOKIE_SECURE: "true"
volumes:
- tindra_data:/data
depends_on:
postgres:
condition: service_healthy
volumes:
postgres_data:
tindra_data:
docker compose up -d
Migrations run automatically on startup. Once the container is healthy, create your first account:
docker compose exec tindra /tindra users create \
--email you@example.com \
--name "Your Name" \
--password yourpassword
There is no sign-up page. The first account created automatically receives all admin permissions.
Environment variables
Required
| Variable | Description |
|---|---|
DATABASE_URL |
Postgres connection string |
PUBLIC_URL |
The public URL of your Tindra instance (used in emails and DSN generation) |
Optional
| Variable | Default | Description |
|---|---|---|
BIND_ADDR |
0.0.0.0:8080 |
Listen address |
DATA_DIR |
/data |
Directory for attachments and other file storage |
RETENTION_DAYS |
90 |
How long to keep events |
COOKIE_SECURE |
false |
Set to true when serving over HTTPS |
LOG_FORMAT |
text |
Set to json for structured logging |
DISABLE_VERSION_CHECK |
false |
Set to true to disable the periodic check for new Tindra versions. When enabled, the server contacts https://www.tindra.sh/version-update-check every 6 hours and shows a notice in Settings > Overview. Useful for air-gapped environments. |
Set EMAIL_PROVIDER to one of: smtp, postmark, brevo, ahasend, lettermint, cloudflare.
Each provider requires its own set of additional variables. See Authentication for OAuth-related email settings and Configuration for the full variable reference.
Reverse proxy
Run Tindra behind nginx or Caddy for TLS termination. Pass the X-Forwarded-Proto and X-Forwarded-For headers so Tindra sees real client IPs.
If you prefer a Unix socket over a TCP port, set BIND_ADDR=unix:/run/tindra/tindra.sock and point your proxy at the socket path instead.
Caddy
your-hostname.example.com {
reverse_proxy localhost:8080
}
Caddy handles TLS automatically.
nginx
server {
listen 443 ssl;
server_name your-hostname.example.com;
location / {
proxy_pass http://localhost:8080;
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;
}
}
Updating
docker compose pull
docker compose up -d
Migrations run on startup. Downtime is typically under a second.
Next steps
- Configuration: full environment variable reference
- Authentication: set up OAuth and disable password login
- Backup: back up your Postgres data