Yes. A bind-mounted /usr/local/bin/ignition/data folder upgrades the same way a native Ignition install does. Change the image tag and start the container. During startup, the new gateway version converts any older configuration it finds in that folder. The image supplies the binaries and the host directory supplies the state. The procedure below covers the steps around that tag change: verify the mount, capture a rollback point, upgrade one gateway at a time, and review what the migration rewrote in your git repository.
Which hop holds the gateway state when the data folder is bind-mounted?
A request to start the gateway follows this path:
- The compose file declares the image tag and the mount.
- The Docker engine builds the container from the image layers.
- The Ignition process under
/usr/local/bin/ignitionreads and writesdata. - Every write passes through the bind mount straight to the host directory, where your per-gateway git repository tracks it.
Recreating the container discards only the image layers and the container's writable layer. Nothing under data is touched. The gateway has no idea it runs in a container. At startup it reads its configuration and, if the stored format is from an older version, runs its upgrade routines against it. An installer-based upgrade on bare metal does the same thing.
| Content | Lives in | Replaced by a tag change? |
|---|---|---|
| Ignition runtime, libraries, bundled Java runtime | Image layers | Yes |
| Gateway config, projects, resources, internal database | Host directory via bind mount | No. Migrated in place at startup |
| Git history and working tree | Host repository | No |
Anything written inside the container outside data
|
Container writable layer | Lost on recreate |
Check: run docker inspect <container> --format '{{json .Mounts}}'. For each gateway, confirm Type is bind, Source is that gateway's own host path, Destination is /usr/local/bin/ignition/data, and RW is true.
Are the host directory and its ownership ready for a new image?
Check the filesystem before looking at anything Ignition-specific. A bind mount passes host ownership and permissions through unchanged. If a new image runs the gateway under a different user or numeric ID, the process can lose write access to its own data. Bind mounts also differ from named volumes in how they get their initial content, and that difference matters when you upgrade.
| Behavior | Bind mount | Named volume |
|---|---|---|
| Seeded from image content when empty | No. The host directory hides the image's copy. | Yes, on first mount |
| File ownership | Host UID/GID passed through as-is | Set when the volume is initialized |
| Managing git from the host | Direct, at your chosen path | Indirect, through Docker's storage path |
| Version upgrade | Gateway migrates the folder at startup | Gateway migrates the volume at startup |
Docker does not populate a bind mount. The gateway itself is responsible for bringing the folder up to date. That is why the startup migration is the whole upgrade mechanism in this setup.
Check: run docker compose exec <service> id to get the runtime UID/GID. Compare it with ls -ln on the host data directory. The numeric owner must match, or the runtime user must have write permission through group access.
How do I capture a rollback point before the tag changes?
Treat the upgrade as one-way. Once a newer version has migrated the folder, do not point an older image at it. A rollback means restoring the pre-upgrade folder and the old tag together.
- Take a gateway backup from the Gateway web interface. This gives you an independent restore path.
- Commit and tag the gateway repository:
git add -A,git commit -m "pre-upgrade",git tag pre-8.3.1. - Stop the gateway with
docker compose stop <service>. This keeps the internal database and config files from being copied mid-write. - Cold-copy the entire host data directory. Include everything your
.gitignoreexcludes. The repository is not a full backup if it ignores databases, keystores, or other binaries.
Check: git status reports a clean tree. The copy's file count and total size match the source directory.
How do I change the image tag without upgrading every gateway at once?
Pin exact version tags and move one service at a time. Keep the other gateways on the old tag until the first one passes verification.
services:
gateway-a:
image: <ignition-image>:8.3.1
volumes:
- ./gateway-a/data:/usr/local/bin/ignition/data
- Edit the tag for one service only.
- Pull the new image with
docker compose pull gateway-a. - Recreate only that container with
docker compose up -d gateway-a.
Avoid these pitfalls:
-
Floating tags: with a tag like
latest, any routinepullbecomes an unplanned upgrade and migrates the data with no rollback point. - Shared data folders: never mount the same host directory into two gateway containers.
- Beta data: for gateways built on the 8.3 beta, read the release notes for the beta-to-release upgrade path before moving that data forward.
Check: docker compose images gateway-a shows the new tag, and docker compose ps shows the container running rather than restarting.
What does the first start on the new image write back to the host?
Follow the startup with docker compose logs -f gateway-a. Do not stop or restart the container during this first boot. An interrupted migration can leave the folder partially converted, and the only clean fix is to restore the cold copy.
When the gateway reports it is running, run git diff --stat on the host. Any files the migration rewrote show up there. Commit them as a dedicated commit, for example "8.3.1 gateway-generated migration". Keep this separate from your own edits so the change stays reviewable and can be reverted on its own.
| Symptom | Likely cause | Action |
|---|---|---|
| Container restart loop with permission errors in logs | UID/GID mismatch on the bind mount | Correct host ownership, then start again |
| Gateway comes up in initial commissioning state | Wrong Source path, so an empty directory is mounted |
Stop immediately, fix the path, and check docker inspect again |
| Old tag fails after a rollback attempt | Older version started against migrated data | Restore the pre-upgrade copy together with the old tag |
| Large, unexpected git diff | Config format rewritten by migration | Review it and commit it separately from your own changes |
How do I confirm the upgraded gateway is fully back in service?
- Open the Gateway web interface and confirm the status page reports the new version.
- Confirm every project is listed. Device connections should show connected, database connections should show valid, and tag providers should be running.
- Confirm gateway network links to the other containers on the compose network have re-established.
- Restart the container once with
docker compose restart gateway-a, then rungit statuson the host. A clean tree proves the migration was a one-time rewrite and that the bind mount persists state across restarts.
Once all four checks pass, repeat the procedure for the next gateway.
FAQ
How do I upgrade an Ignition Docker container without losing gateway config?
Keep /usr/local/bin/ignition/data on a bind mount or named volume, change only the image tag in docker-compose, and run docker compose pull followed by docker compose up -d for that service. The gateway migrates the existing config during startup, as it would in a native upgrade.
How do I roll back an Ignition Docker upgrade when the data folder is on the host?
Stop the container, restore the cold copy of the data directory taken before the upgrade, and set the old image tag again. Do not start an older image against a folder a newer version has already migrated.
How do I see what the Ignition upgrade changed in my git-tracked data folder?
After the first startup on the new image, run git diff --stat in the gateway repository. Commit those migration changes as their own commit, separate from project edits.