Semaphore Installation & Configuration Guide
Prerequisites
- Linux x86_64 host with systemd
dnforyumpackage manager (RHEL/Fedora/CentOS)- MySQL/MariaDB database server
- Root/sudo privileges
Installation Instructions
Step 1: Get the Latest Version
Optionally fetch the latest release version:
VERSION=$(curl -s https://api.github.com/repos/semaphoreui/semaphore/releases/latest \
| grep '"tag_name"' \
| sed -E 's/.*"v?([^"]+)".*/\1/')
echo "Latest Semaphore version: $VERSION"
Step 2: Install the RPM Package
Install Semaphore from the GitHub releases (RPM-based distributions):
VERSION=$(curl -s https://api.github.com/repos/semaphoreui/semaphore/releases/latest | grep '"tag_name"' | sed -E 's/.*"v?([^"]+)".*/\1/')
sudo dnf install -y https://github.com/semaphoreui/semaphore/releases/download/v${VERSION}/semaphore_${VERSION}_linux_amd64.rpm
Step 3: Verify Installation
Check that Semaphore was installed successfully:
Step 4: Generate Configuration File
Run the interactive setup to generate the configuration file and initialize the installation:
This will prompt you for: - Database connection details (host, user, password, database name) - Admin account credentials - Encryption keys
Alternatively, manually create /etc/semaphore_config.json (see configuration section below).
Step 5: Create Encryption Keys
Generate three cryptographically secure keys for the configuration:
openssl rand -base64 32 # cookie_hash
openssl rand -base64 32 # cookie_encryption
openssl rand -base64 32 # access_key_encryption
Step 6: Enable and Start Service
Enable Semaphore to start on boot and start the service:
Step 7: Verify Service Status
Check that the service is running:
Step 8: Access Semaphore
Access the web interface (default):
Step 9: Upgrade Semaphore
When upgrading to a newer version:
VERSION=$(curl -s https://api.github.com/repos/semaphoreui/semaphore/releases/latest | grep '"tag_name"' | sed -E 's/.*"v?([^"]+)".*/\1/')
sudo dnf install -y https://github.com/semaphoreui/semaphore/releases/download/v${VERSION}/semaphore_${VERSION}_linux_amd64.rpm
sudo systemctl restart semaphore
sudo systemctl status semaphore
Systemd Service Configuration
The RPM package automatically installs a systemd unit at /etc/systemd/system/semaphore.service. The service is managed through standard systemd commands.
Service Management
| Command | Purpose |
|---|---|
sudo systemctl start semaphore |
Start the service |
sudo systemctl stop semaphore |
Stop the service |
sudo systemctl restart semaphore |
Restart the service |
sudo systemctl status semaphore |
Check service status |
sudo systemctl enable semaphore |
Enable on boot |
sudo systemctl disable semaphore |
Disable on boot |
Service Logs
View service logs using journalctl:
# View last 50 lines
sudo journalctl -u semaphore -n 50
# Follow logs in real-time
sudo journalctl -u semaphore -f
# View all logs without paging
sudo journalctl -u semaphore --no-pager
# View logs since last boot
sudo journalctl -u semaphore -b
Configuration File
Place the configuration file at /etc/semaphore_config.json. This file contains all settings for database, security, and web server configuration.
Generating Encryption Keys
Before creating the configuration, generate three secure encryption keys:
# Generate and save each key
KEY1=$(openssl rand -base64 32)
KEY2=$(openssl rand -base64 32)
KEY3=$(openssl rand -base64 32)
echo "cookie_hash: $KEY1"
echo "cookie_encryption: $KEY2"
echo "access_key_encryption: $KEY3"
Sample Configuration
{
"mysql": {
"host": "127.0.0.1:3306",
"user": "semaphore",
"pass": "your_secure_password",
"name": "semaphore"
},
"dialect": "mysql",
"tmp_path": "/srv/ansible",
"web_host": "http://opscenter.skynet.lan",
"port": "3000",
"cookie_hash": "generate_with_openssl_rand_-base64_32",
"cookie_encryption": "generate_with_openssl_rand_-base64_32",
"access_key_encryption": "generate_with_openssl_rand_-base64_32"
}
Configuration Reference
Database Settings
- mysql.host: Database server address and port (default:
127.0.0.1:3306) - mysql.user: Database user account
- mysql.pass: Database user password
- mysql.name: Database name
- dialect: Database type (
mysql,postgres,bolt)
Server Settings
- tmp_path: Directory for temporary Ansible playbook execution files
- web_host: Public URL for the Semaphore web interface (used for links and redirects)
- port: Port that Semaphore listens on (default:
3000)
Security Settings
- cookie_hash: Hash key for session cookies (generate with
openssl rand -base64 32) - cookie_encryption: Encryption key for session cookies (generate with
openssl rand -base64 32) - access_key_encryption: Encryption key for API access keys (generate with
openssl rand -base64 32)
Optional Settings
- email_sender: Email address for notifications
- email_host: SMTP server address
- ldap_binddn: LDAP directory for authentication
- max_parallel_tasks: Maximum concurrent task executions
Nginx Reverse Proxy Configuration
Place this configuration in your Nginx configuration directory (e.g., /etc/nginx/sites-available/semaphore or /etc/nginx/conf.d/semaphore.conf):
server {
listen 80;
server_name opscenter.skynet.lan;
location / {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
}
Nginx Configuration Breakdown
| Setting | Purpose |
|---|---|
listen 80 |
Listens for HTTP requests on port 80 |
server_name |
Domain name this server block handles |
location / |
Match all request paths |
proxy_pass |
Forward requests to Semaphore on localhost:3000 |
proxy_set_header Host |
Pass original hostname to Semaphore |
proxy_set_header X-Real-IP |
Pass client's real IP address |
proxy_set_header X-Forwarded-For |
Pass full client IP chain |
proxy_set_header X-Forwarded-Proto |
Tell Semaphore whether original request was HTTP/HTTPS |
proxy_http_version 1.1 |
Use HTTP/1.1 for backend connection (required for WebSocket) |
proxy_set_header Upgrade |
Pass WebSocket upgrade header (for terminal/real-time features) |
proxy_set_header Connection |
Upgrade WebSocket connection |
Enabling the Configuration
-
Test Nginx configuration:
-
Reload Nginx:
Quick Reference Commands
# Package management
semaphore version # Show installed version
sudo semaphore setup # Interactive configuration setup
# Service management
sudo systemctl start semaphore # Start service
sudo systemctl stop semaphore # Stop service
sudo systemctl restart semaphore # Restart service
sudo systemctl status semaphore # Check status
sudo systemctl enable semaphore # Enable on boot
sudo systemctl disable semaphore # Disable on boot
# View logs
sudo journalctl -u semaphore -f # Follow logs in real-time
sudo journalctl -u semaphore -n 50 # View last 50 lines
sudo journalctl -u semaphore --no-pager # View without paging
# Nginx management
sudo nginx -t # Test nginx configuration
sudo systemctl reload nginx # Reload nginx
sudo systemctl status nginx # Check nginx status
# Generate encryption keys
openssl rand -base64 32 # Generate random key
Troubleshooting
Service Fails to Start
Check the journal for error details:
Common issues:
- Database connection error: Verify MySQL is running and credentials in config are correct
- Port already in use: Check if another process is using port 3000
- Config file missing: Run sudo semaphore setup to generate configuration
Cannot Access Web Interface
Verify the service is listening:
If using Nginx, test the configuration:
WebSocket Connection Issues
If terminal/real-time features don't work, ensure your Nginx configuration includes: