Run the container image
The image holds three things: the telecraft binary with the console inside
it, the Catalogue for the collector version it was built against, and the
licence. It runs the same command a host process runs, so everything in
Run an Instance applies here, with a container's way of
passing configuration in.
It carries no shell, no package manager, and no interpreter, and the process
runs as user 65532.
Pull it
docker pull ghcr.io/telecraft-dev/telecraft:release
Two tags:
| Tag | Points at |
|---|---|
vMAJOR.MINOR.PATCH |
One release. It never moves. |
release |
The current stable release. It moves with each one. |
Pin the digest in a deployment. Every release names its own:
docker pull ghcr.io/telecraft-dev/telecraft@sha256:DIGEST
DIGEST is the value the release notes carry.
Serve an estate
Mount an estate checkout read only, and publish the two addresses:
docker run --rm \
--volume /srv/estate:/estate:ro \
--publish 4321:4321 \
--publish 4320:4320 \
ghcr.io/telecraft-dev/telecraft:release \
serve -estate /estate
console and API on http://0.0.0.0:4321
OpAMP on 0.0.0.0:4320
the session key was drawn at start, so sessions last as long as this process
Open http://127.0.0.1:4321 and sign in.
| Port | What listens |
|---|---|
| 4321 | The console, the API, and the two probes. |
| 4320 | The OpAMP endpoint, at /v1/opamp. |
serve is the image's default command, so the arguments after the image name
are the flags you want to change. Binding both addresses on every interface
inside the container is the only configuration the image sets for you.
The estate needs at least one user in users.yaml before the Instance
starts. Hash a secret with the same image, where SECRET is the password you
are setting:
printf %s "$SECRET" | docker run --rm -i ghcr.io/telecraft-dev/telecraft:release passwd
Keep the checkout current
The image carries no git, so -repo has nothing to fetch an estate with.
Serve a directory instead, and keep that directory current from outside the
container: a job on the host that pulls, or a container beside this one that
syncs the repository into a volume both of them mount. Each poll re-reads the
directory, so a merge arrives without a restart. On Kubernetes that second
container is what the chart installs, and
Deploy on Kubernetes sets it up.
On a host that has git, -repo works as
Run an Instance describes.
Configure it from the environment
Every flag has an environment variable: TELECRAFT_ plus the flag name
upper-cased, with dashes as underscores. A flag beats an environment
variable, which beats the default.
docker run --rm \
--volume /srv/estate:/estate:ro \
--publish 4321:4321 \
--env TELECRAFT_ESTATE=/estate \
--env TELECRAFT_EXTERNAL_URL=https://telecraft.example \
--env TELECRAFT_FETCH_INTERVAL=15s \
ghcr.io/telecraft-dev/telecraft:release
TLS terminates in front of the container. Tell the process what the outside
sees with TELECRAFT_EXTERNAL_URL, and it refuses to start on a non-loopback
host over plain HTTP unless -insecure-http says you mean it.
Place the secrets
Telecraft reads secret material from files in one directory. No secret travels as an environment variable, and none belongs in an image layer.
docker run --rm \
--volume /srv/estate:/estate:ro \
--volume /srv/telecraft/secrets:/run/secrets:ro \
--publish 4321:4321 \
ghcr.io/telecraft-dev/telecraft:release \
serve -estate /estate -secrets-dir /run/secrets
The files must be readable by user 65532. A compose file's secrets: block
presents them at /run/secrets already, which is why that is the path in the
examples. Rotating one is rewriting its file.
Run the CLI from the same image
The image is the whole CLI, so a pipeline that already pulls it runs the same commands the Instance runs from the same artefact, with nothing else to place. A pipeline with no container runtime downloads the binary instead, which the quickstart does.
docker run --rm --volume "$PWD:/estate:ro" \
ghcr.io/telecraft-dev/telecraft:release \
check -library /estate/requirements \
-estate /estate/rows.yaml \
-endpoint https://telemetry.example \
> report.json
Every command in the CLI reference works the same way: name it after the image, mount what it reads, and redirect what it writes. Check conformance covers this one's inputs and its exit codes.
Activate the Catalogue it carries
The image carries the Catalogue for its pinned collector version at
/usr/share/telecraft/catalogues/. It arrives in your estate the way a
Catalogue carried across an air gap does: copy it in, read the impact report,
then activate it.
id=$(docker create ghcr.io/telecraft-dev/telecraft:release)
docker cp "$id:/usr/share/telecraft/catalogues/." /srv/estate/catalogues/
docker rm "$id"
Activate a version is the rest of it.
Carry it across an air gap
The image is the only thing that has to travel. VERSION is the release tag,
such as v0.8.0:
docker save ghcr.io/telecraft-dev/telecraft:VERSION -o telecraft-VERSION.tar
Move the file, then load it where it is going:
docker load -i telecraft-VERSION.tar
Nothing else is fetched. The console is inside the binary and reaches no other origin, and the Catalogue baseline is in the image. What the air gap still supplies from inside is the secrets, the estate, and any Catalogue newer than the one the image carries.
What is where inside the image
| Path | Holds |
|---|---|
/usr/local/bin/telecraft |
The binary, and the image's entrypoint. |
/usr/share/telecraft/LICENSE |
The terms the software is licensed under. |
/usr/share/telecraft/catalogues/ |
The Catalogue baseline. |
Build the image yourself
From a checkout, two scripts do it. The first builds the console, cross-compiles both Linux binaries, and stages everything the image copies. The second builds the image from that staged directory:
tools/image/stage.sh
PLATFORMS=linux/amd64 LOAD=1 tools/image/build.sh
tools/image/build.sh stages first unless you set STAGED=1, and builds both
architectures unless you name one. tools/image/offline.sh then starts an
image with networking disabled and requires it to serve.
What next
- Deploy with Compose puts this image on one host behind a terminator, with the secrets and the estate around it.
- Deploy on Kubernetes installs this image from a chart, with the checkout kept current beside it.
- Run an Instance is the same server as a host process, with the whole flag surface.
- Activate a version moves the estate onto a new Catalogue or Schema Registry version.