Add a deploy script, with no host in it
The live deploy script has never been under version control, which makes
it the one part of the pipeline that can silently fall out of step with
the repo -- as it just did: it builds without --build-arg
IHASMAIL_VERSION, so every deployment would report 2.16.0 no matter what
was actually built.
This is that script with the host taken out of it. Every path, name,
port and volume is a variable with a default that describes the shape of
a deployment rather than any particular one, so what is published is the
logic and none of the topology. It follows Caddyfile.example and
nginx.example.conf, which are here for the same reason.
Nothing sensitive was in the original either -- it never reads the
environment file, only hands the path to docker run --env-file -- but
the absolute paths named a user and a directory layout, and there is no
reason for those to be public to buy version control over the guards.
Two things it does that the original did not:
- passes the version to the build, which is the whole reason this came
up. A Docker tag may not contain "+", which a version for a commit
that arrived outside a pull request does (2.16.57+g1fa6578), so the
tag turns it into "-" while the build is told the real form. About
and /api/health still report it correctly.
- tags each build with its own version as well as :current, so rolling
back is running the previous tag rather than rebuilding it. The
failure path lists what is there to go back to.
Exercised against a throwaway clone, container, volume and image:
the hold guard refuses a held commit that production does not already
carry and lets one through that it does; the confirmation guard refuses
to run over a pipe without --yes; a dry run stops before building; and a
full run built, replaced the container and reported healthy at
2.16.57+g0549a09 -- from an image tagged 2.16.57-g0549a09, which is the
sanitising working.
This commit is contained in:
@@ -209,6 +209,34 @@ session to find:
|
||||
for unsupported servers can be tested. That is all it does — the rest still
|
||||
behaves like 0.16. Emulating 0.15 properly went with the support for it
|
||||
|
||||
### Deploying
|
||||
|
||||
[`deploy.example.sh`](deploy.example.sh) is a single-host Docker deploy: it
|
||||
fetches, refuses anything held back, shows what is about to be introduced and
|
||||
asks, rebuilds the image with the right version baked in, replaces the
|
||||
container and waits for it to report healthy. Copy it, or run it as-is and set
|
||||
what differs in the environment — `IHASMAIL_APP`, `IHASMAIL_ENV`,
|
||||
`IHASMAIL_NAME`, `IHASMAIL_BIND`, `IHASMAIL_VOLUME`, `IHASMAIL_IMAGE`.
|
||||
|
||||
```bash
|
||||
./deploy.sh # origin/main, asks before shipping new commits
|
||||
./deploy.sh --dry-run # run the guards and stop
|
||||
./deploy.sh v2.16.57 --yes # a named ref, no prompt (there is no tty over ssh)
|
||||
```
|
||||
|
||||
Two guards, because a deploy script is exactly where a careless run does the
|
||||
most damage. `.deploy-hold` lists commits that must not reach production yet,
|
||||
one per line, and a target carrying one that production does not already have
|
||||
is refused outright — `--yes` does not override it, and clearing a hold means
|
||||
deleting its line. Separately, anything introducing new commits is listed and
|
||||
has to be confirmed; over SSH, with no terminal to answer on, that means
|
||||
passing `--yes` deliberately rather than a bare run shipping whatever `main`
|
||||
has picked up since.
|
||||
|
||||
Each build is tagged with its own version as well as `:current`, so rolling
|
||||
back is running the previous tag rather than rebuilding it. The environment
|
||||
file is never read by the script, only handed to `docker run --env-file`.
|
||||
|
||||
## Configuration
|
||||
|
||||
All configuration is via environment variables (see `.env.example`):
|
||||
|
||||
Reference in New Issue
Block a user