Files
homelab/docs/semaphore.md
Hermes Agent service account 6e50461999 docs: add comprehensive Semaphore deployment and setup guide
- Covers deployment, initial setup, DNS/Traefik, GitOps approach, and troubleshooting
2026-05-27 21:57:02 -05:00

101 lines
3.3 KiB
Markdown

# Semaphore UI
This document describes the deployment, initial setup, and ongoing management of [Semaphore UI](https://semaphoreui.com/) in mk-labs.
## Overview
Semaphore is deployed as a rootless Podman container on `figment` using a systemd quadlet managed by Ansible. It uses BoltDB for its database and is exposed via Traefik with Cloudflare TLS.
## Deployment
The deployment is handled by the `semaphore` Ansible role:
- **Role location**: `ansible/roles/semaphore/`
- **Playbook**: `playbooks/deploy_semaphore.yml`
- **Container**: Managed via quadlet at `/etc/systemd/system/container-semaphore.service`
- **Image**: `semaphoreui/semaphore:latest`
Key features of the role:
- Creates dedicated `cast` user/group
- Manages data and config directories
- Generates systemd quadlet with proper rootless volume flags (`:Z,U`)
- Creates `config.json` for non-interactive BoltDB startup
- Idempotently creates the initial admin user (when `semaphore_admin_password` is defined in vault)
## Initial Setup
### 1. Deploy the container
```bash
ansible-playbook -i inventory.yml playbooks/deploy_semaphore.yml --limit figment
```
### 2. Create the initial admin user
The role will attempt to create the admin user defined in the defaults/vault. If this fails or you need to do it manually:
```bash
sudo podman exec semaphore semaphore user add --admin \
--login admin \
--name "Administrator" \
--email admin@local.mk-labs.cloud \
--password 'YourStrongPassword'
```
### 3. Access the UI
- `https://semaphore.local.mk-labs.cloud`
- `https://imagineering.local.mk-labs.cloud`
## DNS / Traefik
Traefik dynamic configuration is located at:
- `boilerplates/traefik/dynamic/semaphore.yml`
This file defines two hostnames:
- `semaphore.local.mk-labs.cloud`
- `imagineering.local.mk-labs.cloud`
Both point to `figment:3000` and use the `cloudflare` certificate resolver.
DNS records are managed via `playbooks/add_service_route.yml`, which now supports multiple hostnames per service config file.
## GitOps Approach
The goal is to manage as much of Semaphore as possible through Git and Ansible:
- **Projects, repositories, inventories, and task templates** should be defined and synced via the Semaphore API using Ansible.
- The initial admin user creation is handled idempotently by the role.
- Future enhancements will include a dedicated playbook/role for syncing Semaphore configuration from the repository.
## Variables
### Required Vault Variables
Add the following to your vault:
```yaml
vault_semaphore_admin_password: "your-strong-password"
```
### Role Defaults
See `ansible/roles/semaphore/defaults/main.yml` for all configurable values (admin user details, container settings, paths, etc.).
## Authentik Integration (Planned)
OIDC integration with Authentik is planned. Once enabled, local authentication can be disabled or restricted to an emergency admin account.
## Troubleshooting
- **Container fails to start**: Check `journalctl -u container-semaphore.service`
- **Permission issues with BoltDB**: Ensure the `:U` volume flag is present in the quadlet and directories are owned by the `cast` user.
- **No admin user**: Re-run the role or create the user manually via `podman exec`.
## References
- Semaphore documentation: https://docs.semaphoreui.com/
- Role source: `ansible/roles/semaphore/`
- Traefik config: `boilerplates/traefik/dynamic/semaphore.yml`