https://github.com/noahwhite/alloy-sysext-build
Build systemd-sysext images for Grafana Alloy on Flatcar Container Linux
https://github.com/noahwhite/alloy-sysext-build
flatcar flatcar-linux grafana grafana-alloy observability sysext systemd-sysext
Last synced: 3 months ago
JSON representation
Build systemd-sysext images for Grafana Alloy on Flatcar Container Linux
- Host: GitHub
- URL: https://github.com/noahwhite/alloy-sysext-build
- Owner: noahwhite
- License: mit
- Created: 2026-01-20T02:01:57.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-03-10T00:04:23.000Z (3 months ago)
- Last Synced: 2026-03-10T07:35:33.458Z (3 months ago)
- Topics: flatcar, flatcar-linux, grafana, grafana-alloy, observability, sysext, systemd-sysext
- Language: Shell
- Homepage:
- Size: 118 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Grafana Alloy systemd-sysext Build Tooling
Build tooling for creating Grafana Alloy systemd-sysext images for Flatcar Container Linux.
## Purpose
This repository provides automated build tooling to package [Grafana Alloy](https://grafana.com/docs/alloy/) as a systemd-sysext image for Flatcar Container Linux. systemd-sysext allows you to extend the immutable Flatcar base system with additional binaries and services without modifying the root filesystem.
## What is systemd-sysext?
systemd-sysext (system extension) images provide a way to overlay additional files onto an immutable OS like Flatcar Container Linux. When merged, the files in the sysext image appear in the host filesystem at their defined paths (e.g., `/usr/local/bin/alloy`).
Key benefits:
- **Immutability**: Extends the system without modifying the base OS
- **Atomic operations**: Images are merged/unmerged as atomic units
- **Version management**: Easy to swap versions by changing which image is active
- **Persistence**: Survives OS updates
## Download Pre-built Images
Pre-built sysext images are available at:
```
https://ghost-sysext-images.separationofconcerns.dev/alloy-{VERSION}-amd64.raw
https://ghost-sysext-images.separationofconcerns.dev/alloy-{VERSION}-amd64.raw.sha256
```
Example in Butane configuration:
```yaml
storage:
files:
- path: /opt/extensions/alloy/alloy-1.10.2-amd64.raw
mode: 0644
contents:
source: https://ghost-sysext-images.separationofconcerns.dev/alloy-1.10.2-amd64.raw
verification:
hash: sha256-feb76c5aa5408c267d59508bd39d322c20d6fce44abd686296f4d0ca87e42671
links:
- target: /opt/extensions/alloy/alloy-1.10.2-amd64.raw
path: /etc/extensions/alloy.raw
hard: false
```
## Build Requirements
- Docker or Podman
- Internet connection (to download Alloy releases)
The build container includes all necessary tools:
- Ubuntu 22.04 base
- `curl`, `wget`, `unzip`
- `squashfs-tools` (for creating the image)
- `xz-utils` (for compression)
## Usage
### Build the Container Image
```bash
docker build -t alloy-sysext-builder .
```
### Run the Build
```bash
mkdir -p output
docker run --rm \
-v "${PWD}/output:/output" \
-v "${PWD}/build-alloy-sysext.sh:/build/build-alloy-sysext.sh:ro" \
alloy-sysext-builder \
/build/build-alloy-sysext.sh
```
This will:
1. Download the specified Alloy version from GitHub releases
2. Create the systemd-sysext directory structure
3. Install the Alloy binary
4. Generate a systemd service unit
5. Create extension metadata
6. Package everything into a squashfs image
7. Generate SHA256 checksums
### Customize the Build
Edit the configuration variables in `build-alloy-sysext.sh`:
```bash
VERSION="1.10.2" # Alloy version to build
ARCHITECTURE="amd64" # Target architecture
SYSEXT_NAME="alloy" # Extension name
```
## Output Format
The build produces the following files in the `output/` directory:
```
alloy-1.10.2-amd64.raw # Architecture-specific sysext image
alloy-1.10.2-amd64.raw.sha256 # SHA256 checksum
alloy-1.10.2.raw # Compatibility version (same content)
alloy-1.10.2.raw.sha256 # SHA256 checksum
```
### Sysext Image Contents
The sysext image contains:
```
/usr/local/bin/alloy # Alloy binary
/usr/lib/systemd/system/alloy.service # systemd unit
/usr/lib/extension-release.d/extension-release.alloy # Extension metadata
```
## Using the sysext Image on Flatcar
### 1. Copy the Image to Flatcar
```bash
scp output/alloy-1.10.2-amd64.raw core@your-flatcar-host:/var/lib/extensions/
```
### 2. Merge the Extension
```bash
systemd-sysext refresh
systemd-sysext list
```
### 3. Verify the Binary
```bash
which alloy
alloy --version
```
### 4. Configure and Enable the Service
Create your Alloy configuration:
```bash
sudo mkdir -p /var/mnt/storage/alloy
sudo vi /var/mnt/storage/alloy/config.alloy
```
Enable and start the service:
```bash
sudo systemctl daemon-reload
sudo systemctl enable alloy.service
sudo systemctl start alloy.service
sudo systemctl status alloy.service
```
### 5. View Logs
```bash
journalctl -u alloy.service -f
```
## systemd-sysext Image Format
The sysext image is a squashfs filesystem compressed with xz. It must include:
1. **Extension metadata** at `/usr/lib/extension-release.d/extension-release.`:
```
ID=_any
ARCHITECTURE=x86-64
```
- `ID=_any` makes it compatible with any OS (not just Flatcar)
- `ARCHITECTURE` must match the host architecture
2. **File hierarchy** under standard paths:
- `/usr/local/bin/` for binaries
- `/usr/lib/systemd/system/` for systemd units
- Other `/usr/` paths as needed
3. **Squashfs format** with xz compression for optimal size
## Service Configuration
The included systemd service (`alloy.service`) is configured with:
- **Config location**: `/var/mnt/storage/alloy/config.alloy`
- **State directory**: `/var/lib/alloy` (automatically created)
- **Security hardening**: NoNewPrivileges, ProtectSystem, ProtectHome, PrivateTmp
- **Automatic restart**: On failure with 10s delay
You can customize the service by editing `build-alloy-sysext.sh` before building.
## Automated Builds
GitHub Actions automatically builds new sysext images when:
- A new release is created in this repository
- The workflow is manually triggered with a version parameter
Built images are automatically uploaded to the Cloudflare R2 bucket.
## Repository Structure
```
.
├── Dockerfile # Container image for building sysext images
├── build-alloy-sysext.sh # Build script
├── README.md # This file
├── LICENSE # MIT License
└── .github/
└── workflows/
└── build-and-publish.yml # CI/CD pipeline (future)
```
## Updating Alloy
To update to a new Alloy version:
1. Update the `VERSION` variable in `build-alloy-sysext.sh`
2. Rebuild the image
3. Copy the new image to `/var/lib/extensions/` on your Flatcar host
4. Remove the old image
5. Run `systemd-sysext refresh`
6. Restart the service: `sudo systemctl restart alloy.service`
## Troubleshooting
### Extension not merging
Check extension status:
```bash
systemd-sysext status
```
Verify the image format:
```bash
unsquashfs -ll /var/lib/extensions/alloy-1.10.2-amd64.raw
```
### Service not starting
Check logs:
```bash
journalctl -u alloy.service -n 50
```
Verify binary:
```bash
file /usr/local/bin/alloy
/usr/local/bin/alloy --version
```
Check config syntax:
```bash
/usr/local/bin/alloy fmt /var/mnt/storage/alloy/config.alloy
```
## References
- [Grafana Alloy Documentation](https://grafana.com/docs/alloy/)
- [systemd-sysext Documentation](https://www.freedesktop.org/software/systemd/man/systemd-sysext.html)
- [Flatcar Container Linux Documentation](https://www.flatcar.org/docs/latest/)
## Contributing
Contributions are welcome! Please open an issue or pull request.
## License
MIT License - see [LICENSE](LICENSE) file for details.