Skip to main content
This guide will help you deploy a production-ready Skald instance on your own infrastructure. Spinning up the complete stack so that you have Skald live on domains that you own with SSL certificates should realistically take less than half-an-hour, but that’s with Postgres and RabbitMQ running in Docker. These should ideally be deployed externally and of course configuring those will take more time.

Pre-requisites

  1. A Linux server (x86) with Docker and Docker Compose installed
  2. Two domain names (or subdomains) pointing to your server’s IP address:
    • One for the API (e.g., api.yourdomain.com)
    • One for the UI (e.g., app.yourdomain.com)
  3. Ports 80 and 443 open on your server
The last step is easy to forget! Do it right when you spin up your instance to prevent yourself from spending time debugging later.

DNS Configuration

Before running the deployment, ensure the following DNS records are configured:
  1. Create an A record for your API domain pointing to your server’s IP address
  2. Create an A record for your UI domain pointing to your server’s IP address
Example DNS configuration:
skald-api.yourdomain.com    A    123.456.789.0
skald.yourdomain.com        A    123.456.789.0
If you are using CloudFlare to manage your DNS, make sure to disable the ‘Proxied’ option. A proxied record will not work with our Traefik configuration.

Deployment

Clone the Skald repo:
git clone https://github.com/skaldlabs/skald
And then from inside the directory, run the deployment setup script:
./bin/deploy.sh
The script will:
  1. Prompt you for your API and UI domain names.
  2. Request an email address (required for Let’s Encrypt SSL certificates).
  3. Prompt you for the environment variables required to run Skald (e.g. API keys). Check out the Configuration section on the Intro page if you want to understand these better.
  4. Verify your DNS configuration.
  5. Generate secure credentials (e.g. Django’s SECRET_KEY, Postgres password).
  6. Set up a .env.prod file to be used when deploying the stack.
After you’re done with the setup, run the following command to start the stack in detached mode:
docker compose -f docker-compose.selfhosted.yml --env-file .env.prod up -d

Managing Your Deployment

View logs

docker compose -f docker-compose.selfhosted.yml logs -f
View logs for a specific service:
docker compose -f docker-compose.selfhosted.yml logs -f api

Stop the deployment

docker compose -f docker-compose.selfhosted.yml down

Restart the deployment

docker compose -f docker-compose.selfhosted.yml --env-file .env.prod up -d

Update the deployment

To update to the latest version:
# Pull the latest images from DockerHub
docker compose -f docker-compose.selfhosted.yml --env-file .env.prod pull

# Restart services with the new images
docker compose -f docker-compose.selfhosted.yml --env-file .env.prod up -d

What Gets Deployed

The deployment includes:
  • Traefik: Reverse proxy with automatic SSL certificate generation.
  • PostgreSQL with pgvector: Our database. pgvector support is needed for vector embeddings.
  • RabbitMQ: Used for communicating between the Django server and the Memo Processing Server.
  • API: The main Skald API Django server.
  • Memo Processing Server: Background worker for processing memos.
  • UI: The web interface.

Configuration

All configuration is stored in .env.prod, which is automatically generated by the deployment script. This file contains:
  • Domain names
  • Database credentials
  • API keys
  • Security secrets

SSL Certificates

SSL certificates are automatically generated and renewed by Let’s Encrypt through Traefik. The certificates are stored in a Docker volume (traefik-certificates) and will auto-renew before expiration.

Troubleshooting

SSL certificate issues

If you’re having trouble with SSL certificates:
  1. Ensure ports 80 and 443 are open
  2. Verify DNS records are pointing to the correct IP
  3. Check Traefik logs: docker compose -f docker-compose.selfhosted.yml logs traefik
  4. Wait a few minutes — certificate generation can take some time

Service won’t start

  1. Check service logs: docker compose -f docker-compose.selfhosted.yml logs <service-name>
  2. Ensure all required environment variables are set in .env.prod

Cannot connect to API

  1. Verify DNS is resolving correctly: dig your-api-domain.com
  2. Check API logs: docker compose -f docker-compose.selfhosted.yml logs api
  3. Ensure Traefik is running: docker compose -f docker-compose.selfhosted.yml ps traefik

Backups

To backup your data (if you’re not using an external Postgres deployment), you can run the following command (or set it to run on a cron):
docker run --rm -v skald2_postgres_data:/data -v $(pwd):/backup ubuntu tar czf /backup/postgres-backup.tar.gz /data
To restore:
docker run --rm -v skald2_postgres_data:/data -v $(pwd):/backup ubuntu tar xzf /backup/postgres-backup.tar.gz -C /
I