#118 put docker-compose.prod.yml in the repository and explained at length why it belongs there. What it never produced is the procedure for getting production from where it is — a stack defined in Portainer's web editor — to where that file expects it to be, deployed as a git repository stack.
The material that exists is scattered and none of it is a procedure:
The compose file's header comment states the target state: name the stack redefined-designs, deploy it as a git repository stack with a given repository, reference and compose path, do not let it build, rename any stack variables whose names differ. That is a description of the destination, written where someone editing the file will see it, not a set of steps for someone performing a migration.
README.md → Promoting a reviewed change to production is a good runbook for the wrong thing. It covers a routine redeploy of an already-correct stack: promote the image, recreate the container, verify. It assumes the stack already exists in the right form.
So the one-time cutover — the riskiest deployment operation this project has — is the one with no written procedure.
Why it needs one rather than being obvious
Two properties of this stack decide whether the cutover is safe, and neither is stated anywhere:
All persistent data is on bind mounts, not named Docker volumes — /volume1/configs/redefined-designs/postgres and .../uploads. Deleting and recreating the stack therefore cannot lose the database or the product images. That is the single most reassuring fact about this operation and it is currently something you have to work out by reading the volumes block.
Both services set an explicit container_name.redefined-designs-syn and redefined-designs-db-syn are fixed names, so the old containers must be gone before the new stack comes up. Otherwise the deploy fails on a name collision, which reads as a Portainer problem rather than as a sequencing one.
There are also things that are simply lost if not captured first. Portainer stack variables belong to the stack; deleting it discards them, and they are all secrets — the database password among them. Recreating the stack without having written them down first means a stack that cannot start and a database whose password no longer matches.
And the stack does not build. redefined-designs:latest has to exist on the NAS before the new stack starts, or the deploy fails with "image not found" (#146).
What this should produce
A runbook at docs/ops/production-stack-cutover.md covering, in order: recording what exists today, backing up, reconciling variable names, confirming the image is present, removing the old stack, creating the git repository stack, and verifying — including which boot warnings are expected afterwards and which are not.
It has to have a rollback, and the rollback is only credible if step one captured the old definition.
And de-duplication
Once the runbook exists, the procedural lines in the compose header should point at it rather than restate it, while keeping the rationale that belongs at the point of use — why there is no build:, why most values are hardcoded, why NODE_ENV is absent. The README should distinguish the first-time cutover from the routine redeploy it already documents, rather than leaving a reader to infer which one they are doing.
#118 put `docker-compose.prod.yml` in the repository and explained at length why it belongs there. What it never produced is the procedure for getting production from where it is — a stack defined in Portainer's web editor — to where that file expects it to be, deployed as a git repository stack.
The material that exists is scattered and none of it is a procedure:
- **The compose file's header comment** states the target state: name the stack `redefined-designs`, deploy it as a git repository stack with a given repository, reference and compose path, do not let it build, rename any stack variables whose names differ. That is a description of the destination, written where someone editing the file will see it, not a set of steps for someone performing a migration.
- **`README.md` → Promoting a reviewed change to production** is a good runbook for the wrong thing. It covers a *routine redeploy* of an already-correct stack: promote the image, recreate the container, verify. It assumes the stack already exists in the right form.
So the one-time cutover — the riskiest deployment operation this project has — is the one with no written procedure.
## Why it needs one rather than being obvious
Two properties of this stack decide whether the cutover is safe, and neither is stated anywhere:
**All persistent data is on bind mounts**, not named Docker volumes — `/volume1/configs/redefined-designs/postgres` and `.../uploads`. Deleting and recreating the stack therefore cannot lose the database or the product images. That is the single most reassuring fact about this operation and it is currently something you have to work out by reading the volumes block.
**Both services set an explicit `container_name`.** `redefined-designs-syn` and `redefined-designs-db-syn` are fixed names, so the old containers must be gone before the new stack comes up. Otherwise the deploy fails on a name collision, which reads as a Portainer problem rather than as a sequencing one.
There are also things that are simply lost if not captured first. Portainer stack variables belong to the stack; deleting it discards them, and they are all secrets — the database password among them. Recreating the stack without having written them down first means a stack that cannot start and a database whose password no longer matches.
And the stack does not build. `redefined-designs:latest` has to exist on the NAS before the new stack starts, or the deploy fails with "image not found" (#146).
## What this should produce
A runbook at `docs/ops/production-stack-cutover.md` covering, in order: recording what exists today, backing up, reconciling variable names, confirming the image is present, removing the old stack, creating the git repository stack, and verifying — including which boot warnings are expected afterwards and which are not.
It has to have a rollback, and the rollback is only credible if step one captured the old definition.
## And de-duplication
Once the runbook exists, the procedural lines in the compose header should point at it rather than restate it, while keeping the rationale that belongs at the point of use — why there is no `build:`, why most values are hardcoded, why `NODE_ENV` is absent. The README should distinguish the first-time cutover from the routine redeploy it already documents, rather than leaving a reader to infer which one they are doing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
#118 put
docker-compose.prod.ymlin the repository and explained at length why it belongs there. What it never produced is the procedure for getting production from where it is — a stack defined in Portainer's web editor — to where that file expects it to be, deployed as a git repository stack.The material that exists is scattered and none of it is a procedure:
redefined-designs, deploy it as a git repository stack with a given repository, reference and compose path, do not let it build, rename any stack variables whose names differ. That is a description of the destination, written where someone editing the file will see it, not a set of steps for someone performing a migration.README.md→ Promoting a reviewed change to production is a good runbook for the wrong thing. It covers a routine redeploy of an already-correct stack: promote the image, recreate the container, verify. It assumes the stack already exists in the right form.So the one-time cutover — the riskiest deployment operation this project has — is the one with no written procedure.
Why it needs one rather than being obvious
Two properties of this stack decide whether the cutover is safe, and neither is stated anywhere:
All persistent data is on bind mounts, not named Docker volumes —
/volume1/configs/redefined-designs/postgresand.../uploads. Deleting and recreating the stack therefore cannot lose the database or the product images. That is the single most reassuring fact about this operation and it is currently something you have to work out by reading the volumes block.Both services set an explicit
container_name.redefined-designs-synandredefined-designs-db-synare fixed names, so the old containers must be gone before the new stack comes up. Otherwise the deploy fails on a name collision, which reads as a Portainer problem rather than as a sequencing one.There are also things that are simply lost if not captured first. Portainer stack variables belong to the stack; deleting it discards them, and they are all secrets — the database password among them. Recreating the stack without having written them down first means a stack that cannot start and a database whose password no longer matches.
And the stack does not build.
redefined-designs:latesthas to exist on the NAS before the new stack starts, or the deploy fails with "image not found" (#146).What this should produce
A runbook at
docs/ops/production-stack-cutover.mdcovering, in order: recording what exists today, backing up, reconciling variable names, confirming the image is present, removing the old stack, creating the git repository stack, and verifying — including which boot warnings are expected afterwards and which are not.It has to have a rollback, and the rollback is only credible if step one captured the old definition.
And de-duplication
Once the runbook exists, the procedural lines in the compose header should point at it rather than restate it, while keeping the rationale that belongs at the point of use — why there is no
build:, why most values are hardcoded, whyNODE_ENVis absent. The README should distinguish the first-time cutover from the routine redeploy it already documents, rather than leaving a reader to infer which one they are doing.