๐ฎ Semaphore UI for Ansible on AlmaLinux: Simple Web Interface for Automation
Welcome to hassle-free Ansible automation! ๐ Ready to manage your playbooks with a beautiful web interface? Semaphore UI is the lightweight, open-source alternative to AWX and Ansible Tower, bringing simple automation to everyone! Itโs the platform that makes Ansible visual without the complexity! Think of it as your minimalist automation dashboard with all the power you need! ๐โจ
๐ค Why is Semaphore Important?
Semaphore transforms Ansible from CLI to web UI! ๐ Hereโs why itโs amazing:
- ๐ฏ Simple Interface - Clean and intuitive design!
- ๐ชถ Lightweight - Minimal resource requirements!
- ๐ Playbook Management - Visual playbook execution!
- ๐ฅ Team Collaboration - Share automation easily!
- ๐ Job Scheduling - Automate on schedule!
- ๐ Completely Free - Open source forever!
Itโs like having Ansible Tower without the complexity! ๐ฐ
๐ฏ What You Need
Before building your automation dashboard, ensure you have:
- โ AlmaLinux 9 server
- โ Root or sudo access
- โ At least 2GB RAM (4GB recommended)
- โ 2 CPU cores minimum
- โ 10GB free disk space
- โ Docker or Podman installed
- โ Love for simple solutions! ๐ฎ
๐ Step 1: System Preparation - Getting Ready!
Letโs prepare AlmaLinux 9 for Semaphore! ๐๏ธ
# Update system
sudo dnf update -y
# Install required packages
sudo dnf install -y git curl wget ansible-core python3-pip
# Install Docker if not already installed
sudo dnf install -y docker docker-compose
# Or use Podman as alternative
# sudo dnf install -y podman podman-compose
# Start Docker service
sudo systemctl start docker
sudo systemctl enable docker
# Check Docker is running
sudo systemctl status docker
# Add user to docker group
sudo usermod -aG docker $USER
# Log out and back in for group changes
# Install Docker Compose (if using Docker)
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
# Verify installations
docker --version
# Should show: Docker version 20.x.x
docker-compose --version
# Should show: docker-compose version 2.x.x
Configure firewall for Semaphore:
# Open required ports
sudo firewall-cmd --permanent --add-port=3000/tcp # Semaphore UI
sudo firewall-cmd --permanent --add-port=5432/tcp # PostgreSQL (internal)
sudo firewall-cmd --reload
# Verify ports
sudo firewall-cmd --list-ports
# Should show: 3000/tcp 5432/tcp
Perfect! System is ready! ๐ฏ
๐ง Step 2: Installing Semaphore - The Easy Way!
Semaphore installation is super simple with Docker! ๐
Using Docker Compose (Recommended):
# Create Semaphore directory
mkdir ~/semaphore
cd ~/semaphore
# Create docker-compose.yml
cat << 'EOF' > docker-compose.yml
version: '3'
services:
postgres:
image: postgres:14
hostname: postgres
environment:
POSTGRES_USER: semaphore
POSTGRES_PASSWORD: semaphore
POSTGRES_DB: semaphore
volumes:
- semaphore-postgres:/var/lib/postgresql/data
restart: unless-stopped
semaphore:
image: semaphoreui/semaphore:latest
ports:
- "3000:3000"
environment:
SEMAPHORE_DB_USER: semaphore
SEMAPHORE_DB_PASS: semaphore
SEMAPHORE_DB_HOST: postgres
SEMAPHORE_DB_PORT: 5432
SEMAPHORE_DB_DIALECT: postgres
SEMAPHORE_DB: semaphore
SEMAPHORE_PLAYBOOK_PATH: /tmp/semaphore/
SEMAPHORE_ADMIN_PASSWORD: admin
SEMAPHORE_ADMIN_NAME: admin
SEMAPHORE_ADMIN_EMAIL: admin@localhost
SEMAPHORE_ADMIN: admin
SEMAPHORE_ACCESS_KEY_ENCRYPTION: gs72mPntFATGJs9qK0pQ0rKtfidlexiMjYCH9gWKhTU=
SEMAPHORE_LDAP_ACTIVATED: 'no'
TZ: America/New_York
volumes:
- semaphore-data:/var/lib/semaphore
- ./inventory:/inventory
- ./playbooks:/playbooks
depends_on:
- postgres
restart: unless-stopped
volumes:
semaphore-postgres:
semaphore-data:
EOF
# Create directories for playbooks and inventory
mkdir playbooks inventory
# Start Semaphore
docker-compose up -d
# Check if containers are running
docker-compose ps
# Should show both postgres and semaphore running
# View logs
docker-compose logs -f semaphore
# Wait for "Semaphore started" message
Alternative: Manual Docker Installation:
# Create PostgreSQL container
docker run -d \
--name semaphore-postgres \
-e POSTGRES_USER=semaphore \
-e POSTGRES_PASSWORD=semaphore \
-e POSTGRES_DB=semaphore \
-v semaphore-postgres:/var/lib/postgresql/data \
postgres:14
# Create Semaphore container
docker run -d \
--name semaphore \
--link semaphore-postgres:postgres \
-p 3000:3000 \
-e SEMAPHORE_DB_USER=semaphore \
-e SEMAPHORE_DB_PASS=semaphore \
-e SEMAPHORE_DB_HOST=postgres \
-e SEMAPHORE_DB_PORT=5432 \
-e SEMAPHORE_DB_DIALECT=postgres \
-e SEMAPHORE_DB=semaphore \
-e SEMAPHORE_PLAYBOOK_PATH=/tmp/semaphore/ \
-e SEMAPHORE_ADMIN_PASSWORD=admin \
-e SEMAPHORE_ADMIN_NAME=admin \
-e SEMAPHORE_ADMIN_EMAIL=admin@localhost \
-e SEMAPHORE_ADMIN=admin \
-v semaphore-data:/var/lib/semaphore \
semaphoreui/semaphore:latest
# Verify containers
docker ps
# Should show both containers running
๐ Step 3: Accessing Semaphore - Your Automation UI!
Time to access your new UI! ๐ฎ
First Login:
# Get your server IP
ip addr show | grep inet
# Note your server IP address
# Access Semaphore
# URL: http://your-server-ip:3000
# Username: admin
# Password: admin
# IMPORTANT: Change admin password immediately!
Initial Setup Steps:
- Open browser to
http://your-server-ip:3000
- Login with admin/admin
- Change password immediately!
- Youโre in Semaphore! ๐
Dashboard shows:
- ๐ Dashboard - Overview of activity
- ๐ Projects - Your automation projects
- ๐ Task Templates - Playbook definitions
- ๐๏ธ Inventory - Managed hosts
- ๐ Key Store - SSH keys and credentials
- ๐ฅ Users - Team management
โ Step 4: Setting Up Your First Project - Letโs Automate!
Time to create your first automation project! ๐ฏ
Create SSH Key:
# Generate SSH key for Ansible
ssh-keygen -t ed25519 -f ~/.ssh/ansible_key -N ""
# Copy public key to managed hosts
ssh-copy-id -i ~/.ssh/ansible_key.pub user@target-host
# Get private key content
cat ~/.ssh/ansible_key
# Copy this for Semaphore
In Semaphore UI:
1. Add SSH Key:
- Click โKey Storeโ โ โNew Keyโ
- Fill in:
- Name:
Ansible SSH Key
- Type:
SSH Key
- Private Key: (paste your private key)
- Name:
- Save
2. Create Project:
- Click โProjectsโ โ โNew Projectโ
- Configure:
- Name:
My First Project
- Alert: Disabled (for now)
- Name:
- Save
3. Add Repository:
- In Project, click โRepositoriesโ โ โNew Repositoryโ
- Configure:
- Name:
Local Playbooks
- URL:
file:///playbooks
- Branch:
master
- Access Key: None (local file)
- Name:
- Save
4. Create Inventory:
- Click โInventoryโ โ โNew Inventoryโ
- Configure:
- Name:
Production Servers
- Type:
Static
- Inventory Content:
[webservers] web01 ansible_host=192.168.1.10 web02 ansible_host=192.168.1.11 [dbservers] db01 ansible_host=192.168.1.20 [all:vars] ansible_user=ansible ansible_ssh_private_key_file=/tmp/semaphore/ansible_key
- Name:
- Save
๐ Step 5: Creating Task Templates - Automation Blueprints!
Letโs create reusable automation tasks! ๐ฏ
Create Sample Playbook:
# Create playbook in mounted directory
cat << 'EOF' > ~/semaphore/playbooks/install-nginx.yml
---
- name: Install and Configure Nginx
hosts: webservers
become: yes
tasks:
- name: Install Nginx
dnf:
name: nginx
state: present
- name: Start Nginx service
systemd:
name: nginx
state: started
enabled: yes
- name: Configure firewall
firewalld:
service: http
permanent: yes
state: enabled
immediate: yes
EOF
Create Task Template:
- Click โTask Templatesโ โ โNew Templateโ
- Configure:
- Name:
Install Nginx
- Playbook:
install-nginx.yml
- Inventory:
Production Servers
- Repository:
Local Playbooks
- Environment:
{}
- Vault Password: (leave empty)
- Type:
Task
- Name:
- Save
Run Task:
- Click โRunโ button on template ๐
- Watch real-time output!
- Task completes successfully! โ
๐ฎ Quick Examples
Example 1: Scheduled Tasks
Create scheduled automation:
# Create backup playbook
cat << 'EOF' > ~/semaphore/playbooks/backup.yml
---
- name: Backup Databases
hosts: dbservers
become: yes
tasks:
- name: Create backup directory
file:
path: /backup
state: directory
- name: Backup MySQL databases
mysql_db:
state: dump
name: all
target: /backup/mysql-{{ ansible_date_time.date }}.sql
- name: Compress backup
archive:
path: /backup/*.sql
dest: /backup/mysql-{{ ansible_date_time.date }}.tar.gz
format: gz
EOF
# In Semaphore:
# 1. Create Task Template for backup
# 2. Click "Schedule" on template
# 3. Set cron expression: "0 2 * * *" (2 AM daily)
# 4. Save schedule
Example 2: Multi-Environment Setup
# Development inventory
cat << 'EOF' > ~/semaphore/inventory/dev.ini
[webservers]
dev-web01 ansible_host=10.0.1.10
[dbservers]
dev-db01 ansible_host=10.0.1.20
[all:vars]
environment=development
EOF
# Production inventory
cat << 'EOF' > ~/semaphore/inventory/prod.ini
[webservers]
prod-web01 ansible_host=192.168.1.10
prod-web02 ansible_host=192.168.1.11
[dbservers]
prod-db01 ansible_host=192.168.1.20
[all:vars]
environment=production
EOF
# Create separate templates for each environment
Example 3: GitLab Integration
# Use Git repository instead of local files
# In Semaphore Repository settings:
# URL: https://gitlab.com/youruser/ansible-playbooks.git
# Branch: main
# Access Key: (Create deploy key in GitLab)
# Auto-sync on push with webhook:
# GitLab โ Settings โ Webhooks
# URL: http://semaphore-server:3000/api/project/1/repositories/1/refresh
# Token: (from Semaphore API)
๐จ Fix Common Problems
Problem 1: Cannot Connect to Hosts
Symptom: SSH connection fails ๐ฐ
Fix:
# Test SSH from Semaphore container
docker exec -it semaphore /bin/sh
$ ssh ansible@target-host
# If fails, check SSH key
# Verify key permissions
chmod 600 ~/.ssh/ansible_key
# Add host to known_hosts
ssh-keyscan -H target-host >> ~/.ssh/known_hosts
# Copy known_hosts to container
docker cp ~/.ssh/known_hosts semaphore:/tmp/semaphore/
Problem 2: Playbook Not Found
Symptom: Task fails with โplaybook not foundโ ๐
Fix:
# Check playbook location
docker exec semaphore ls -la /playbooks/
# Verify mount in docker-compose.yml
# volumes:
# - ./playbooks:/playbooks
# Restart containers
docker-compose restart
# Use absolute path in template
# Playbook: /playbooks/install-nginx.yml
Problem 3: Database Connection Error
Symptom: Semaphore wonโt start ๐ด
Fix:
# Check PostgreSQL is running
docker ps | grep postgres
# View PostgreSQL logs
docker logs semaphore-postgres
# Test connection
docker exec -it semaphore-postgres psql -U semaphore -d semaphore
# Reset database if needed
docker-compose down -v
docker-compose up -d
# Wait for initialization
docker-compose logs -f semaphore
๐ Simple Commands Summary
Task | Command | Purpose |
---|---|---|
Start Semaphore | docker-compose up -d | Launch services |
Stop Semaphore | docker-compose down | Stop services |
View logs | docker-compose logs -f | Monitor output |
Restart | docker-compose restart | Restart services |
Update | docker-compose pull && docker-compose up -d | Update images |
Backup DB | docker exec semaphore-postgres pg_dump -U semaphore semaphore > backup.sql | Database backup |
Shell access | docker exec -it semaphore /bin/sh | Container shell |
Check status | docker-compose ps | Service status |
๐ก Tips for Success
๐ Performance Optimization
Make Semaphore super fast:
# Increase container resources
# In docker-compose.yml:
services:
semaphore:
mem_limit: 2g
cpus: 2
# Enable Ansible pipelining
# In ansible.cfg:
[ssh_connection]
pipelining = True
# Use fact caching
[defaults]
gathering = smart
fact_caching = jsonfile
fact_caching_connection = /tmp/facts_cache
fact_caching_timeout = 86400
๐ Security Best Practices
Keep Semaphore secure:
- Use HTTPS - Add reverse proxy with SSL! ๐
- Strong passwords - Change defaults immediately! ๐
- Limit access - Use firewall rules! ๐ก๏ธ
- Vault integration - Encrypt sensitive data! ๐
- Regular updates - Keep containers updated! ๐ฆ
# Setup HTTPS with Nginx
sudo dnf install -y nginx certbot
# Configure reverse proxy
cat << 'EOF' > /etc/nginx/conf.d/semaphore.conf
server {
listen 443 ssl;
server_name semaphore.example.com;
ssl_certificate /etc/letsencrypt/live/semaphore.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/semaphore.example.com/privkey.pem;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
๐ Monitoring and Backup
Keep Semaphore healthy:
# Automated backups
cat << 'EOF' > backup-semaphore.sh
#!/bin/bash
BACKUP_DIR="/backup/semaphore"
DATE=$(date +%Y%m%d)
# Create backup directory
mkdir -p $BACKUP_DIR
# Backup database
docker exec semaphore-postgres pg_dump -U semaphore semaphore > $BACKUP_DIR/semaphore-$DATE.sql
# Backup data volumes
docker run --rm -v semaphore-data:/data -v $BACKUP_DIR:/backup alpine tar czf /backup/semaphore-data-$DATE.tar.gz /data
# Keep only last 7 days
find $BACKUP_DIR -name "*.sql" -mtime +7 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +7 -delete
EOF
chmod +x backup-semaphore.sh
# Add to cron for daily backups
๐ What You Learned
Youโre now a Semaphore UI expert! ๐ Youโve successfully:
- โ Installed Semaphore on AlmaLinux 9
- โ Deployed with Docker Compose
- โ Created projects and inventories
- โ Built task templates
- โ Scheduled automation tasks
- โ Managed playbooks visually
- โ Mastered simple automation UI
Your automation platform is lightweight and powerful! ๐ฎ
๐ฏ Why This Matters
Semaphore transforms Ansible automation! With your simple UI, you can:
- ๐ Automate easily - Visual interface for everyone!
- ๐ฅ Collaborate simply - Share automation tasks!
- ๐ Schedule smartly - Set and forget!
- ๐ชถ Run lightweight - Minimal resources needed!
- ๐ฐ Save money - Free and open source!
Youโre not just running playbooks - youโre making automation accessible to your entire team! Every task is visual, every execution is tracked! ๐ญ
Keep automating, keep simplifying, and remember - with Semaphore, Ansible automation is beautiful and easy! โญ
May your playbooks run smoothly and your automation stay simple! ๐๐ฎ๐