mirror of
https://github.com/jbowdre/runtimeterror.git
synced 2024-11-28 17:32:18 +00:00
new draft: automate-proxmox-packer-builds-github-actions
This commit is contained in:
parent
8c14234cab
commit
0a9c73dbd0
1 changed files with 128 additions and 0 deletions
|
@ -0,0 +1,128 @@
|
|||
---
|
||||
title: "Automate Proxmox Packer Builds Github Actions"
|
||||
date: 2024-07-21
|
||||
# lastmod: 2024-07-21
|
||||
draft: true
|
||||
description: "This is a new post about..."
|
||||
featured: false
|
||||
toc: true
|
||||
reply: true
|
||||
categories: Code
|
||||
tags:
|
||||
- api
|
||||
- automation
|
||||
- containers
|
||||
- docker
|
||||
- iac
|
||||
- linux
|
||||
- packer
|
||||
- proxmox
|
||||
- selfhosting
|
||||
- shell
|
||||
- tailscale
|
||||
---
|
||||
|
||||
I recently shared how I [set up Packer to build Proxmox templates](building-proxmox-templates-packer) in my homelab. That post covered storing (and retrieving) environment-specific values in Vault, the `cloud-init` configuration for definiting the installation parameters, the various post-install scripts for further customizing and hardening the template, and the Packer template files that tie it all together. By the end of the post, I was able to simply run `./build.sh ubuntu2204` to kick the build of a new Ubuntu 22.04 template without having to do any other interaction with the process.
|
||||
|
||||
That's pretty slick, but *The Dream* is to not have to do anything at all. So that's what this post is about: describing setting up a rootless self-hosted GitHub Actions Runner to perform the build, and the GitHub Actions workflows to trigger it.
|
||||
|
||||
### Self-Hosted Runner
|
||||
When a GitHub Actions workflow fires, it schedules the job(s) to run on GitHub's own infrastructure. That's easy and convenient, but can make things tricky when you need a workflow to interact with on-prem infrastructure. I've worked around that in the past by [configuring the runner to connect to my tailnet](/gemini-capsule-gempost-github-actions/#publish-github-actions), but given the amount of data that will need to be transferred during the Packer build I decided that a [self-hosted runner](https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners) would be a better solution.
|
||||
|
||||
I wanted my runner to execute the build inside of a Docker container so that I could control that environment a bit more, and I also wanted to ensure that it would run [without elevated permissions](https://docs.docker.com/engine/security/rootless/). It took a bit of fiddling to get there, but I'm pretty pleased with the result!
|
||||
|
||||
I started by cloning a fresh Ubuntu 22.04 VM off of my new template. After doing the basic initial setup (setting the hostname and IP, connecting it Tailscale), I then created a user account for the runner to use. That account will need sudo privileges during the initial setup, but then I can revoke that access. I also set a password for the account.
|
||||
|
||||
```shell
|
||||
sudo useradd -m -G sudo -s $(which bash) github # [tl! .cmd:1]
|
||||
sudo passwd github
|
||||
```
|
||||
|
||||
I then installed the `systemd-container` package so that I could use [`machinectl`](https://www.man7.org/linux/man-pages/man1/machinectl.1.html) to log in as the new user (since [`sudo su` won't work for the rootless setup](https://docs.docker.com/engine/security/rootless/#unable-to-install-with-systemd-when-systemd-is-present-on-the-system)).
|
||||
|
||||
```shell
|
||||
sudo apt update # [tl! .cmd:2]
|
||||
sudo apt install systemd-container
|
||||
sudo machinectl shell github@
|
||||
```
|
||||
|
||||
And I installed the `uidmap` package since rootless Docker requires `newuidmap` and `newgidmap`:
|
||||
|
||||
```shell
|
||||
sudo apt install uidmap # [tl! .cmd]
|
||||
```
|
||||
|
||||
At this point, I just followed the usual [Docker installation instructions](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository):
|
||||
|
||||
```shell
|
||||
# Add Docker's official GPG key:
|
||||
sudo apt-get update # [tl! .cmd:4]
|
||||
sudo apt-get install ca-certificates curl
|
||||
sudo install -m 0755 -d /etc/apt/keyrings
|
||||
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||
sudo chmod a+r /etc/apt/keyrings/docker.asc
|
||||
|
||||
# Add the repository to Apt sources:
|
||||
echo \ # [tl! .cmd]
|
||||
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
|
||||
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
|
||||
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
sudo apt-get update # [tl! .cmd]
|
||||
|
||||
sudo apt-get install \ # [tl! .cmd]
|
||||
docker-ce \
|
||||
docker-ce-cli \
|
||||
containerd.io \
|
||||
docker-buildx-plugin \
|
||||
docker-compose-plugin
|
||||
```
|
||||
|
||||
Then the actual rootless setup can begin. That starts by disabling the existing Docker service and socket and then running the `dockerd-rootless-setuptool.sh` script:
|
||||
|
||||
```shell
|
||||
sudo systemctl disable --now docker.service docker.socket # [tl! .cmd:1]
|
||||
sudo rm /var/run/docker.sock
|
||||
|
||||
dockerd-rootless-setuptool.sh install # [tl! .cmd]
|
||||
```
|
||||
|
||||
After that, I started and enabled the service in the user context and enabled "linger" for the `github` user so that its systemd instance can continue to function even while the user is not logged in:
|
||||
|
||||
```shell
|
||||
systemctl --user start docker # [tl! .cmd:2]
|
||||
systemctl --user enable docker
|
||||
sudo loginctl enable-linger $(whoami)
|
||||
```
|
||||
|
||||
That should take care of setting up Docker, and I can quickly confirm by spawning the `hello-world` container:
|
||||
|
||||
```shell
|
||||
docker run hello-world # [tl! .cmd]
|
||||
Unable to find image 'hello-world:latest' locally # [tl! .nocopy:25]
|
||||
latest: Pulling from library/hello-world
|
||||
c1ec31eb5944: Pull complete
|
||||
Digest: sha256:1408fec50309afee38f3535383f5b09419e6dc0925bc69891e79d84cc4cdcec6
|
||||
Status: Downloaded newer image for hello-world:latest
|
||||
|
||||
Hello from Docker!
|
||||
This message shows that your installation appears to be working correctly.
|
||||
|
||||
To generate this message, Docker took the following steps:
|
||||
1. The Docker client contacted the Docker daemon.
|
||||
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
|
||||
(amd64)
|
||||
3. The Docker daemon created a new container from that image which runs the
|
||||
executable that produces the output you are currently reading.
|
||||
4. The Docker daemon streamed that output to the Docker client, which sent it
|
||||
to your terminal.
|
||||
|
||||
To try something more ambitious, you can run an Ubuntu container with:
|
||||
$ docker run -it ubuntu bash
|
||||
|
||||
Share images, automate workflows, and more with a free Docker ID:
|
||||
https://hub.docker.com/
|
||||
|
||||
For more examples and ideas, visit:
|
||||
https://docs.docker.com/get-started/
|
||||
```
|
||||
|
Loading…
Reference in a new issue