BOOTC-MANAGEMENT-SERVICES(7)
π NAME π
bootc-management-services β management services, bestie π
(yes that's literally the whole name, and yes this page from the Miscellaneous Information Manual is about gluing a fleet of machines to a central management service)
β¨ DESCRIPTION β¨
okay SO. when you're running a whole fleet of systems π, the move is usually to hook them all up to a central management service. and like, the way that works is: the service hands you a client, you install that client on every single system, and it phones home to the central service. and β important β a lot of these services make the client do a one time registration first. like a vibe check, but for your machine's identity π«Ά.
so here's an example showing how to install the client into a bootc image and run it at startup so it registers the system. this example is assuming your management-client handles all the future connections to the server itself, e.g. via a cron job or a separate systemd service. and like, you could tweak this to make a persistent systemd service if that's what you need π. also, the Containerfile here is not optimized β on purpose!! β so that every step is super clear to read. (ngl the better practice is to invoke RUN a single time so you don't stack up layers in the image, but that would make this way less readable, so.)
so, the Containerfile, in all its glory π
FROM <bootc base image>
# Typically when using a management service, it will determine when to upgrade the system.
# So, disable bootc-fetch-apply-updates.timer if it is included in the base image.
RUN systemctl disable bootc-fetch-apply-updates.timer
# Install the client from dnf, or some other method that applies for your client
RUN dnf install management-client -y && dnf clean all
# Bake the credentials for the management service into the image
ARG activation_key=
# The existence of .run_next_boot acts as a flag to determine if the
# registration is required to run when booting
RUN touch /etc/management-client/.run_next_boot
COPY <<"EOT" /usr/lib/systemd/system/management-client.service
[Unit]
Description=Run management client at boot
After=network-online.target
ConditionPathExists=/etc/management-client/.run_client_next_boot
[Service]
Type=oneshot
EnvironmentFile=/etc/management-client/.credentials
ExecStart=/usr/bin/management-client register --activation-key ${CLIENT_ACTIVATION_KEY}
ExecStartPre=/bin/rm -f /etc/management-client/.run_next_boot
ExecStop=/bin/rm -f /etc/management-client/.credentials
[Install]
WantedBy=multi-user.target
EOT
# Link the service to run at startup
RUN ln -s /usr/lib/systemd/system/management-client.service \
/usr/lib/systemd/system/multi-user.target.wants/management-client.service
# Store the credentials in a file to be used by the systemd service
RUN echo -e "CLIENT_ACTIVATION_KEY=${activation_key}" > /etc/management-client/.credentials
# Set the flag to enable the service to run one time
# The systemd service will remove this file after the registration completes the first time
RUN touch /etc/management-client/.run_next_boot
π bestie pls copy that block verbatim, character for character. don't go "improving" it, i'm watching π«Ά
let's break the vibe down real quick though, because every chunk is doing a job β¨:
- first thing,
systemctl disable bootc-fetch-apply-updates.timerβ because when a management service is in the picture, it decides when the system upgrades. so if that timer came baked into your base image, it's gotta go π. - then you install the client, whether that's from
dnfor literally any other method that applies to whichever client you're using π. ARG activation_key=is where you bake the credentials for the management service right into the image π.- the existence of
.run_next_bootis acting as a flag β it's the little "yep, registration still needs to run when we boot" signal πΈ. - the
management-client.serviceunit is written in viaCOPY <<"EOT"at/usr/lib/systemd/system/management-client.service, and it runs the client at boot, afternetwork-online.target, only whenConditionPathExists=/etc/management-client/.run_client_next_boot. it reads/etc/management-client/.credentialsas itsEnvironmentFile, runs/usr/bin/management-client register --activation-key ${CLIENT_ACTIVATION_KEY}, cleans up the flag file beforehand withExecStartPre=/bin/rm -f /etc/management-client/.run_next_boot, and nukes the credentials afterward withExecStop=/bin/rm -f /etc/management-client/.credentials. - then you symlink the unit into
multi-user.target.wantsat startup, so it's wanted bymulti-user.targetπ. echo -e "CLIENT_ACTIVATION_KEY=${activation_key}" > /etc/management-client/.credentialsdrops the credential into that file the systemd service uses π.- and finally,
touch /etc/management-client/.run_next_bootflips the flag so the service gets to run exactly one time β because the service itself removes that file once the first registration completes β¨.
π SEE ALSO π
π VERSION π
v1.17.1
and that's the whole page, bestie!! π you just read bootc-management-services(7) from the Miscellaneous Information Manual, and this version info is riding along at v1.17.1. go forth and register your fleet, it's giving main character energy ππ¦β¨
π¦ where this page comes from
- fedora 43: bootc 1.17.1-1.fc43 Β· Apache-2.0 AND BSD-3-Clause AND MIT AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT) AND (Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT) AND (Unlicense OR MIT)
- fedora 44: bootc 1.17.1-1.fc44 Β· Apache-2.0 AND BSD-3-Clause AND MIT AND (Apache-2.0 OR BSL-1.0) AND (Apache-2.0 OR MIT) AND (Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT) AND (Unlicense OR MIT)
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms