You edit the WireGuard config inside a running container, it works, and the next image update erases it. Nothing was misconfigured. The file lived in the container's writable layer, which exists only for that container instance. The comparison that matters is not which tool to use but which inputs your deployment declares. Anything you edited by hand is an input the deployment does not know about.

Two kinds of state, one of them is disposable

A container has a writable layer for changes made at runtime, and that layer is discarded when the container is replaced. It is not a configuration store and it is not a backup. The image plus the declared inputs is the whole definition of what runs.

Ask which of your VPN files are declared inputs and which are accidents:

docker diff wg-vpn
docker inspect --format '{{json .Mounts}}' wg-vpn

The diff lists what changed in the writable layer, which is precisely the set of things that will vanish. The mount listing shows what survives. Comparing the two answers the question before you lose anything.

Bind mount, named volume or secret: what each protects

All three can hold a VPN profile, and they differ in who can read it and what happens on replacement.

MechanismSurvives recreationWho can read it
Writable layerNoAnyone with container access, until it is gone
Bind mountYes, while the host path existsWhatever the host permissions allow
Named volumeYes, until the volume is removedManaged by the runtime
SecretYes, as a declared inputThe container process, by design

A bind mount maps a host path, so the file is as protected as that path is and as visible as the host's permissions allow. A named volume is managed by the runtime and survives container removal, which makes it the safer default for state the deployment owns. A secret mechanism is for material you do not want in an image or an environment variable.

Do not treat every environment variable and host file as equivalent protection, because they are not.

Editing inside the container is the trap

The trap is not the tool, it is the direction of the edit. A change made inside a running container is invisible to the deployment, so the next recreate silently reverts it and the symptom looks like a regression in the image. If you must make a change there to diagnose, copy it out immediately and put it in the declared input. Then recreate to prove the deployment reproduces it.

A profile can carry private keys and account material, which makes a backup of that file a secret-handling task rather than a file copy. Keep ownership and read access scoped to the container's actual process instead of widening a host directory to make a permission error disappear.

That widening is how a container convenience becomes a host exposure.

Recreate deliberately, then verify four things

Record the image version, the required device and capabilities, the network attachment and the persistent inputs. The device and capability list matters for a VPN container specifically, because the tunnel needs the network device and the privilege to configure it.

Confirm which generated runtime state should be rebuilt rather than saved. Keys the tunnel generated on first start are state, and whether you keep them or regenerate them is a decision with consequences for every peer that knows the old public key.

After a controlled recreation, verify identity, routing, DNS and the required failure block. A process that starts without errors proves none of those four. Check it while the tunnel is up and again after you stop it, because the failure block only shows itself when the tunnel goes away.

Keep a recovery copy outside the container

Keep a recovery copy that lives independently of the container, and test restoring it through the documented process. An untested backup of a VPN profile is a hope, especially when the restore path involves permissions the container process needs.

If a VPN owner container is replaced, coordinate the applications sharing its network stack under the runtime's supported lifecycle.

That coordination is the difference between a restart and an outage. The deployment should describe where the configuration comes from, and the volume documentation is the place to check what the runtime actually persists.

Makomi ya ndenge moko