Troubleshooting
This page covers common issues you might encounter when self-hosting solyto and how to resolve them.
Checking logs
Section titled “Checking logs”The first step in debugging any issue is checking the container logs:
# All servicesdocker compose logs
# A specific servicedocker compose logs apidocker compose logs appdocker compose logs nginx
# Follow logs in real timedocker compose logs -f apiLogs are your best friend. Most errors are explained in the output.
Container won’t start
Section titled “Container won’t start”Symptoms: docker compose ps shows a service restarting or exited.
Checks:
- View the logs for the failing service:
docker compose logs <service> - Verify
.envhas all required variables — see Configuration - Verify all required secret files exist in
./secrets/— see Docker Secrets - Check that Docker has enough resources (memory, disk space)
Common cause: missing or empty secret file. Check with:
ls -la secrets/Database connection errors
Section titled “Database connection errors”Symptoms: API returns 500 errors, logs show SQLSTATE or Connection refused.
Checks:
- Is the database running?
docker compose ps mariadbanddocker compose ps postgres - Check credentials match between
.envand secret files:Terminal window cat secrets/db_usercat secrets/db_password - Ensure
DB_HOST=mariadbandDAV_DB_HOST=postgres(Docker service names) - Wait — MariaDB and PostgreSQL can take a few seconds to be ready on first start. The API container will retry.
Reset database credentials (if corrupted):
# Regenerate the secret fileopenssl rand -hex 32 > secrets/db_passworddocker compose up -d mariadb# Wait for MariaDB to start, then restart APIdocker compose restart api queueTLS certificate issues
Section titled “TLS certificate issues”Symptoms: Browser shows security warning, Traefik certificate errors.
Checks:
- Verify your domains resolve to the server IP:
dig api.example.com - Ensure ports 80 and 443 are open and not blocked by a firewall
- Check that
ACME_EMAILis set in.env - Verify the
traefik_acmevolume exists and is writable
Force certificate renewal:
docker compose downdocker volume rm <project>_traefik_acmedocker compose up -dReplace <project> with your PROJECT_NAME. Traefik will request new certificates on startup.
Permission problems with storage/
Section titled “Permission problems with storage/”Symptoms: File uploads fail, logs show Permission denied in storage/.
Fix:
chown -R www-data:www-data storage/chmod -R 775 storage/The storage/ directory is shared between api, dav, queue, nginx, and imgproxy via a bind mount. All of these need write access.
CalDAV/CardDAV not working
Section titled “CalDAV/CardDAV not working”Symptoms: Calendar or contact sync fails in external apps (DAVx5, Apple Calendar, etc.).
Checks:
- Verify the
davservice is running:docker compose ps dav - Ensure
DAV_DOMAINis set and resolving correctly - Check that the CalDAV/CardDAV URL your external app uses matches
https://dav.example.com - Check
davservice logs:docker compose logs dav - Verify PostgreSQL is running:
docker compose ps postgres - Ensure
dav_db_useranddav_db_passwordsecrets are correct
Common issue: The DAV domain must be different from the API domain. They run as separate services behind Traefik.
Queue not processing
Section titled “Queue not processing”Symptoms: Async tasks don’t complete (notifications, background jobs).
Checks:
- Is the queue worker running?
docker compose ps queue - Check queue logs:
docker compose logs queue - Verify Redis is running:
docker compose ps redis - Check Redis connectivity:
docker compose exec api so tinkerthen try a Redis command
Restart the queue worker:
docker compose restart queueImages not loading
Section titled “Images not loading”Symptoms: Uploaded profile images or other media return 404 or broken.
Checks:
- If using
IMAGE_DRIVER=intervention(default), no extra service is needed - If using
IMAGE_DRIVER=imgproxy, ensure theimgproxyservice is running andimgproxy_key/imgproxy_saltsecrets are set - Check
storage/app/public/exists and is writable - Check nginx logs:
docker compose logs nginx
Healthcheck failures
Section titled “Healthcheck failures”The nginx service has a healthcheck on /api/v1/health. If it’s failing:
- Test manually:
curl -s https://api.example.com/api/v1/health - If the API is not responding, check
apicontainer logs - If the database is down, the healthcheck will fail — resolve the database issue first
Getting help
Section titled “Getting help”If you can’t resolve an issue:
- Search existing issues on the selfhosted repo
- Submit a new issue with your logs (redact any secrets first)
- Check the Dev Requests board if you’re using solyto.app