jenkins
gentoo
fiber
+
cdn
cobol
+
spring
+
hack
{}
+
+
+
โˆš
+
+
+
+
+
fortran
sails
+
wsl
+
--
nomad
fortran
+
+
terraform
+
โ‰ˆ
gatsby
strapi
+
+
keras
//
chef
graphql
+
solid
+
+
+
+
+
_
aurelia
+
fedora
influxdb
+
+
+
meteor
meteor
+
jax
+
terraform
+
aurelia
bsd
+
elementary
wsl
neo4j
puppet
~
linux
+
+
+
elementary
astro
+
vim
+
+
+
rest
+
+
micronaut
django
wsl
termux
grafana
Back to Blog
๐ŸŽฎ Semaphore UI for Ansible on AlmaLinux: Simple Web Interface for Automation
semaphore ansible almalinux

๐ŸŽฎ Semaphore UI for Ansible on AlmaLinux: Simple Web Interface for Automation

Published Sep 6, 2025

Master Semaphore UI on AlmaLinux! Learn installation, playbook management, job scheduling, and team collaboration. Perfect lightweight alternative to AWX/Tower!

5 min read
0 views
Table of Contents

๐ŸŽฎ 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! ๐Ÿš€

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

  1. Open browser to http://your-server-ip:3000
  2. Login with admin/admin
  3. Change password immediately!
  4. 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:

  1. Click โ€œKey Storeโ€ โ†’ โ€œNew Keyโ€
  2. Fill in:
    • Name: Ansible SSH Key
    • Type: SSH Key
    • Private Key: (paste your private key)
  3. Save

2. Create Project:

  1. Click โ€œProjectsโ€ โ†’ โ€œNew Projectโ€
  2. Configure:
    • Name: My First Project
    • Alert: Disabled (for now)
  3. Save

3. Add Repository:

  1. In Project, click โ€œRepositoriesโ€ โ†’ โ€œNew Repositoryโ€
  2. Configure:
    • Name: Local Playbooks
    • URL: file:///playbooks
    • Branch: master
    • Access Key: None (local file)
  3. Save

4. Create Inventory:

  1. Click โ€œInventoryโ€ โ†’ โ€œNew Inventoryโ€
  2. 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
  3. 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:

  1. Click โ€œTask Templatesโ€ โ†’ โ€œNew Templateโ€
  2. Configure:
    • Name: Install Nginx
    • Playbook: install-nginx.yml
    • Inventory: Production Servers
    • Repository: Local Playbooks
    • Environment: {}
    • Vault Password: (leave empty)
    • Type: Task
  3. Save

Run Task:

  1. Click โ€œRunโ€ button on template ๐Ÿš€
  2. Watch real-time output!
  3. 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

TaskCommandPurpose
Start Semaphoredocker-compose up -dLaunch services
Stop Semaphoredocker-compose downStop services
View logsdocker-compose logs -fMonitor output
Restartdocker-compose restartRestart services
Updatedocker-compose pull && docker-compose up -dUpdate images
Backup DBdocker exec semaphore-postgres pg_dump -U semaphore semaphore > backup.sqlDatabase backup
Shell accessdocker exec -it semaphore /bin/shContainer shell
Check statusdocker-compose psService 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:

  1. Use HTTPS - Add reverse proxy with SSL! ๐Ÿ”
  2. Strong passwords - Change defaults immediately! ๐Ÿ”‘
  3. Limit access - Use firewall rules! ๐Ÿ›ก๏ธ
  4. Vault integration - Encrypt sensitive data! ๐Ÿ”“
  5. 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! ๐Ÿš€๐ŸŽฎ๐Ÿ™Œ