- Jinja 78.4%
- Shell 9.8%
- Makefile 6.1%
- Dockerfile 5.7%
|
All checks were successful
CI / validate (push) Successful in 12s
Reviewed-on: #3 |
||
|---|---|---|
| .forgejo/workflows | ||
| .github/workflows | ||
| ansible | ||
| control-node | ||
| docker | ||
| .gitignore | ||
| .yamllint | ||
| compose.yml | ||
| Makefile | ||
| README.md | ||
Foundry
Foundry is the configuration repository for a personal Ubuntu homelab server. The repo is centered on Ansible-managed host provisioning, with Docker service configuration kept alongside the playbooks that deploy it.
Note: the copy on GitHub is an intentional read-only mirror. Primary development and CI run on Codeberg.
What This Manages
- Baseline Ansible connectivity for the
foundryhost - Apt mirror pinning for faster Ubuntu package installs
- General-purpose system packages such as
ffmpeg - Human user accounts, shell setup, SSH access, and developer CLIs
- Tailscale enrollment and advertised subnet routes
- Thunderbolt-attached storage mounted at
/mnt/store - Tailnet-only SMB sharing from
/mnt/store/share - Docker Engine and the Plex, Jellyfin, Forgejo, and Caddy Compose services
under
docker/, with Caddy reverse proxying them at*.emkaytec.com - Self-managed
ansible-pullconvergence through a systemd timer - Explicit system package maintenance through a dedicated update playbook
Repository Layout
.
ansible/ Ansible inventory, playbooks, roles, and operator docs
control-node/ Image for running Ansible locally without installing it
docker/ Compose files deployed by the Ansible Docker role
The detailed runbook lives in ansible/README.md. Start
there for manual server prerequisites, collection installation, baseline
provisioning, individual playbook commands, vault usage, and maintenance tasks.
Local Ansible runs expect ansible/.vault-password to exist because
ansible/ansible.cfg points at it; the file is ignored by git.
Common Commands
Run commands from the Ansible directory so the repo-local ansible.cfg is used:
cd ansible
ansible-playbook foundry.yml
Running Without Installing Ansible
The repo-root compose.yml builds a disposable control-node container from
control-node/ so the playbooks can run from any machine with Docker, no
local Ansible install required. From the repo root:
make dev # interactive shell
make dev CMD="ansible-playbook foundry.yml" # one-off run
make dev resolves the Ansible vault password from 1Password on the host
(where Touch ID works) before handing off to docker compose run --rm ansible. The raw compose command works too; vaulted playbooks then just need
FOUNDRY_VAULT_PASSWORD exported first (see below).
The container mounts the repo at /workspace, starts in /workspace/ansible
so the repo-local ansible.cfg applies, and mounts the host's ~/.ssh
read-only so the foundry-admin SSH alias and known_hosts carry over. SSH
auth flows through the ssh-agent socket the Docker VM forwards at
/run/host-services/ssh-auth.sock — Colima and Docker Desktop both expose it
at that path. The entrypoint strips macOS-only UseKeychain/IdentityAgent
lines from the container's copy of the SSH config, so the 1Password agent
works through that forwarding instead of its Mac socket path.
Two pieces of one-time Docker VM configuration are required (already applied
to the local Colima profile in ~/.colima/default/colima.yaml):
- the repo's volume must be shared into the VM — for Colima that means a
mounts:entry for/Volumes/Bolt(note that listing any custom mount replaces the defaults, so~and/tmp/colimamust be re-listed too); for Docker Desktop, add it under File Sharing - agent forwarding must be on —
forwardAgent: truefor Colima, which is what populates/run/host-services/ssh-auth.sockin the VM
The vault password is not stored on disk. ansible/.vault-password is a
dual-mode helper script: when FOUNDRY_VAULT_PASSWORD is set it prints that,
otherwise it reads op://Private/Foundry Ansible Vault/password through the
1Password CLI. On the Mac the op path runs directly; inside the container
(which has no op) the make dev target resolves the password on the host
first and passes it in through the FOUNDRY_VAULT_PASSWORD environment
variable declared in compose.yml. The container entrypoint wires the helper
into Ansible (ANSIBLE_VAULT_PASSWORD_FILE) only when that variable is set,
so password-less sessions still run everything except vault decryption.
This compose file is purely a local development tool; the Compose files that
Ansible deploys to the server live in docker/.
Run package maintenance explicitly:
cd ansible
ansible-playbook playbooks/system-updates.yml
The update playbook reports whether a reboot is required. To reboot automatically only when required:
cd ansible
ansible-playbook playbooks/system-updates.yml -e system_updates_reboot=true
Local Private Values
Committed Ansible defaults are intentionally public-safe. Host-specific human
user details belong in ansible/group_vars/all/99-private.yml, which is ignored
by git and loaded by Ansible when present.