Skip to Content
⚠️Active Development Notice: TimeTiles is under active development. Information may be placeholder content or not up-to-date.
Self-HostingMaintenance

Maintenance

Backups, updates, monitoring, and troubleshooting for production instances.

Backups

TimeTiles uses restic  for encrypted, deduplicated backups with optional S3 offsite storage.

Commands

timetiles backup # Full backup (database + uploads) timetiles backup --offsite # Full backup with S3 sync timetiles backup db # Database only timetiles backup uploads # Uploads only timetiles backup list # List snapshots timetiles backup verify # Verify integrity timetiles backup prune # Apply retention policy timetiles backup auto # Set up daily cron job

timetiles backup writes two snapshots, not one: a db-tagged snapshot and an uploads-tagged snapshot. This matters for recovery — see below.

Restore

Restore operates on one snapshot at a time, and each snapshot holds either the database or the uploads. A full recovery is therefore two commands.

timetiles backup list # Find the snapshot IDs and their tags timetiles restore abc123 # Restore that snapshot timetiles restore abc123 --offsite # Restore it from S3

Full disaster recovery

# 1. List snapshots and note the newest `db` id and the newest `uploads` id timetiles backup list # 2. Restore the database timetiles restore <newest-db-id> # 3. Restore the uploads timetiles restore <newest-uploads-id>

Do not use timetiles restore latest for disaster recovery. latest resolves to the newest snapshot of any tag, and because a full backup writes the database first and the uploads second, that is always the uploads snapshot. It restores your files and leaves the database exactly as it was — which on a rebuilt host means empty. The command reports which half it restored (Restore complete! Restored: uploads); read that line, it is the only signal that the database was not touched.

timetiles restore with no arguments lists the available snapshots, same as timetiles backup list.

Offsite Storage (S3)

Configure in .env.production:

RESTIC_OFFSITE_REPOSITORY=s3:s3.amazonaws.com/your-bucket/timetiles AWS_ACCESS_KEY_ID=your-key AWS_SECRET_ACCESS_KEY=your-secret

For write-only credentials (recommended), use S3 lifecycle rules to expire old backups instead of timetiles backup prune.

Retention Policy

Default retention: 7 daily, 4 weekly, 12 monthly. All backups are encrypted with RESTIC_PASSWORD.

Updates

# 1. Back up first timetiles backup # 2. Pull latest images and redeploy timetiles update # 3. Verify curl https://your-domain.com/api/health

Database migrations run automatically on container startup — no manual intervention needed.

Monitoring

Health Checks

# Application health curl https://your-domain.com/api/health # Container status timetiles status # Live logs timetiles logs -f

Recommended schedule: health endpoint every 5 minutes, service status hourly, log review daily.

Resource Usage

# Container CPU and memory docker stats # Database size docker compose -f deployment/docker-compose.prod.yml exec postgres \ psql -U timetiles_user -d timetiles -c \ "SELECT pg_size_pretty(pg_database_size('timetiles'));" # Disk space df -h

Log Management

All containers use JSON logging with 50 MB max per file, 5 files retained.

timetiles logs web # Web application logs timetiles logs worker-ingest # Import worker logs timetiles logs postgres # Database logs timetiles logs nginx # Reverse proxy logs

Database Maintenance

Run weekly for optimal performance:

-- Connect: docker compose exec postgres psql -U timetiles_user timetiles VACUUM ANALYZE;

Slow Query Debugging

CREATE EXTENSION IF NOT EXISTS pg_stat_statements; SELECT mean_exec_time, calls, query FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;

SSL Certificates

Certificates auto-renew every 12 hours via the certbot container. Verify monthly:

# Check certificate status timetiles logs certbot # Force renewal if needed docker compose -f deployment/docker-compose.prod.yml exec certbot certbot renew --force-renewal docker compose -f deployment/docker-compose.prod.yml restart nginx

Health Check

TimeTiles exposes a health endpoint for monitoring and load balancer integration:

curl https://your-instance.com/api/health

Returns 200 when the system is healthy. Use this for Docker health checks or uptime monitoring (e.g., UptimeRobot , Gatus ).

Troubleshooting

ProblemDiagnosisSolution
App won’t starttimetiles logs webCheck DATABASE_URL and PAYLOAD_SECRET in .env.production
Imports stuckCheck /dashboard/payload-jobsWorkers may be down — timetiles restart worker-ingest
High memorydocker statsRestart: timetiles restart web. If persistent, set NODE_OPTIONS="--max-old-space-size=4096"
SSL expiredtimetiles logs certbotDNS must resolve to your server. Force renewal (see above)
Disk fulldf -h and docker system dfPrune Docker: docker system prune. Prune backups: timetiles backup prune
Slow queriesEnable pg_stat_statementsAdd indexes, run VACUUM ANALYZE, check PostGIS query plans

Debug Mode

# Enable detailed logging # Edit deployment/.env.production: LOG_LEVEL=debug timetiles restart timetiles logs -f web

Next Steps

Last updated on