# 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`