Semaphore UI: a web control plane for Ansible, Terraform and OpenTofu runs
Modern UI and powerful API for Ansible, Terraform/OpenTofu/Terragrunt, PowerShell and other DevOps tools.
At a glance
- What is it?
- Semaphore UI puts a Go web application in front of the DevOps CLIs your team already runs from a terminal. The Docker path takes one command; the trade-off is that the tool owns your credentials, your inventory and your schedule.
- Who is it for?
- Adopt Semaphore UI if a team runs Ansible or Terraform from individual laptops and needs shared inventories, schedules and an audit trail in one place, and if you can accept that the application database becomes the store for your SSH keys, cloud tokens and vault passwords.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The terminal stops scaling before the tooling does
The README states the problem plainly: "If your project has grown and deploying from the terminal is no longer feasible, then Semaphore UI is the tool you need." That is a narrow claim, and it is the right one to judge the project against. The friction it targets is not Ansible itself. It is the point where three engineers each hold a slightly different ansible-playbook invocation, a different inventory file on a different laptop, and a private SSH key that nobody else can rotate.
Semaphore UI is aimed at infrastructure and operations teams that already have playbooks or Terraform configurations in a Git repository and want them executed somewhere that is not a personal machine. The README lists the tools it drives: Ansible playbooks, Terraform, OpenTofu and Terragrunt code, plus Bash and PowerShell scripts. It is not a configuration management engine and it does not replace Ansible. It is a scheduling and access layer around the binaries.
The people who benefit most are the ones who currently answer the question "who deployed this and when" by searching chat history. The people who benefit least are solo operators, for whom a local terminal plus a Makefile is genuinely simpler than a web application with a database.
Projects, templates, tasks and where the state lives
The README defines five concepts, and they map onto a fairly conventional resource hierarchy. A Project is "a collection of related resources, configurations, and tasks." Inside a project, a Task Template is a reusable definition of a task, executed on demand or on a schedule. A Task is one execution of that template. An Inventory is the set of target hosts. A Variable Group holds environment variables and secrets used during execution.
The Go module list shows what sits underneath. The web layer is gorilla/mux with gorilla/websocket for live output, so task logs stream to the browser rather than being polled. Persistence goes through go-gorp/gorp over database drivers for SQLite (modernc.org/sqlite, a pure-Go implementation), PostgreSQL (lib/pq) and MySQL (go-sql-driver/mysql). Scheduling uses robfig/cron. Repository access uses go-git, meaning Semaphore clones your playbook repository itself rather than relying on a system git binary. Authentication dependencies include go-oidc for OpenID Connect, go-ldap for directory binds, and pquerna/otp for TOTP, which is why the repository carries examples/openldap and examples/authentik_ldap directories. Prometheus client_golang is present for metrics, and lumberjack handles log rotation.
One structural detail matters more than the rest: go.mod contains a replace directive pointing github.com/semaphoreui/semaphore/pro at a local ./pro directory, and the repository has both pro/ and pro_interfaces/ at the top level. The README describes the project as MIT without qualifying that, so anyone building from source should look at what that directory contains in the tree they build, rather than assuming the compiled binary matches the licence badge.
Installing Semaphore UI with Docker and running a first task
The README calls Docker "the most popular way to install Semaphore." The published command maps port 3000 and passes the admin account and database dialect as environment variables. Run it as given; the password below is the README's own placeholder and should be changed before anything else touches the instance.
docker run -p 3000:3000 --name semaphore \
-e SEMAPHORE_DB_DIALECT=sqlite \
-e SEMAPHORE_ADMIN=admin \
-e SEMAPHORE_ADMIN_PASSWORD=changeme \
-e SEMAPHORE_ADMIN_NAME=Admin \
-e SEMAPHORE_ADMIN_EMAIL=admin@localhost \
-d semaphoreui/semaphore:latestAfter the container starts, the web interface answers on http://localhost:3000 and the first login uses the SEMAPHORE_ADMIN and SEMAPHORE_ADMIN_PASSWORD values you passed. SEMAPHORE_DB_DIALECT selects the storage backend; sqlite is what the README uses for the single-container example, and the gorp drivers in go.mod are the reason PostgreSQL and MySQL are also on the table.
The README points at a Container Configurator at semaphoreui.com/install/docker for anything beyond the default, and that is worth using rather than hand-writing environment variables, because the README itself does not enumerate the full set. For a first real use, the sequence implied by the key concepts is: create a project, add an inventory of target hosts, add a variable group holding the credentials the playbook needs, create a task template pointing at your repository and playbook, then run it and watch the output stream in the browser. The README does not document those screens step by step; the linked User Guide at docs.semaphoreui.com is where that lives.
If Docker is not an option, the README lists Snap, a binary file, and Debian or RPM packages, all linked from semaphoreui.com/install, plus marketplace images for AWS, DigitalOcean, Vultr, Cloudzy, Yandex Cloud and RepoCloud.
What Semaphore UI does not do for you
The most consequential limitation is implied by the Variable Group concept rather than stated as a warning: secrets used by tasks live in Semaphore's own database, encrypted by the application. Anyone who can read that database and the key material beside it can read your deployment credentials. If your current practice is short-lived cloud credentials issued per pipeline run, Semaphore changes that model, and the README does not describe a built-in dynamic secrets backend. LDAP and OIDC integration control who logs in; they do not change where the secrets are stored.
Second, the project assumes the tools are installed where the runner executes. The README describes running Ansible playbooks and Terraform code, not bundling the binaries. Container images presumably ship them, but the README does not state which versions, and version drift between the Semaphore container and the Terraform or Ansible version your configuration expects is a problem you will discover at run time.
Third, the documentation surface is thin on operational detail. The README does not document rollback of a failed task, does not describe how concurrent tasks on the same inventory are serialised, and does not explain what happens to a running task when the server restarts. Those are the questions that decide whether a tool is safe for production change management, and the README is silent on all three.
Finally, this is the wrong tool if your deployments are already expressed as CI pipeline stages. Semaphore is a parallel system with its own users, its own permissions and its own audit log. Running it alongside a CI platform means two places to check when something fails.
Semaphore UI against AWX and against plain CI runners
The obvious comparison is AWX, the upstream open source project behind Red Hat Ansible Automation Platform. Both give you a web interface over Ansible with inventories, credentials and scheduled jobs, and the repository's own topics list includes awx, so the maintainers clearly expect the comparison. The difference in approach is scope. AWX is built around Ansible as the execution engine and inherits its project, credential and inventory types from that world. Semaphore UI positions itself as a UI for several tools at once: the README's first bullet is running "Ansible playbooks, Terraform and OpenTofu code, as well as Bash and PowerShell scripts." If your estate is Ansible only, AWX is the more vertically integrated choice. If you run Ansible for configuration and Terraform or OpenTofu for provisioning and want one place to trigger both, Semaphore's breadth is the reason to pick it.
The second comparison is a general CI runner such as Jenkins, which also appears in the repository topics. Jenkins models work as pipeline stages defined in a Jenkinsfile that lives with the code. Semaphore models work as task templates configured in the application, pointing at a repository. That is the real difference: in Jenkins the pipeline definition is versioned alongside the playbook, while in Semaphore the template and its variables are application state, exported or backed up separately from Git. Teams that treat deployment definitions as code will find that inversion uncomfortable.
There are also community integrations listed in the README that soften the boundary: a Terraform provider for managing Semaphore resources, a PowerShell module for its REST API, an Ansible collection, and an MCP server for AI assistants. The Terraform provider in particular is the escape hatch for teams that want Semaphore's configuration itself under version control.
Licence, upgrade cadence and the pro directory
The README states the project is MIT licensed, copyright Denis Gukov. MIT is permissive: it allows commercial use, modification and redistribution with the licence text retained. That is a straightforward position, and it is a genuine advantage over the copyleft alternatives in the same space. It is not legal advice, and it applies to the code in the repository, which brings us back to the pro/ directory.
Because go.mod replaces the pro module with ./pro, the licence that applies to a given binary depends on what is in that directory in the tree you build. The README does not explain the split. Anyone evaluating Semaphore for a commercial deployment should read THIRD-PARTY-LICENSES.md and the contents of pro/ before assuming the MIT badge covers every feature they plan to use.
On maintenance, the release history shows a steady cadence: v2.19.12 and v2.18.30 both on 2026-08-30, with v2.19.11 three days earlier, and the last push to the develop branch on 2026-09-21. Two maintained release lines in parallel is a signal that patch fixes are being backported rather than landing only on the newest minor version. The upgrade cost is dominated by the database: a Go binary that runs migrations against SQLite, PostgreSQL or MySQL means you should take a backup of that database before pulling a new image, and the README does not describe a downgrade path. The repository carries a config.schema.yaml at the top level, which is the file to diff between versions if you maintain configuration outside the container.
Editorial conclusion
Adopt Semaphore UI if a team runs Ansible or Terraform from individual laptops and needs shared inventories, schedules and an audit trail in one place, and if you can accept that the application database becomes the store for your SSH keys, cloud tokens and vault passwords. Skip it if your runs are already modelled as pipeline stages in a CI system, or if you need a per-run approval gate before a task starts: the README and the repository layout describe templates, schedules and notifications, but nothing that blocks execution pending a human decision. Before rolling it out, verify the database dialect you intend to use against the SEMAPHORE_DB_DIALECT value you plan to pass, check whether the pro/ directory is compiled into your build, and confirm where the task runner writes its working copy of your repository.
Frequently asked questions
How do I install Semaphore UI?
The README gives Docker as the most popular method, with a single docker run command that maps port 3000 and sets SEMAPHORE_DB_DIALECT, SEMAPHORE_ADMIN and SEMAPHORE_ADMIN_PASSWORD. It also lists Snap, a binary file, Debian or RPM packages, and marketplace VM images for AWS, DigitalOcean, Vultr, Cloudzy, Yandex Cloud and RepoCloud.
How do I use Semaphore UI with Ansible?
According to the README, you create a project, add an inventory of target hosts, add a variable group holding the credentials the playbook needs, then create a task template that defines the playbook to run. The template can be executed on demand or on a schedule, and the task output streams to the browser over a websocket.
How do I set up Semaphore UI on Ubuntu?
The README does not give Ubuntu-specific steps. It links to a Debian or RPM package download and to a binary file, both from semaphoreui.com/install, and Docker works on Ubuntu as it does elsewhere. The linked User Guide at docs.semaphoreui.com is where the installation detail beyond the README lives.
How do I install Semaphore UI with Ansible?
The README does not document an Ansible-based installation. It lists Docker, Snap, a binary file, Debian or RPM packages and marketplace images, and separately lists a community Ansible collection for managing Semaphore among its related projects.
How do I set up Ansible Semaphore?
The README's setup sequence is Docker-first: run the container with SEMAPHORE_DB_DIALECT and the SEMAPHORE_ADMIN variables, then create a project, an inventory, a variable group for credentials and a task template pointing at your repository. The Container Configurator at semaphoreui.com/install/docker is the README's recommendation for anything beyond the default command.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/semaphoreui-semaphore)