diff --git a/deploy/README.md b/deploy/README.md index 868aa99..0e4cedf 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -21,7 +21,7 @@ The two settings are independent. [Setup with nginx and PostgreSQL on the host]( ## Requirements - Docker 20.10 or newer, `bash` and `openssl` on the host. The Compose plugin is needed only when Traefik or PostgreSQL run as containers of this stack. -- The application image on the host: `docker build -t rezervator:latest .` in the repository root, or pulled from a registry. The image must match the CPU architecture of the host. +- The application image on the host: `docker build -t rezervator:latest .` in the repository root, or pulled from a registry (see [Distributing the image](#distributing-the-image)). The image must match the CPU architecture of the host. - A DNS record for every customer domain pointing to the host ## First setup @@ -37,6 +37,47 @@ With `REZERVATOR_PROXY=traefik`, `REZERVATOR_TLS=true` gets a Let's Encrypt cert The session cookie is marked `Secure`. Whatever the setup, customers must reach the application over HTTPS, otherwise logging in works only on `localhost` addresses. +## Distributing the image + +Building the image takes several minutes and needs the Rust toolchain image. To set up another server quickly, build once, push the image to a container registry and pull it elsewhere. Gitea has a registry built in; the examples use the one at `gitea.itsolved.cz` and the organization `itsolved`. + +On the server where the image was built: + +```sh +docker login gitea.itsolved.cz +docker tag rezervator:latest gitea.itsolved.cz/itsolved/rezervator:1.2.0 +docker push gitea.itsolved.cz/itsolved/rezervator:1.2.0 +``` + +Log in with a Gitea user name and an access token (Settings → Applications) that may write packages. Use the version from `Cargo.toml` as the tag rather than only `latest`: it shows what runs where, and an older version stays available. + +On another server: + +```sh +docker login gitea.itsolved.cz # only when the package is not public; a token that may read packages is enough +docker pull gitea.itsolved.cz/itsolved/rezervator:1.2.0 +``` + +and in `.env`: + +```ini +REZERVATOR_IMAGE=gitea.itsolved.cz/itsolved/rezervator:1.2.0 +``` + +To release a new version, build and push it under a new tag, then on every server pull it, change the tag in `.env` and run `./rezervator.sh upgrade --all`. + +Things to know: + +- The image runs only on the CPU architecture it was built on (`x86_64` when built on such a server). +- The package belongs to the organization and follows its visibility: the image of a public organization can be pulled without logging in. The image contains no configuration or passwords. +- If the push fails with `413 Request Entity Too Large`, the reverse proxy in front of Gitea limits the upload size; raise `client_max_body_size` in its nginx server block. + +Without a registry, an image can be copied to one server directly: + +```sh +docker save rezervator:latest | gzip | ssh user@other-server 'gunzip | docker load' +``` + ## Setup with nginx and PostgreSQL on the host ```ini