Ansible Automation For Ghosts - Semaphore UI
Mission of the Ghost
Ansible is a sharp blade.
- open source
- command line
- fast and efficient
- Ghost approved
For operators craving API-driven command, Semaphore rises from Ansible's silent core.
- open source
- fast, Go language based
- UI
- API
DeadSwitch maps it.
Requirements
- Debian 12 (with hardened kernel preferred)
- Podman installed and functional (v4 or later)
- Environment variables set securely or managed via
.env
- Terminal access with elevated privileges or configured rootless Podman
Step 1: Create the podman volume
Persistent volume for the MySQL data:
podman volume create semaphore_mysql
Step 2: Deploy containers with Podman Compose
With Podman Compose you can whisper to Podman and deploy the MySQL and Semaphore containers together.
In production you must use environment files:
env_file:
- .env
version: "3.9" services: mysql: image: docker.io/mysql:lts hostname: mysql volumes: - semaphore_mysql:/var/lib/mysql environment: MYSQL_RANDOM_ROOT_PASSWORD: 'yes' MYSQL_DATABASE: semaphore MYSQL_USER: semaphore MYSQL_PASSWORD: semaphore semaphore: image: docker.io/semaphoreui/semaphore:latest ports: - 3000:3000 environment: SEMAPHORE_DB_USER: semaphore SEMAPHORE_DB_PASS: semaphore SEMAPHORE_DB_HOST: mysql SEMAPHORE_DB_PORT: 3306 SEMAPHORE_DB_DIALECT: mysql SEMAPHORE_DB: semaphore SEMAPHORE_PLAYBOOK_PATH: /tmp/semaphore/ SEMAPHORE_ADMIN_PASSWORD: changeme SEMAPHORE_ADMIN_NAME: admin SEMAPHORE_ADMIN_EMAIL: admin@localhost SEMAPHORE_ADMIN: admin SEMAPHORE_ACCESS_KEY_ENCRYPTION: gs72mPntFATGJs9qK0pQ0rKtfidlexiMjYCH9gWKhTU= SEMAPHORE_LDAP_ACTIVATED: 'no' SEMAPHORE_LDAP_HOST: dc01.local.example.com SEMAPHORE_LDAP_PORT: '636' SEMAPHORE_LDAP_NEEDTLS: 'yes' SEMAPHORE_LDAP_DN_BIND: 'uid=bind_user,cn=users,cn=accounts,dc=local,dc=shiftsystems,dc=net' SEMAPHORE_LDAP_PASSWORD: 'ldap_bind_account_password' SEMAPHORE_LDAP_DN_SEARCH: 'dc=local,dc=example,dc=com' SEMAPHORE_LDAP_SEARCH_FILTER: "(\u0026(uid=%s)(memberOf=cn=ipausers,cn=groups,cn=accounts,dc=local,dc=example,dc=com))" TZ: UTC depends_on: - mysql volumes: semaphore_mysql:
Note: Podman Compose supports the same syntax as Docker Compose but is a separate tool. Install with:
pip install podman-compose
Deploy using:
podman-compose -f podman-compose.yaml up
Step 3: First contact
Initiate secure access using a hardened browser:
Credentials: whatever you defined in the environment above.
Step 4: Harden
This is only the echo.
- Wrap behind a reverse proxy (Caddy, Traefik, or Nginx).
- Enforce HTTPS (Let's Encrypt or internal CA).
- Rotate admin password. Strip LDAP if unused.
- Lock containers to loopback if accessed only locally.
- Use systemd units generated from Podman.
Your playbook is now mapped.
—
Write to DeadSwitch on Matrix: @deadswitch:matrix.org
Maybe he whispers back…
DeadSwitch | The Cyber Ghost
"In silence, we rise. In the switch, we fade."