Deploy immutably by default #139

Closed
opened 2026-08-31 05:26:32 +00:00 by jcoffey-dev · 0 comments
Owner

IHASMAIL_IMMUTABLE defaulted to 0, and .env.production doesn't set it either. So a plain ./deploy.sh origin/main --yes handed back a writable container with a /data volume mounted — quietly, and then reported healthy.

Nothing in the deploy output said the immutability had gone. docker inspect was the only place it showed, and only if you thought to look:

ReadonlyRootfs=false  Mounts=1

That is the wrong way round for the posture the project leads with. The safe one is now the default, and giving it up is the half that has to be deliberate:

IHASMAIL_IMMUTABLE=0 ./ihasmail-deploy.sh --yes

Found by deploying prod today. The running container had IMMUTABLE=1 and a read-only root, and reproducing that state took passing the variable by hand — because the script's own default would have taken it away.

No behaviour change for anyone already passing IHASMAIL_IMMUTABLE=1, and the named volume is still never touched either way, so an instance that opts back out finds whatever was in it.

One line of code; the rest is the comment explaining which way round the two options should sit and why.

Merged 2026-08-30 as coffey-labs/ihasmail@0fb504748d

Rebuilt from: git history, session transcript.

`IHASMAIL_IMMUTABLE` defaulted to `0`, and `.env.production` doesn't set it either. So a plain `./deploy.sh origin/main --yes` handed back a **writable container with a `/data` volume mounted** — quietly, and then reported healthy. Nothing in the deploy output said the immutability had gone. `docker inspect` was the only place it showed, and only if you thought to look: ``` ReadonlyRootfs=false Mounts=1 ``` That is the wrong way round for the posture the project leads with. The safe one is now the default, and giving it up is the half that has to be deliberate: ``` IHASMAIL_IMMUTABLE=0 ./ihasmail-deploy.sh --yes ``` Found by deploying prod today. The running container had `IMMUTABLE=1` and a read-only root, and reproducing that state took passing the variable by hand — because the script's own default would have taken it away. No behaviour change for anyone already passing `IHASMAIL_IMMUTABLE=1`, and the named volume is still never touched either way, so an instance that opts back out finds whatever was in it. One line of code; the rest is the comment explaining which way round the two options should sit and why. **Merged** 2026-08-30 as coffey-labs/ihasmail@0fb504748d29 <sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.