Skip to content

Semaphore Installation & Configuration Guide

Prerequisites

  • Linux x86_64 host with systemd
  • dnf or yum package 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:

semaphore version

Step 4: Generate Configuration File

Run the interactive setup to generate the configuration file and initialize the installation:

sudo semaphore setup

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:

sudo systemctl daemon-reload
sudo systemctl enable semaphore
sudo systemctl start semaphore

Step 7: Verify Service Status

Check that the service is running:

sudo systemctl status semaphore
semaphore version

Step 8: Access Semaphore

Access the web interface (default):

http://localhost:3000
or
http://opscenter.skynet.lan  (with reverse proxy)

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

  1. Test Nginx configuration:

    sudo nginx -t
    

  2. Reload Nginx:

    sudo systemctl 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:

sudo journalctl -u semaphore --no-pager

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:

sudo ss -ltnp | grep 3000

If using Nginx, test the configuration:

sudo nginx -t
sudo systemctl status nginx

WebSocket Connection Issues

If terminal/real-time features don't work, ensure your Nginx configuration includes:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_http_version 1.1;