Skip to content
OpenPostDocs
OpenPostDocs

Maintenance

Back up, upgrade, monitor, and recover a self-hosted instance.

The database holds accounts, schedules, and post state. The media directory holds uploaded files. Back up both with the Compose file and .env; the latter contains the JWT and encryption secrets needed to read saved credentials. Keep backups private and off the server, and test a restore before relying on them.

Back up from the web app

Instance administrators can create and restore a backup without using a terminal. Open Settings → Instance → Backup and restore.

  • Download a backup creates one ZIP file with a consistent snapshot of the database and every uploaded media file. The server keeps running.
  • Restore from a backup checks the uploaded file first and changes nothing until you type restore to confirm. The server then restarts and replaces its data. The data it replaced stays in a pre-restore-* folder next to the database, listed on the same page, so you can go back. Delete these copies when you no longer need them.

The ZIP contains private instance data, including API tokens and session records. Store it securely. It does not contain environment variables, the Compose file, external services, or OPENPOST_ENCRYPTION_KEY. A restore is refused when the key differs, because saved provider credentials would be unreadable. Keep .env with your backups.

Export temporarily copies the database and local media next to the database before sending the ZIP. Restore needs space for the uploaded archive, its extracted contents, and a complete copy of the data being replaced. Allow free disk space for these copies. Uploads and media deletion wait while export captures its private copy; downloads do not hold that lock.

Uploading alone never schedules a restore. You can leave the page or restart the server before confirmation without replacing current data. Once confirmed, leave the server running until its restart completes. If installation is interrupted, the next start recovers the previous database and media and requires confirmation again. Check the server logs if startup fails; recovery files are retained.

To recover a saved restore point manually, stop the server first. Preserve the current database and media separately. In the chosen pre-restore-* folder, copy database to your configured SQLite filename, copy database-wal and database-shm to that filename with -wal and -shm suffixes if present, and replace the contents of your configured media directory with the folder's media/ contents. Remove current SQLite sidecars before copying the saved ones. Remove any restore-pending/ folder before starting again so a confirmed restore cannot override this recovery. Start the server and verify a saved post and its media. These folders are recovery copies, not downloadable ZIP backups.

This feature needs the default SQLite database, local media storage, and a server that runs as a single process. It also needs a container restart policy such as the unless-stopped policy in the Compose file. Other setups keep using the manual steps below.

Back up the SQLite setup

For the Compose guide's ./data bind mount, run these commands from the directory containing docker-compose.yml. Stop OpenPost so the SQLite copy is consistent. Record the image tag and create an archive:

docker compose stop openpost
tar -czf "openpost-backup-$(date +%Y%m%d-%H%M%S).tar.gz" data .env docker-compose.yml
docker compose start openpost

Check that the archive opens with tar -tzf openpost-backup-YYYYMMDD-HHMMSS.tar.gz, replacing the name with your new file. Copy it to private storage outside this server. It contains account data and secrets. If you use PostgreSQL or S3 storage, back up those services with their own consistent backup tools as well.

The repository's docker-compose.yml and platform recipes use an openpost_data named volume instead of ./data. Back up that volume with the Compose file, environment values, and image tag. Follow your platform guide for its storage location and backup steps. The archive command above does not include a named volume.

Upgrade

Back up first. Change the image: value in docker-compose.yml to the release tag you intend to run, then pull and start it:

docker compose pull openpost
docker compose up -d openpost
curl -fsS http://localhost:8080/api/v1/ready
docker compose logs --tail=100 openpost

The self-hosted all container applies database migrations at startup. If you need to return to the previous image, restore its matching database backup too. An older binary may not understand a newer database schema.

Restore

On a replacement server, install Docker Compose and restore the data using the same storage layout. Extract the bind-mount archive into an empty directory, or restore the named volume from its volume backup before starting OpenPost. Check the image tag and paths in docker-compose.yml, and restore the same .env secrets. Start with docker compose up -d, check /api/v1/ready, sign in, open a saved post with media, and inspect a scheduled post. Reconnect any provider whose external app or token was revoked since the backup.

Check health

curl https://your-openpost-host.example/api/v1/health
curl https://your-openpost-host.example/api/v1/ready

/health shows that the process responds; /ready checks whether it can serve work with its required dependencies. Check readiness after every restart and from outside the reverse proxy. For a failed post, open the affected variant, fix its provider or media issue, and retry it. For a failed startup, check the logs, database connection, writable media directory, disk space, and original secrets.

On this page