#cloud-config
# Dokploy node bootstrap — Hetzner Cloud, Fedora 44 (x86)
# Automates tutorial steps 3 (base OS), 5 (Tailscale+SSH), 6 (Docker CE),
# and configures unattended SECURITY updates via dnf5-automatic.
# Role-specific steps stay manual by design: swarm init/join (§7, §9),
# Dokploy (§8), Traefik (§9-A) — they are sequential and node-specific.
#
# Before use: inject the Tailscale auth key (see tutorial §2-B):
#   sed "s|__TS_AUTHKEY__|$TS_AUTHKEY|" cloud-init-dokploy-node.yaml > /tmp/ci.yaml

package_update: true
package_upgrade: true          # full `dnf upgrade` on first boot (was manual step 3)

write_files:
  # Unattended-update policy. Deliberately conservative for a Swarm node:
  #  - security advisories only
  #  - never reboot unattended (3-manager quorum; timers fire within the same
  #    randomized hour on every node)
  #  - never touch the container engine unattended: a dockerd restart kills
  #    every task on the node, and live-restore does not apply in swarm mode
  #  - kernel changes only during deliberate §13 drain/reboot maintenance
  # Engine and kernel updates therefore follow the manual §13 procedure.
  - path: /etc/dnf/automatic.conf
    permissions: '0644'
    content: |
      [commands]
      upgrade_type = security
      apply_updates = yes
      reboot = never

      [emitters]
      emit_via = stdio

      [base]
      # Overrides dnf config for AUTOMATIC runs only —
      # a manual `dnf upgrade` still sees these packages.
      excludepkgs = docker-ce* docker-ce-cli containerd.io* docker-buildx-plugin docker-compose-plugin kernel*

runcmd:
  - set -e
  # Vendor repositories — identical sources to manual steps 5/6
  - curl -fsSL -o /etc/yum.repos.d/docker-ce.repo https://download.docker.com/linux/fedora/docker-ce.repo
  - curl -fsSL -o /etc/yum.repos.d/tailscale.repo https://pkgs.tailscale.com/stable/fedora/tailscale.repo
  # Latest Docker CE at provision time + Tailscale + the DNF5 automatic plugin
  - dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin tailscale dnf5-plugin-automatic
  - systemctl enable --now docker
  - systemctl enable --now tailscaled
  # Unattended tailnet join, Tailscale SSH enabled. Requires a REUSABLE,
  # TAGGED (tag:dokploy) auth key — see §2-B for the ACL prerequisites.
  # Device name defaults to the hostname Hetzner set from the server name.
  - tailscale up --ssh --authkey=__TS_AUTHKEY__
  - systemctl enable --now dnf5-automatic.timer
  # Sentinel: the reboot below only fires if everything above succeeded
  - touch /run/bootstrap-ok

# One clean reboot at the end — first-boot package_upgrade almost certainly
# staged a kernel. On failure the node stays up for debugging (public SSH
# works; see /var/log/cloud-init-output.log).
power_state:
  mode: reboot
  condition: test -f /run/bootstrap-ok
  message: "bootstrap complete, rebooting onto updated kernel"
