New FCOS user, requesting Butane critique

Hi. I’m a longtime Proxmox VE user (LXC only), but have recently been getting into Podman.
For my homelab environment, I’m currently running Fedora 36 and Podman in a nested LXC container. I do love Proxmox, but would also love to move to a more automated system with the ability to update containers via systemd. This of course led me to FCOS.

I’m hoping someone could critique my butane config before I add too much more to it. I’m currently testing with a qcow2 image, which is why I don’t have much in the way of filesystem paritioning and mounting, but will eventually move to a bare metal installation on a laptop.

I took some inspiration for my butane config from this post, which is why I’m using the “–privileged=true” flag. I have very little knowledge of SELINUX, so I’m not sure if it’s still required for Portainer or any other container for that matter.

I have much to learn with regards to inter-container networking, but for now, I’m just curious where best to initialize a new Podman network within Ignition. My config below (with “podman network create caddybridge”) could obviously present some race conditions.

I realize I could use the “podman generate systemd” command, but is that the correct approach for CoreOS?

EDIT: After reading this thread, graceful shutdown seems to be a good enough reason to use the podman generate command.

variant: fcos
version: 1.4.0
passwd:
  users:
    - name: core
      ssh_authorized_keys:
        - ssh-rsa AAAA....
storage:
  files:
    - path: /etc/hostname
      mode: 0644
      contents:
        inline: |
          falcon
    - path: /etc/Caddyfile
      mode: 0644
      contents:
        inline: |
          falcon.lan {
                tls internal

                encode gzip
                # The negotiation endpoint is also proxied to Rocket
                reverse_proxy /notifications/hub/negotiate vaultwarden:80
                # Notifications redirected to the websockets server
                reverse_proxy /notifications/hub vaultwarden:3012
                # Send all other traffic to the regular Vaultwarden endpoint
                reverse_proxy vaultwarden:80
          }
systemd:
  units:
    - name: docker.service
      mask: true
    - name: podman.service
      enabled: true
    - name: podman.portainer.service
      enabled: true
      contents: |
        [Unit]
        Description=Portainer Admin Container
        After=network-online.target
        Wants=network-online.target
        Requires=podman.service network.target network-online.target

        [Service]
        ExecStartPre=mkdir -p /var/portainer_data
        ExecStartPre=-/bin/podman kill portainer
        ExecStartPre=-/bin/podman rm portainer
        ExecStartPre=-/bin/podman pull docker.io/portainer/portainer-ce
        # Privileged mode is required for binding to local socket to work due to SELINUX (https://github.com/portainer/portainer/issues/849)
        ExecStart=/bin/podman run \
                    --privileged=true \
                    -p 8000:8000 \
                    -p 9443:9443 \
                    --name portainer \
                    --restart=always \
                    -v /run/podman/podman.sock:/var/run/docker.sock \
                    -v /var/portainer_data:/data \
                    docker.io/portainer/portainer-ce:latest
        ExecStop=/bin/podman stop portainer

        [Install]
        WantedBy=multi-user.target
    - name: podman.vaultwarden.service
      enabled: true
      contents: |
        [Unit]
        Description=Vaultwarden
        After=network-online.target
        Wants=network-online.target
        Requires=podman.service network.target network-online.target

        [Service]
        ExecStartPre=mkdir -p /var/vaultwarden_data
        ExecStartPre=-/bin/podman kill vaultwarden
        ExecStartPre=-/bin/podman rm vaultwarden
        ExecStartPre=-/bin/podman pull docker.io/vaultwarden/server:latest
        # Privileged mode is required for binding to local socket to work due to SELINUX (https://github.com/portainer/portainer/issues/849)
        ExecStart=/bin/podman run \
                    --privileged=true \
                    -p 127.0.0.1:8080:80 \
                    -p 127.0.0.1:3012:3012 \
                    -e WEBSOCKET_ENABLED=true \
                    --name vaultwarden \
                    --hostname vaultwarden \
                    --network caddybridge \
                    --restart=always \
                    -v /var/vaultwarden_data:/data \
                    docker.io/vaultwarden/server:latest
        ExecStop=/bin/podman stop vaultwarden

        [Install]
        WantedBy=multi-user.target
    - name: podman.caddy.service
      enabled: true
      contents: |
        [Unit]
        Description=Caddy v2
        After=network-online.target
        Wants=network-online.target
        Requires=podman.service network.target network-online.target

        [Service]
        ExecStartPre=mkdir -p /var/caddy_data
        ExecStartPre=-/bin/podman kill caddy
        ExecStartPre=-/bin/podman rm caddy
        ExecStartPre=-/bin/podman pull docker.io/library/caddy:latest
        ExecStartPre=-/bin/podman network create caddybridge
        # Privileged mode is required for binding to local socket to work due to SELINUX (https://github.com/portainer/portainer/issues/849)
        ExecStart=/bin/podman run \
                    --privileged=true \
                    -p 80:80 \
                    -p 443:443 \
                    --name caddy \
                    --hostname caddy \
                    --network caddybridge \
                    --restart=always \
                    -v /etc/Caddyfile:/etc/caddy/Caddyfile \
                    -v /var/caddy_data:/root/.local/share/caddy \
                    docker.io/library/caddy:latest
        ExecStop=/bin/podman stop caddy

        [Install]
        WantedBy=multi-user.target
1 Like

Looks like a good start. We don’t have better podman integration for now so podman generate systemd is a good option.

You might also want to try podman compose or podman play kube.

2 Likes

I’m interested in Quadlet, and in specific work to integrate this into podman. The idea is that you just drop a file into /etc/containers/systemd. This is formatted like a normal systemd unit file, except it has instead of a long, complicated podman run line, it has a [Container] group. This way, it automatically takes care of boilerplate and best-practices, and seems a lot more maintainable.

I’m also very interested in Quadlet.

1 Like

This is fantastic. Thank you!
I will most definitely test this as soon as I can find some free time.