feat: add container deploy path (Containerfile, self-provisioning entrypoint, Forgejo registry push)
This commit is contained in:
parent
fd847d035f
commit
50e5e444bc
5 changed files with 100 additions and 3 deletions
13
.dockerignore
Normal file
13
.dockerignore
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
/target
|
||||
/result
|
||||
/result-*
|
||||
/cache
|
||||
/config
|
||||
/fumi.rns
|
||||
.git
|
||||
.jj
|
||||
.env
|
||||
*.db
|
||||
*.db-wal
|
||||
*.db-shm
|
||||
server.key
|
||||
22
Containerfile
Normal file
22
Containerfile
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Default (non-rns) build only: microReticulum's cmake/C++ build isn't set
|
||||
# up for the musl toolchain alpine gives us, mirroring packages.static in
|
||||
# flake.nix. Use the Nix flake if you need the rns feature.
|
||||
FROM rust:1-alpine AS builder
|
||||
RUN apk add --no-cache musl-dev gcc
|
||||
WORKDIR /usr/src/bunshin
|
||||
COPY Cargo.toml Cargo.lock build.rs ./
|
||||
COPY src ./src
|
||||
RUN cargo build --release --locked
|
||||
|
||||
FROM alpine:3.20
|
||||
RUN apk add --no-cache ca-certificates \
|
||||
&& adduser -D -h /data -u 10000 bunshin
|
||||
COPY --from=builder /usr/src/bunshin/target/release/bunshin /usr/local/bin/bunshin
|
||||
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
||||
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
|
||||
USER bunshin
|
||||
WORKDIR /data
|
||||
VOLUME /data
|
||||
EXPOSE 1961/tcp
|
||||
ENTRYPOINT ["docker-entrypoint.sh"]
|
||||
CMD ["serve", "--key", "/data/server.key", "--db", "/data/mail.db", "--host", "0.0.0.0", "--port", "1961"]
|
||||
24
README.md
24
README.md
|
|
@ -6,11 +6,29 @@ A Rust implementation of the [Smol Mail](https://code.randogoth.com/randogoth/sm
|
|||
|
||||
The server never sees plaintext, sender identities or any private key. It learns only which mailbox an envelope is for, its size, and when it arrived.
|
||||
|
||||
The flake's main purpose is turnkey deployment on a NixOS host: import `nixosModules.default`, point it at a key, and `nixos-rebuild switch`.
|
||||
The quickest way to run it is the container image below. For a NixOS host, the flake also provides turnkey deployment as a special case: import `nixosModules.default`, point it at a key, and `nixos-rebuild switch`.
|
||||
|
||||
## Deploying with a container
|
||||
|
||||
Pull the published image and bring up a server in one command:
|
||||
|
||||
```
|
||||
podman run -d --name bunshin -p 1961:1961 -v bunshin-data:/data code.randogoth.com/randogoth/bunshin
|
||||
```
|
||||
|
||||
`docker` works the same way — the image is a standard OCI image either way. The entrypoint generates `/data/server.key` on first run if it's missing, then runs `serve` against `/data/server.key` and `/data/mail.db` on `0.0.0.0:1961`; `podman logs bunshin` prints the generated public key to publish to clients. A key already in the volume is left alone, so restarts and upgrades keep the same identity.
|
||||
|
||||
Pass your own arguments to run `keygen` or a customized `serve` instead of the default — they take the same flags as a bare-metal install, e.g. `podman run --rm -v bunshin-data:/data code.randogoth.com/randogoth/bunshin keygen --key /data/server.key --force`.
|
||||
|
||||
To build the image locally instead of pulling (same non-`rns` build as the release image, see the `Containerfile` header comment):
|
||||
|
||||
```
|
||||
podman build -t bunshin -f Containerfile .
|
||||
```
|
||||
|
||||
## Deploying on NixOS
|
||||
|
||||
Add bunshin as a flake input and import the module:
|
||||
For a NixOS host that already manages the rest of its config with Nix, import the module instead of running the container:
|
||||
|
||||
```nix
|
||||
{
|
||||
|
|
@ -34,7 +52,7 @@ Add bunshin as a flake input and import the module:
|
|||
}
|
||||
```
|
||||
|
||||
`services.bunshin` also takes `host`, `port`, `dataDir`, `maxEnvelope`, `quota`, `requestsQuota`, `retentionDays`, `requestsRetentionDays`, `maxTokens`, `rateConnections`, `rateSends`, `rateTokens`, `maxConnections` and `domains`; see `flake.nix` for defaults. The module renders a `systemd` unit that runs `bunshin serve` under `DynamicUser`; it does not generate a key.
|
||||
`services.bunshin` also takes `host`, `port`, `dataDir`, `maxEnvelope`, `quota`, `requestsQuota`, `retentionDays`, `requestsRetentionDays`, `maxTokens`, `rateConnections`, `rateSends`, `rateTokens`, `maxConnections` and `domains`; see `flake.nix` for defaults. The module renders a `systemd` unit that runs `bunshin serve` under `DynamicUser`; unlike the container entrypoint, it does not generate a key.
|
||||
|
||||
For the RNS carrier, build `packages.rns`, set `services.bunshin.package` to it, and enable `services.bunshin.rns` with its `keyFile`; see [RNS.md](RNS.md) for the protocol and the remaining options.
|
||||
|
||||
|
|
|
|||
12
docker-entrypoint.sh
Normal file
12
docker-entrypoint.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh
|
||||
# Generates the server key on first run so a bare `docker run` against an
|
||||
# empty volume works; a key already at BUNSHIN_KEY is left untouched.
|
||||
set -e
|
||||
|
||||
: "${BUNSHIN_KEY:=/data/server.key}"
|
||||
|
||||
if [ "$1" = "serve" ] && [ ! -f "$BUNSHIN_KEY" ]; then
|
||||
bunshin keygen --key "$BUNSHIN_KEY"
|
||||
fi
|
||||
|
||||
exec bunshin "$@"
|
||||
32
flake.nix
32
flake.nix
|
|
@ -156,6 +156,38 @@
|
|||
};
|
||||
};
|
||||
|
||||
# Builds the Containerfile image (same non-rns build the release
|
||||
# binary is, see its header comment) and pushes it to this repo's
|
||||
# Forgejo container registry, tagged by short commit hash and
|
||||
# `latest`. Needs FORGEJO_TOKEN (a token with write:package scope)
|
||||
# in the environment; run from a checkout so `git rev-parse` and
|
||||
# the Containerfile build context resolve to the right place.
|
||||
apps.release-container = flake-utils.lib.mkApp {
|
||||
drv = pkgs.writeShellApplication {
|
||||
name = "bunshin-release-container";
|
||||
runtimeInputs = [ pkgs.podman pkgs.git ];
|
||||
text = ''
|
||||
if [ -f .env ]; then
|
||||
set -a
|
||||
# shellcheck disable=SC1091
|
||||
. ./.env
|
||||
set +a
|
||||
fi
|
||||
: "''${FORGEJO_TOKEN:?set FORGEJO_TOKEN (env or .env) to a Forgejo token with write:package scope}"
|
||||
|
||||
rev=$(git rev-parse --short HEAD)
|
||||
registry="code.randogoth.com/randogoth/bunshin"
|
||||
|
||||
echo "''${FORGEJO_TOKEN}" | podman login code.randogoth.com -u randogoth --password-stdin
|
||||
podman build -f Containerfile -t "$registry:$rev" -t "$registry:latest" .
|
||||
podman push "$registry:$rev"
|
||||
podman push "$registry:latest"
|
||||
|
||||
echo "pushed: https://code.randogoth.com/randogoth/-/packages/container/bunshin"
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
devShells.default = pkgs.mkShell {
|
||||
packages = with pkgs; [ cargo rustc rustfmt clippy pkg-config gcc sqlite cmake ninja ];
|
||||
env = rnsSourceEnv;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue