Check these first
Four checks, in this order. They resolve most problems before you have to think hard about any of them.
- Read the logs.
docker compose logs -f servicename. The answer is in there far more often than people expect, and reading it takes less time than guessing. - Check the container is not just pretending.
docker compose psshowingUponly means the process started. A container can be running while the application inside it is wedged, waiting on a database that never came up. - Check what it depends on. If an app needs PostgreSQL or Redis, look at those first. An app that cannot reach its database usually reports something vague about its own startup rather than naming the database.
- Check the URL variable. Half of all "it loads but nothing works" reports are an app that does not know its own address. APP_URL, PAPERLESS_URL, ROOT_URL, PUBLIC_URL, SERVER_URL. Different name in every app, same problem.
Permissions
Permission errors are the most common first-run failure, and the error message rarely says "permissions".
What you usually see instead: the app starts and immediately exits, or it starts and reports that it cannot write to a directory, or it comes up with an empty database every restart.
The cause is a mismatch between the user inside the container and the owner of your bind-mount directory. Two fixes, depending on the image:
- Images with PUID and PGID, which includes everything from
LinuxServer: set them to your own IDs from
id -uandid -g. - Images with a fixed internal user: change the directory
to match. PsiTransfer is the clearest case on this site. Upstream requires
its data volume to be owned by UID 1000, so
chown -R 1000 ./databefore the first start.
Port clashes
Two services wanting the same host port will not start, and the error names the port rather than the app, which is why it reads as mysterious.
The clash you will hit is port 3000. On this site alone, Forgejo, Gogs, CryptPad, PairDrop, PsiTransfer, Zipline and OpenSign's client all default to it. Port 8080 is the second most crowded.
Find out what is holding a port with docker compose ps, or on
the host with ss -tulpn | grep 3000.
"4000:8080" the left number is yours to pick
freely. The right number is what the application listens on inside the
container, and changing it usually requires also changing a configuration
variable. The Generator assigns unique host
ports so this does not come up.Remember that other containers do not use your host port. They reach the service on its container port by service name. Publishing a port is for you, not for them, and a database needs no published port at all.
Upgrade traps
The generic advice is on the Guide: pin major versions, read release notes, take a backup. These are the traps specific to modules on this site.
| Module | What bites |
|---|---|
| Wiki.js | Pulling latest moves you toward version 3, which upstream says is an unstable beta not for production. Pin :2 |
| Dashy | v3 moved config to /app/user-data and the port from 80 to 8080. v4 removed the build-and-start entrypoint |
| Zipline | v3 to v4 is a rewrite with no in-place upgrade. Variables were renamed: CORE_DATABASE_URL to DATABASE_URL, CORE_HOST to CORE_HOSTNAME |
| Huly | 0.6 to 0.7 needs upstream's dedicated migration steps, not a pull |
| Homarr | The v1 rewrite required manual reconfiguration |
| PdfDing | The GitHub repo is archived. Development moved to Codeberg |
Getting your data back out
Every module on this site has a way out. Knowing which one, before you need it, is the difference between switching tools and being stuck.
- Paperless-ngx
- Document export, which writes originals plus metadata to the export volume
- Docspell
- Documents remain in its storage, with a documented API for bulk retrieval
- BookStack and Wiki.js
- Content export. Wiki.js can also keep everything mirrored to Git continuously
- Forgejo and Gogs
- Git repositories are already portable. Clone them. Issues need the API
- Wekan
- Board export as JSON, attachments included
- PdfDing
- The PDFs are files on disk in your media directory
- Kiwix
- The ZIM files are yours already
- CryptPad
- Export per document. The server cannot do it for you, by design
Test one export while everything is working. An export path you have never run is a claim, not a plan.