How to Self-Host Grocy in 2026: Inventory Data, Timezone and Backups
Self-host Grocy with correct ports, persistent storage, HTTPS, secrets, backups and upgrade checks. Learn how to fix when the SQLite database cannot write.
Treat Grocy as a small system, not a Docker image. The user-facing goal for Grocy is clear: household inventory, groceries, chores and equipment tracking; the deployment is acceptable only when you can replace the default login, add a product, record a purchase and consumption, scan a barcode and trigger a chore or expiry reminder.
That distinction catches the failure mode operators meet after local testing: the SQLite database cannot write or scheduled chores use the wrong timezone. It also makes the backup and upgrade plan specific enough to test.
Ports, processes and private services
A useful Grocy diagram shows the public route, private port 80, state boundary and every supporting requirement. Mark which arrows carry credentials and which are ordinary user traffic. The local runtime requirement is one durable config volume and optional barcode-device access. Size and monitor that resource with the container instead of exposing an unrelated network service.
Prove the diagram with one real action: replace the default login, add a product, record a purchase and consumption, scan a barcode and trigger a chore or expiry reminder. The likely pressure comes from SQLite writes, uploaded images, scheduled jobs and household-device traffic; monitor that path rather than treating all HTTP requests as equal.
Watch the workload, not only the container
Observe the work Grocy performs: SQLite writes, uploaded images, scheduled jobs and household-device traffic. Set limits with headroom for that work and avoid a liveness probe that competes with it. The operator check should still attempt to replace the default login, add a product, record a purchase and consumption, scan a barcode and trigger a chore or expiry reminder on a schedule.
For updates, remember that Grocy database migrations and custom extensions should be rehearsed on a copied config directory. Deploy the candidate against a recovered copy and repeat the known test. If the SQLite database cannot write or scheduled chores use the wrong timezone, use runtime logs and the actual network request to find which assumption changed.
What must pass before real Grocy data arrives
A production gate for Grocy should be executable by someone who did not build the deployment. Give that person the pinned version, a non-sensitive test account and this task: replace the default login, add a product, record a purchase and consumption, scan a barcode and trigger a chore or expiry reminder. If the instructions require undocumented shell access, the service is not yet operationally ready.
Repeat the gate after replacing only the container. Then restore database, uploaded files, recipes and configuration into blank infrastructure and prove that stock, recipes, chores, equipment and history return and the next scheduled reminder has the correct date. Measure SQLite writes, uploaded images, scheduled jobs and household-device traffic during both successful runs; unexpected differences often reveal a missing cache, index, worker or data mount.
Add a failure drill: submit harmless input near the resource or format limit associated with this boundary: the SQLite database cannot write or scheduled chores use the wrong timezone. Grocy should emit a useful error, preserve existing state and recover when the valid condition returns. Save the timestamps and relevant log lines, with secrets redacted. That evidence becomes the reference for the next image or configuration change.
Build a replaceable Grocy container
Use a command that exposes every important choice. This baseline binds Grocy to host loopback, adds the known data mounts and supplies the first required setting. Confirm the local requirement before exposure: one durable config volume and optional barcode-device access.
docker run -d \
--name grocy \
--restart unless-stopped \
-p 127.0.0.1:80:80 \
-v grocy-data:/config \
lscr.io/linuxserver/grocy:latest
Replace floating tags with a tested version or digest. After startup, inspect docker logs --tail 200 grocy and confirm the process listens on 80. Then execute the Grocy acceptance action; a root-page response cannot prove the full scenario succeeds: replace the default login, add a product, record a purchase and consumption, scan a barcode and trigger a chore or expiry reminder.
Design the Grocy restore before launch
Protect Grocy's state before optimizing its container. The required set is database, uploaded files, recipes and configuration. Mount /config before bootstrap, write harmless sample data and replace the container to prove that path is actually persistent. If multiple stores must agree, document the order in which writes are paused and backups are taken.
Keep copies outside the deployment server and encrypt material containing credentials or private content. Recovery succeeds when stock, recipes, chores, equipment and history return and the next scheduled reminder has the correct date. The distinction between a persistent mount and an independent copy is covered in persistent storage and snapshots.
Test Grocy from outside the server
Choose the final Grocy hostname before users save callbacks or client settings, then publish the UI over HTTPS and configure the correct timezone. The platform route should terminate TLS once and target private port 80.
Run the acceptance transaction externally. If the client never reaches Grocy, use the SSL validation checklist for DNS and certificate checks. If the request reaches Grocy but the SQLite database cannot write or scheduled chores use the wrong timezone, stop changing proxy redirects and inspect the application-specific boundary instead.
Choose the Grocy trust boundary
Threat-model the action Grocy performs, not just its login form. Here the high-risk mistake is keeping the default login after setup. Implement this boundary: remove default credentials, choose the correct timezone and limit household data to intended users.
Grocy has no mandatory bootstrap secret in this baseline; protect its actual administrator account or upstream authentication instead. Do not solve a permission error by running the container as root or mounting the host broadly. Resource limits also belong to the security design when SQLite writes, uploaded images, scheduled jobs and household-device traffic can be triggered by users.
A Dockup deployment still needs an Grocy acceptance test
Dockup can own the replaceable platform pieces: route traffic to port 80, issue the domain and certificate, inject secrets, attach persistent storage and connect Grocy to managed or privately attached services. It can do this on Dockup infrastructure or on a server you attach.
The Grocy acceptance work remains explicit. After the one-click deployment, publish the UI over HTTPS and configure the correct timezone, confirm the local requirement — one durable config volume and optional barcode-device access and run this scenario: replace the default login, add a product, record a purchase and consumption, scan a barcode and trigger a chore or expiry reminder. That division is intentional: Dockup removes repetitive infrastructure setup without pretending that application roles, provider credentials or restore policy choose themselves.
Frequently asked questions
What does Grocy need for a production deployment?
Route the Grocy container on port 80 through one HTTPS origin. The local runtime requirement is one durable config volume and optional barcode-device access. Do not call Grocy ready until you can replace the default login, add a product, record a purchase and consumption, scan a barcode and trigger a chore or expiry reminder.
Which Grocy data belongs in a backup?
Persist /config and include database, uploaded files, recipes and configuration in the same recovery manifest. A clean Grocy restore passes only when stock, recipes, chores, equipment and history return and the next scheduled reminder has the correct date.
Does Grocy require HTTPS behind a reverse proxy?
Use HTTPS for the public Grocy origin and keep port 80 on the internal route. Apply the Grocy setting correctly: publish the UI over HTTPS and configure the correct timezone. For Grocy, HTTPS protects credentials or user content in transit and keeps origin-sensitive client behavior consistent.
How should a Grocy upgrade be tested?
Restore current Grocy state into an isolated deployment, apply the candidate version and repeat its acceptance transaction. Pay particular attention because Grocy database migrations and custom extensions should be rehearsed on a copied config directory. Keep the previous Grocy image until its data-migration and rollback boundary are understood.
