Install Berth with Docker
Updated October 27, 2026
Berth is one container, ghcr.io/joveptesg/berth, built for amd64 and arm64. It runs on a Linux server or VPS, a NAS or a Raspberry Pi and keeps everything in one data folder. Setup takes a few minutes.
What you need
- Docker with Compose, or a NAS that can run a container image (Synology, Unraid, CasaOS).
- An amd64 or arm64 machine — a Raspberry Pi or an ARM NAS works.
- A folder on a local disk for
./data. Do not put it on a network share (NFS, SMB): SQLite there can corrupt the database.
Run with Docker Compose
./data holds the database, its backups, the local storage and secret.key.
mkdir berth && cd berth
curl -fsSLO https://raw.githubusercontent.com/joveptesg/berth/main/docker-compose.yml
docker compose up -d # http://localhost:8080, data in ./data
docker compose logs berth # the setup code is in the logKeep a copy of secret.key apart from the backups: storage keys in the database cannot be read without it.
First setup in the browser
- Open the server address in a browser:
http://<server>:8080, or the domain your hosting assigned. - Find the setup code in the log, in the line
server is not set up: … enter the setup code K7P2-9QXM. It changes on every restart until setup is done. - Enter the code and create the administrator. The address you opened becomes the home or internet address in the phone QR codes; you can change it later under Settings → Server.
- Upload the first book: drag a folder or a file into the admin. Berth reads tags, chapters and the cover; check them and add the book to the library.
Plain Docker, NAS and Raspberry Pi
For plain Docker or a NAS interface that asks for an image name:
- In a NAS interface (Synology Container Manager, Unraid, CasaOS): image
ghcr.io/joveptesg/berth:1, port8080, a folder mounted at/data. - On a Raspberry Pi the same commands work: the arm64 image is pulled automatically.
docker run -d --name berth --restart unless-stopped \
-p 8080:8080 -v "$PWD/data:/data" ghcr.io/joveptesg/berth:1
docker logs berth # the setup code is in the logUpdating and rolling back
The 1 tag follows all 1.x releases; 1.0 follows fixes of 1.0, and an exact tag like 1.0.1 never changes. Avoid latest with auto-updaters such as Watchtower: it also follows new major versions.
Before a new version changes the database schema, it saves a copy to ./data/backups (the last 3 are kept). To roll back, pin the previous version in docker-compose.yml and restore that copy:
docker compose stop berthdocker compose run --rm berth admin restore /data/backups/auto-<time>.sqlitedocker compose up -d
docker compose pull && docker compose up -dAccess from the internet
Berth serves plain HTTP, which is enough at home. For access from outside, put a reverse proxy with HTTPS in front, for example Caddy:
books.example.com {
reverse_proxy localhost:8080
}Then enter https://books.example.com in the admin under Settings → Internet address, so the QR codes for phones include it. The app switches between the home and internet addresses by itself.
Backups
- Settings → Backup in the admin downloads a copy of the database and restores one, from an automatic backup or an uploaded file. The current database is saved first, so a restore can be undone.
- With S3 storage, the server can also put a daily copy of the database into the bucket — away from the disk the database lives on.
- From the console, with the server stopped:
berth admin restore <file>.
Questions
Which port does Berth use?
8080 inside the container. Publish it on any host port you like, e.g. -p 9000:8080.
Where are my books stored?
By default in the local storage inside ./data. You can add S3-compatible storage later in the admin and make it the default for new books. See S3 storage.
Can I build Berth from source?
Yes: in a clone of the repository, uncomment build: . in docker-compose.yml and run docker compose up -d --build.