Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Tymeslot/tymeslot/llms.txt

Use this file to discover all available pages before exploring further.

Tymeslot ships as a single Docker image with PostgreSQL embedded — there’s nothing else to install or wire up. One docker run command pulls the image, starts the database, runs migrations, and brings up the Phoenix web server. You can be taking bookings in under five minutes on any machine that has Docker installed.

System requirements

RequirementMinimumRecommended
Docker20.10+Latest stable
RAM500 MB1 GB
Disk1 GB free5 GB+
OSAny Linux (64-bit)Ubuntu 22.04 / Debian 12
A domain name is optional for local testing but required for a production deployment with SSL. For reverse proxy setup (Nginx, Caddy, Traefik), see the Reverse Proxy Setup guide.

Choose your install path

The fastest way to get started. Docker pulls the published image from Docker Hub automatically.
Keep tymeslot_pg as a named volume. Swapping it for a host path (e.g. ./pgdata:/var/lib/postgresql/data) can break first-run initialisation on Docker Desktop, rootless Docker, userns-remap, or SELinux-enforcing hosts because the mount arrives with an ownership the container can’t change. If you need the database on a specific host path, use an external PostgreSQL instance instead.
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 with no error. Configure SMTP or Postmark before going live. See the Email Configuration guide.
Run the following command to start Tymeslot with SMTP email configured:
docker run -d \
  --name tymeslot \
  -p 4000:4000 \
  -e SECRET_KEY_BASE="$(openssl rand -base64 64 | tr -d '\n')" \
  -e PHX_HOST=localhost \
  -e EMAIL_ADAPTER=smtp \
  -e EMAIL_FROM_NAME="Tymeslot" \
  -e EMAIL_FROM_ADDRESS="noreply@yourdomain.com" \
  -e SMTP_HOST="smtp.example.com" \
  -e SMTP_PORT=587 \
  -e SMTP_USERNAME="your-smtp-username" \
  -e SMTP_PASSWORD="your-smtp-password" \
  -v tymeslot_data:/app/data \
  -v tymeslot_pg:/var/lib/postgresql/data \
  luka1thb/tymeslot:latest
Wait 30–60 seconds for PostgreSQL to initialise, then open http://localhost:4000.To pin a specific version instead of latest, replace the tag with a release number — e.g. luka1thb/tymeslot:1.2.0. The full list of published tags is on Docker Hub.
The embedded PostgreSQL listens only on localhost inside the container and is never exposed externally. If you omit POSTGRES_PASSWORD it defaults to tymeslot, which is fine for the embedded database. Set a strong password only when pointing Tymeslot at an external database via DATABASE_HOST.

Becoming an admin

The first user to register on a fresh install is automatically promoted to admin. To promote additional users — or recover access if no admin exists — run the release helper from inside the container:
docker exec -it tymeslot bin/tymeslot rpc 'Tymeslot.Release.promote_admin("you@example.com")'
The user must already have an account. To demote an admin or list all current admins, see ADMIN.md.

Common commands

# Stream logs
docker logs -f tymeslot

# Stop the container
docker stop tymeslot

# Start a stopped container
docker start tymeslot

# Restart
docker restart tymeslot

# Open a bash shell
docker exec -it tymeslot /bin/bash

# Open an Elixir remote console
docker exec -it tymeslot bin/tymeslot remote

# Remove the container (volumes are preserved)
docker stop tymeslot && docker rm tymeslot

Troubleshooting

Check the logs first — they usually tell you exactly what’s wrong:
docker logs tymeslot
Common causes:
  • SECRET_KEY_BASE is missing or fewer than 64 characters
  • Port 4000 is already in use on the host
  • Insufficient disk space
Verify your configuration variables:
source .env
echo "SECRET_KEY_BASE length: ${#SECRET_KEY_BASE}"  # Should be >= 64
echo "PHX_HOST: $PHX_HOST"
echo "POSTGRES_PASSWORD set: $([ -n "$POSTGRES_PASSWORD" ] && echo 'Yes' || echo 'No')"
The container needs 30–60 seconds to initialise on first run. Watch the logs and wait for Running TymeslotWeb.Endpoint:
docker logs -f tymeslot
If you see that line but the browser still can’t connect, check that you’re using the right port (default 4000) and that no firewall rule is blocking it.
Check that PostgreSQL is running inside the container:
docker exec -it tymeslot ps aux | grep postgres
Verify the database connection:
docker exec -it tymeslot su - postgres -c "psql -U $POSTGRES_USER -d $POSTGRES_DB -c 'SELECT version();'"
To reset the database entirely (destroys all data — stop the container first, as the volume can’t be removed while in use):
docker rm -f tymeslot
docker volume rm tymeslot_pg
This error appears on first start when the PostgreSQL volume is bind-mounted at /var/lib/postgresql/data with ownership the container can’t change. It’s common on Docker Desktop, rootless Docker, and SELinux-enforcing hosts.Fixes in order of preference:
  1. Use the named volume from the quick-start (-v tymeslot_pg:/var/lib/postgresql/data). Named volumes live inside Docker’s own storage and are immune to host filesystem ownership quirks.
  2. If you need the data on a specific host path, run PostgreSQL externally and point Tymeslot at it with DATABASE_HOST.
  3. If a previous first-run attempt crashed, remove the partially-initialised volume before retrying: docker volume rm tymeslot_pg.
Find what’s occupying port 4000:
sudo lsof -i :4000
Either stop the conflicting service, or change the port Tymeslot listens on:
# In your .env file or -e flag:
PORT=8080
Then update your docker run command accordingly: -p 8080:8080.

Data-at-rest encryption

Integration credentials (calendar tokens, CalDAV passwords, video API keys) are encrypted at rest. By default the encryption key is derived from SECRET_KEY_BASE, which means rotating your session secret would make stored credentials unreadable. Setting a dedicated DATA_ENCRYPTION_KEY decouples the two so you can rotate SECRET_KEY_BASE freely.
# Add to your .env (generate once, keep stable forever)
DATA_ENCRYPTION_KEY=$(openssl rand -base64 48 | tr -d '\n')
See Data-at-Rest Encryption for full details, including how to migrate existing credentials onto the new key.

Next steps

  • Configure email — test password reset to verify delivery is working. See Email Configuration.
  • Set up a reverse proxy — see the Reverse Proxy Setup guide for Nginx and Caddy walkthroughs with SSL.
  • Connect calendar integrations — Google Calendar and Outlook from Dashboard → Integrations.
  • Full environment variable reference — every supported variable with annotations lives in the Environment Variables reference.

Build docs developers (and LLMs) love