Back to Overview

Self-Host Tymeslot with Docker

Deploy Tymeslot on any server with Docker installed. Tymeslot ships as a single self-contained container with PostgreSQL embedded, so there is no separate database to run.

Luka Breitig, Software Engineer & AI Developer
Luka Breitig

Aktualisiert am 29. Juli 2026

Prerequisites

  • Docker: Installed on your server (Docker Engine 20.10+ recommended). Docker Compose is optional.
  • Domain Name: A domain or subdomain pointing to your server (e.g., tymeslot.yourdomain.com). Optional for local testing.
  • Server Resources: Minimum 1GB RAM (2GB recommended), 1 CPU core, 10GB storage
  • SSL Certificate: Terminate TLS at a reverse proxy such as Caddy or Nginx, with Let's Encrypt certificates

How it runs

Tymeslot runs as one container: the Phoenix application and its PostgreSQL database live side by side, with all state on two named volumes: tymeslot_data (uploads and timezone data) and tymeslot_pg (the database). There is no separate database container to manage.

Prefer a managed or external PostgreSQL? Set DATABASE_URL to the connection string your provider gives you, or set the discrete DATABASE_HOST variables, and Tymeslot skips the embedded database automatically. The Environment Variables Reference lists every database variable. Managed databases usually require TLS, so add DATABASE_SSL=true.

With an external database you can run the luka1thb/tymeslot:slim image instead: the same application without a PostgreSQL server inside, around 170 MB smaller. Started without a database configured, it exits with instructions.

To run the database as its own container instead, the repository ships a ready-made Compose file that pairs the slim image with a postgres:17-alpine sidecar, waiting on its health check before starting. Backups then become a plain pg_dump against a container that does one thing:

cp .env.example .env
# fill in SECRET_KEY_BASE, PHX_HOST and POSTGRES_PASSWORD
docker compose -f docker-compose.with-postgres.yml up -d

1 Run the prebuilt image (fastest)

Pull and run the published image directly. This is the quickest way to get a working instance. The first line generates SECRET_KEY_BASE and prints it: store that value somewhere safe, because every later run of the container, including upgrades, must use the same one.

SECRET_KEY_BASE="$(openssl rand -base64 64 | tr -d '\n')"; echo "$SECRET_KEY_BASE"

docker run -d \
  --name tymeslot \
  -p 4000:4000 \
  -e SECRET_KEY_BASE="$SECRET_KEY_BASE" \
  -e PHX_HOST=tymeslot.yourdomain.com \
  -v tymeslot_data:/app/data \
  -v tymeslot_pg:/var/lib/postgresql/data \
  luka1thb/tymeslot:latest

Keep tymeslot_pg as a named volume

The embedded PostgreSQL volume must be a Docker named volume (as shown above), not a host path. Swapping it for a bind-mount such as ./pgdata:/var/lib/postgresql/data can fail first-run database initialisation on Docker Desktop, rootless Docker, userns-remap, and SELinux-enforcing hosts. If you need the data on a specific path, use an external database instead.

For a pinned release, replace :latest with a version tag (e.g. luka1thb/tymeslot:1.24.0).

2 Or build from source with Docker Compose

If you'd rather build the image yourself, clone the repository and use the docker-compose.build.yml and .env.example that ship in the repository, so you do not need to write your own Compose file. (The default docker-compose.yml pulls the published image instead of building one, which is option 1 above.)

# Clone and enter the repository
git clone https://github.com/Tymeslot/tymeslot.git
cd tymeslot

# Create your environment file
cp .env.example .env

# Generate the required secrets and paste them into .env
openssl rand -base64 64 | tr -d '\n'   # SECRET_KEY_BASE
openssl rand -base64 32 | tr -d '\n'   # POSTGRES_PASSWORD (only needed for an external DB)

# Build and start (Compose reads .env automatically)
docker compose -f docker-compose.build.yml up -d --build

Watch the logs until the Phoenix server reports it is running:

docker compose logs -f tymeslot

3 Configure environment variables

The container refuses to start without a signing secret. Set the hostname too: every link Tymeslot generates, including the ones in emails, is built from it. Everything else has a sensible default, and the Environment Variables Reference has the full list.

# REQUIRED: signing secret (generate with: openssl rand -base64 64 | tr -d '\n')
SECRET_KEY_BASE=your_generated_secret_here

# REQUIRED: the hostname you will serve Tymeslot on
PHX_HOST=tymeslot.yourdomain.com

# RECOMMENDED: dedicated key for credentials at rest; keep it stable once set
# (generate with: openssl rand -base64 48 | tr -d '\n')
DATA_ENCRYPTION_KEY=your_generated_key_here

# REQUIRED only for an EXTERNAL database (the embedded one defaults this internally)
POSTGRES_PASSWORD=your_secure_password_here

# Optional: host port to publish (default 4000)
PORT=4000

Email configuration

Email defaults to silent discard

Without email configuration, EMAIL_ADAPTER defaults to test, which drops every message: password resets, booking confirmations and reminders all vanish without an error. Configure SMTP, or one of the provider APIs (Postmark, SendGrid, Mailgun, AhaSend), before going live.
# Option 1: SMTP (recommended for most users)
EMAIL_ADAPTER=smtp
EMAIL_FROM_NAME="Your Company Name"
EMAIL_FROM_ADDRESS="hello@yourdomain.com"
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=your_email@gmail.com
SMTP_PASSWORD=your_app_password

# Option 2: Postmark (recommended for high reliability)
# EMAIL_ADAPTER=postmark
# EMAIL_FROM_NAME="Your Company Name"
# EMAIL_FROM_ADDRESS="hello@yourdomain.com"
# POSTMARK_API_KEY=your_postmark_api_key

Step-by-step provider guides: SMTP and Postmark.

4 Set up SSL with a reverse proxy

For production use, terminate TLS at a reverse proxy in front of Tymeslot. Here's a minimal Caddy example (Caddy fetches and renews certificates automatically):

tymeslot.yourdomain.com {
    reverse_proxy localhost:4000
    encode gzip
}

SSL is required for OAuth

Google and Microsoft require HTTPS for authentication callbacks. Configure SSL before connecting those integrations. The Reverse Proxy Setup guide has full Nginx and Caddy walkthroughs, including the WebSocket headers LiveView needs.

5 Access your instance

Open your domain in a browser:

https://tymeslot.yourdomain.com

Click "Sign up" to create your account. On a fresh install, the first account to register becomes the instance admin. Setup then guides you to:

  • Create your account and complete registration
  • Connect your calendar (Google Calendar, Outlook, Apple iCloud, Nextcloud or any CalDAV server)
  • Configure video conferencing (Google Meet, Microsoft Teams, Zoom, MiroTalk P2P, Jitsi Meet, kMeet, Nextcloud Talk, or custom links)
  • Set up your availability and create meeting types
  • Customise your booking page theme

Maintenance and updates

To update to the latest version (build-from-source install):

# Pull latest changes
git pull origin main

# Rebuild and restart
docker compose -f docker-compose.build.yml down
docker compose -f docker-compose.build.yml up -d --build

Running the prebuilt image instead? Pull the new tag and recreate the container. Your tymeslot_data and tymeslot_pg volumes carry your data across the upgrade. See the Upgrading guide.

To back up the embedded database:

docker exec tymeslot su - postgres -c 'pg_dump tymeslot' > backup.sql

Full backup and restore procedure (including the data volume): Backup & Restore.

Guides for your profession

Self-hosting is common among privacy-conscious professionals. See how Therapists and Developers use Tymeslot on their own infrastructure.

Related Articles

Read Upgrading Tymeslot

Upgrading Tymeslot

Upgrade Tymeslot with a single Docker command. Database migrations run automatically on startup. Includes rollback procedures and version compatibility notes.

Read Backup & Restore

Backup & Restore

Back up Tymeslot with pg_dump and cron automation. Covers Docker volume backup for uploaded files and step-by-step recovery from a complete data loss.

Read Cloudron Deployment

Cloudron Deployment

Install Tymeslot on Cloudron in minutes. PostgreSQL, SSL certificates, email relay, and automatic updates are all provisioned and managed for you.