Concourse CI
Overview
Concourse CI is an open-source continuous integration and continuous delivery system built on one idea: everything is a pipeline. You declare pipelines as plain YAML made of resources, jobs and tasks, and keep them under version control alongside your code. Every build runs in a clean container, so builds are reproducible and there is no snowflake build server to maintain.
This SecureAnyCloud image installs Concourse CI 8.2.4 on Ubuntu 24.04 LTS as a complete single-node deployment: the web node (the ATC API, the web UI and the TSA worker gateway), one worker that runs your task containers, and a PostgreSQL database.
What you get:
- Concourse CI 8.2.4 (web and worker) and the
flycommand-line client - PostgreSQL backing the Concourse ATC, with its data directory on a dedicated data disk
- The web UI published on port 80 through an nginx reverse proxy, with WebSocket upgrade for live build logs
- A dedicated Azure data disk at
/var/lib/concoursefor the PostgreSQL cluster and the worker work-dir - A unique admin password and a freshly rotated session signing key, generated on the first boot of every VM and written to a root-only credentials file
concourse-web.service,concourse-worker.service,postgresql.serviceandnginx.serviceas enabled, active systemd units- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.
Standard_B4ms (4 vCPU / 16 GiB RAM) is a good starting size, because Concourse runs the web node, the worker and PostgreSQL on one VM.
Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the web UI. For public exposure, put TLS in front of the UI (see Enabling HTTPS).
Step 1 - Deploy from the Azure Marketplace
Sign in to the Azure Portal, choose Create a resource, search the Marketplace for Concourse CI by SecureAnyCloud, and select Create.
On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).
Review the dedicated data disk on the Disks tab, then select Review + create and Create.
Step 2 - Deploy from the Azure CLI
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:concourse-ci-ubuntu-24-04:default:latest
az vm create \
--resource-group <your-rg> \
--name concourse-ci \
--image sac1647283583153:concourse-ci-ubuntu-24-04:default:latest \
--size Standard_B4ms \
--admin-username azureuser \
--ssh-key-values ~/.ssh/id_ed25519.pub \
--vnet-name <your-vnet> --subnet <your-subnet> \
--public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name concourse-ci --port 80 --priority 1010Step 3 - Connect to your VM
ssh azureuser@<vm-public-ip>Step 4 - Confirm the services are running
On first boot, the VM generates a unique admin password, rotates the Concourse session signing key, and then starts the web node, the worker and PostgreSQL. Confirm that all four services are active:
systemctl is-active concourse-web.service concourse-worker.service postgresql.service nginx.serviceEach line reports active.
Step 5 - Check the Concourse info endpoint
The Concourse ATC exposes an unauthenticated info endpoint that returns the running version as JSON. nginx proxies it on port 80. Query it:
curl -s http://127.0.0.1/api/v1/info | jq .The expected output reports version 8.2.4:
{ "version": "8.2.4", "worker_version": "2.5", "feature_flags": { "build_rerun": false, "cache_streamed_volumes": false, "global_resources": false, "resource_causality": false }, "external_url": "http://10.0.0.4", "cluster_name": "sac" }nginx also serves a static health endpoint that does not depend on the upstream. Query it:
curl -s http://127.0.0.1/healthIt returns ok.
Step 6 - Retrieve your admin password
Your VM generates a unique admin password on first boot and writes it to a root-only file. Read it with sudo:
sudo cat /root/concourse-ci-credentials.txtThis file contains CONCOURSE_URL, CONCOURSE_ADMIN_USER (admin) and CONCOURSE_ADMIN_PASSWORD. Store the password somewhere safe. It grants full administrative access to the main team.
Step 7 - Sign in to the web UI
Open http://<vm-public-ip>/ in a browser. Click login, choose the main team, and sign in as admin with the password from Step 6. The dashboard shows your teams and pipelines.
Step 8 - Log in with the fly CLI
fly is the Concourse command-line client. It is preinstalled at /usr/local/bin/fly. Confirm that its version matches the server:
fly --versionIt prints 8.2.4.
Log in to a target named ci. Replace <CONCOURSE_ADMIN_PASSWORD> with your admin password from Step 6:
fly -t ci login -c http://127.0.0.1:8080 -u admin -p <CONCOURSE_ADMIN_PASSWORD>You should see target saved. Then list the registered workers. One worker reports running:
sudo HOME=/root fly -t ci workersStep 9 - Set and trigger a pipeline
Create a minimal pipeline file:
cat > /tmp/hello-world.yml <<'YML' jobs: - name: hello-world plan: - task: say-hello config: platform: linux image_resource: type: registry-image source: { repository: busybox } run: path: echo args: ["hello from sac concourse"] YMLSet the pipeline non-interactively with -n, then unpause it:
sudo HOME=/root fly -t ci set-pipeline -p hello -c /tmp/hello-world.yml -nsudo HOME=/root fly -t ci unpause-pipeline -p helloThe pipeline now appears on the dashboard. Trigger the job from the web UI, or run fly -t ci trigger-job -j hello/hello-world --watch. The first run pulls the busybox image, runs the task in a fresh container and prints the build log live.
Step 10 - Where data lives
PostgreSQL (the Concourse database) and the worker work-dir both live on a dedicated Azure data disk mounted at /var/lib/concourse. The disk is separate from the OS disk and can be resized independently. Check the mount:
df -h /var/lib/concourseEvery VM created from this image gets a newly provisioned disk.
Enabling HTTPS
The image serves the Concourse web UI over plain HTTP on port 80. For production, put TLS in front of it with your own domain. Point a DNS record at the VM public IP, then install a certificate with certbot and the nginx plugin. Replace your-domain.example.com with your hostname:
sudo apt-get update && sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.example.comAfter enabling TLS, set CONCOURSE_EXTERNAL_URL=https://your-domain.example.com/ in /etc/concourse/web.env. Then restart concourse-web.service so that generated links and fly login use HTTPS.
Maintenance
The Concourse and fly binaries live under /opt/concourse and /usr/local/bin/fly. Configuration is in /etc/concourse. To view logs, run:
sudo journalctl -u concourse-web.service --no-pager | tail -20PostgreSQL is the stock Ubuntu package and receives security updates through unattended-upgrades. To back up your Concourse database, run pg_dump against the atc database as the postgres user. To restart the stack, run sudo systemctl restart concourse-web.service concourse-worker.service.
Support
SecureAnyCloud maintains this image and provides 24/7 support. Concourse is a trademark of its respective owners. SecureAnyCloud packages and supports the open-source distribution and is not affiliated with the Concourse project.
Deploy on Azure
Launch Concourse CI on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com