Update Silo safely
Silo is in active development before 1.0. These guides are updated frequently.
Update during a quiet period and tell users that playback will stop briefly.
Before you update
Section titled “Before you update”-
Read the release notes for the version you are moving to, including anything about remote nodes and plugins.
-
Back up the database,
.env, and data directories, and record the image you are running:Terminal window docker compose images siloKeep that output.
latestwon’t identify the old image once you’ve pulled a new one. -
Let active playback and downloads finish.
-
If
docker compose pslistspostgresandredisbesidesilo, read If your server runs PostgreSQL and Redis in their own containers first.
Update with Docker Compose
Section titled “Update with Docker Compose”Published images are tagged latest, build-N, and the full commit SHA (see image tags). If you pinned the image in .env with SILO_OMNIBUS_IMAGE, or SILO_IMAGE with separate containers, change it to the new tag first. Keep your existing .env; don’t replace it with the latest example.
From the directory that holds your Compose file:
docker compose pull silodocker compose up -d --no-deps silodocker compose logs -f siloRecreating the container restarts the PostgreSQL and Redis inside it along with Silo. With separate containers, --no-deps replaces only the Silo container and leaves PostgreSQL and Redis running.
With docker run, pull the new image, then remove the container and start it again with the same command:
docker pull ghcr.io/silo-server/silo-server:latestdocker stop silo && docker rm siloSilo applies database migrations as it starts, before it answers requests. A large migration can take a while, and docker compose ps can show Silo as unhealthy until it finishes. Watch the logs and don’t restart the container during a migration: that abandons the run, and the next start can wait while PostgreSQL still holds the abandoned run’s locks.
Migrations stop after 20 minutes by default. For a very large library, or when the release notes say a migration rewrites large tables, set a longer limit in .env before updating, for example SILO_MIGRATE_TIMEOUT=60m. 0 removes the limit. A table rewrite also needs free space on the database disk for a second copy of each rewritten table and its indexes, so check it before updating.
After the update
Section titled “After the update”- Check health and readiness.
- Sign in as an admin and as a normal account.
- Open a library, load artwork, start playback, seek, stop, and resume.
- Test the integrations and remote nodes you use.
Keep the backup until these checks pass.
If an update moves the bundled Meilisearch to a new version and it doesn’t start, set MEILI_UPGRADE_DB=true in .env for one start, then remove it. A move to a new PostgreSQL major version needs a dump and restore; see Bundled PostgreSQL.
An update doesn’t change your Compose file. If yours is older than the NET_ADMIN capability line, Silo runs without it. If the kernel’s send limit is low, Silo logs a tcp send buffer: listener state warning on each start, with how to fix it. The warning doesn’t stop Silo. Before you add the line, read what the capability allows.
If the update fails
Section titled “If the update fails”Stop and keep the logs. Switching back to the old image doesn’t undo migrations, so don’t alternate old and new images against the same database.
To see which migrations ran:
docker compose exec silo /command/s6-envdir /run/s6/container_environment \ /command/s6-setuidgid silo silo --migrate-statusThe reliable way back is to restore the pre-update backup with the old image, as in Test a restore. For a build from before PostgreSQL and Redis moved into the image, pin its build-N-aio tag. That loses every change made after the backup. Ask for help before changing the database by hand.
If your server runs PostgreSQL and Redis in their own containers
Section titled “If your server runs PostgreSQL and Redis in their own containers”Servers installed before Silo moved to one container run PostgreSQL, Redis, and optionally Meilisearch in containers of their own. Silo’s image now bundles those services, and with your Compose file it leaves them off and keeps using your containers and data. It does change two things for Silo itself: it runs as the account PUID and PGID name instead of root, and on its first start it gives the plugins, artwork, compat, transcode, and download-artifacts directories to that account. Before your next update:
- Set
PUIDandPGIDin.envto an account that can read your media, such as the one that owns it.id -uandid -gprint your own. Without them, Silo runs as uid911. - If your Compose file sets
user:on thesiloservice, remove it. The container has to start as root to switch to that account. - Keep your Compose file. If you replace it with the repository’s current files, for example with
git pullin a clone, usedocker-compose.advanced.yml: setCOMPOSE_FILE=docker-compose.advanced.ymlin.env, and carry over your own changes, such as GPU lines.
After the update, check that your libraries still scan. A library whose folders the new account can’t read stays as it was, and the log names the folder.
Move into one container
Section titled “Move into one container”A command in the image moves a server with separate containers into the single container. It copies the database, links Silo’s directories into config/silo, and leaves the old directories as they were, so the old Compose file still starts on them. Redis and Meilisearch data stay behind: Silo doesn’t need Redis’s data, and it builds a new search index.
Before you move, back up the server, then prepare the directory that holds your Compose file:
- Download the repository’s
docker-compose.ymlanddocker-compose.advanced.ymlthere, and carry over your own changes, such as GPU lines. - In
.env, setPUIDandPGIDas described above. Remove anyDATABASE_URL,REDIS_URL,SILO_SEARCH_PROVIDER,SILO_MEILISEARCH_URL, andSILO_MEILISEARCH_API_KEYlines that point at the old containers. To keep using Meilisearch, setENABLE_MEILISEARCH=true. - If
.envpinsSILO_IMAGE, remove that line to followlatest, or setSILO_OMNIBUS_IMAGEto the image to run. For a build from before Silo moved to one container, that’s itsbuild-N-aiotag. - Remove anything in
docker-compose.override.ymlthat changes thepostgres,redis, ormeilisearchservices. Compose rejectsdocker-compose.ymlwhile the override still names them. - If you use transcode or proxy nodes, turn on node access in
.envand uncomment its port lines.
Remove COMPOSE_FILE from .env if you set it. Then stop the old containers and run the move, with your SILO_DATA_ROOT in place of /opt/silo:
docker compose -f docker-compose.advanced.yml down &&docker compose run --rm -v /opt/silo:/silo-data \ --entrypoint /etc/silo-omnibus/migrate-compose-stack silo &&docker compose up -dThe command checks the install before it copies anything. If something is in the way, such as a setting from step 2 or too little free space for a second copy of the database, it stops with a message that says what to change, and Silo doesn’t start. Fix it and run the commands again. Running it again after a successful move reports that there is nothing to do.
The first start rebuilds some database indexes, so it takes longer on a large library. Sign in with your usual account and check your libraries, artwork, watch progress, and playback.
To go back, run docker compose down, set COMPOSE_FILE=docker-compose.advanced.yml again, and run docker compose up -d. The single container’s copy is then out of date. To move again later, move the config directory aside first. Once the single container works, delete the old postgres, redis, meilisearch, plugins, artwork, and compat directories yourself.
Moving from alpha to 1.0
Section titled “Moving from alpha to 1.0”Existing alpha servers will update in two steps: first to a final bridge release, then to 1.0. The bridge finishes the older database migrations, and 1.0 refuses to start on a database that hasn’t reached it. When 1.0 ships, follow its published update instructions. The plan is in the server’s 1.0 update notes.
What to expect:
- Plan one maintenance window for the whole setup. Don’t run alpha and 1.0 servers or nodes at the same time.
- Have the matching 1.0 app builds ready for your devices.
- Playback, download, callback, and integration URLs created by the alpha server stop working. Create new ones from the 1.0 server and update external services such as autoscan and webhook senders. Don’t edit old URLs by hand.
- Health checks keep their addresses,
/api/v1/healthand/api/v1/ready.