The service embeds everything it serves, so the image carries one binary and
nothing else. The build is in three stages: the frontend is built with Node,
the binary is built with Rust, and the runtime holds the binary and the C
library it links against.
The build context is the directory above this one, because the crate depends
on `apsis-rs` by path; the ignore file is named beside the Dockerfile so that
it applies to that context without living in it. What it keeps out is the
build output of both projects, the installed dependencies, and the working
notes — the first two because the image produces its own, and a copy from the
host would replace the newly built one.
Two things the image has to get right, and both are stated where they happen.
The command names the host explicitly, because the program defaults to the
loopback address where it answers only itself, so a container started without
it would serve nothing to anyone. And the toolchain file is removed inside
the builder, because it asks for the `stable` channel by name and rustup
would fetch it over the network; the image already provides the toolchain the
project builds with.
There is no health check. Probing `GET /health` is what an orchestrator
should do, and a probe inside the container would mean adding an HTTP client
to an image that needs no other tool.
The image could not be built here: this machine cannot reach Docker Hub, so
no base image can be pulled. What was checked is the definition itself, which
the builder parses, and every command in it, which was run directly from the
workspace root — the frontend build, `cargo build --release --locked` with
the frontend build skipped, and the binary started with the host and port the
image uses.