# Butane config for a Flatcar VM running the official httpd (Apache) image # as a docker container. Applied by Ignition on FIRST BOOT only: to change a # running VM, edit this file and taint the VM so it is rebuilt from the image. variant: flatcar version: 1.0.0 systemd: units: - name: webserver.service enabled: true contents: | [Unit] Description=httpd webserver container After=docker.service Requires=docker.service [Service] TimeoutStartSec=0 ExecStartPre=-/usr/bin/docker rm --force webserver ExecStart=/usr/bin/docker run --name webserver --rm -p 80:80 httpd:latest ExecStop=/usr/bin/docker stop webserver Restart=always RestartSec=5s [Install] WantedBy=multi-user.target # Experimental: Flatcar ships no qemu-guest-agent binary, so this runs one # from an Alpine container against the virtio-serial channel Proxmox # exposes when the VM's `agent.enabled` is true (see qemu_guest_agent in # tfvars). --network host is required so qemu-ga reports the host's real # network interfaces/IP instead of the container's own bridge IP. # --pid host + the /sbin/shutdown bind mount (see /opt/qga-shutdown.sh # below) are required so guest-shutdown/reboot actually reach the host # instead of Alpine's own busybox init inside the container. # --privileged + host /dev is broader access than qemu-ga strictly needs, # but keeps this simple for a first try. - name: qemu-guest-agent.service enabled: true contents: | [Unit] Description=QEMU guest agent (containerized) After=docker.service Requires=docker.service [Service] TimeoutStartSec=0 ExecStartPre=-/usr/bin/docker rm --force qemu-guest-agent ExecStart=/usr/bin/docker run --name qemu-guest-agent --rm --privileged \ --network host --pid host -v /dev:/dev \ -v /opt/qga-shutdown.sh:/sbin/shutdown:ro \ alpine:latest sh -c \ "apk add --no-cache qemu-guest-agent util-linux && exec qemu-ga -m virtio-serial -p /dev/virtio-ports/org.qemu.guest_agent.0" Restart=always RestartSec=5s [Install] WantedBy=multi-user.target storage: files: # qemu-ga always execs "/sbin/shutdown +0 " (flag is -H # halt, -P powerdown, -r reboot) to handle guest-shutdown/guest-reboot. # Inside the container that path is Alpine's own busybox shutdown, which # only affects the container's namespace. Bind-mounted over /sbin/shutdown # in the container (see qemu-guest-agent.service above), this shim uses # nsenter to re-enter the real host's namespaces (PID 1 in the container # is the host's actual systemd, since the container runs with --pid host) # and calls the host's real systemctl instead. - path: /opt/qga-shutdown.sh mode: 0755 contents: inline: | #!/bin/sh case "$1" in -H) action=halt ;; -r) action=reboot ;; *) action=poweroff ;; esac exec nsenter --target 1 --mount --uts --ipc --net -- systemctl "$action"