Gitea Woodpecker
Overview
This image is a self-contained DevOps stack. It bundles Gitea, a lightweight self-hosted Git service (MIT), as the Git forge, and Woodpecker CI, a simple container-based continuous integration engine (Apache-2.0), as the pipeline runner, server plus agent.
Woodpecker CI cannot run standalone. It has no user database of its own and authenticates users through a Git forge over OAuth. This image supplies that forge on the same VM and pre-wires the OAuth handshake between the two, so a complete source-control and CI/CD pair is running within minutes of launch, with no external service and no manual configuration.
Every application port binds to the loopback interface and is published by nginx: the Woodpecker UI on port 80 and the bundled Gitea on port 3000. Pipeline steps run in isolated Docker containers, so real builds execute on the one VM.
What you get:
- Gitea 1.27.1 as a single Go binary (
/usr/local/bin/gitea) with a SQLite database, acting as forge and OAuth provider - Woodpecker CI 3.17.0 server, agent and CLI (
/usr/local/bin/woodpecker-*) with the Docker pipeline backend - An
nginxreverse proxy: port 80 to the Woodpecker UI, port 3000 to the bundled Gitea - Four managed services:
gitea.service,woodpecker-server.service,woodpecker-agent.serviceandnginx.service woodpecker-firstboot.service, which rotates every secret, recreates the OAuth app against the VM address and writes the per-VM administrator login on first boot- All data under
/var/lib/woodpecker: the Gitea repositories and both SQLite databases - Gitea open registration disabled and the installer locked, with Woodpecker restricted to Gitea users
- An Ubuntu 24.04 LTS base, patched at build time
- 24/7 SecureAnyCloud support
Prerequisites
You need an active Azure subscription, an SSH key pair, and a VNet with a subnet.
The recommended VM size is Standard_B2s (2 vCPU / 4 GB). It is enough for Gitea, the Woodpecker server and agent, and container-based pipelines for a small team.
Deploy from the Azure Portal
Search the Azure Marketplace for Gitea + Woodpecker CI DevOps Stack, choose the plan, and create the VM.
In the networking step, attach a network security group (NSG) that allows inbound TCP 22 (SSH) from your management network. Also allow TCP 80 (Woodpecker UI) and TCP 3000 (Gitea) from the client networks that need them.
For production, put a TLS-terminating reverse proxy or Azure Application Gateway in front of ports 80 and 3000.
Deploy from the Azure CLI
RG="devops-prod"; LOCATION="eastus"; VM_NAME="gitea-woodpecker-01" IMAGE_URN="sac1647283583153:gitea-woodpecker-ubuntu-24-04:default:latest" SSH_KEY="$(cat ~/.ssh/id_rsa.pub)" az group create --name "$RG" --location "$LOCATION" az network vnet create -g "$RG" --name devops-vnet --address-prefix 10.104.0.0/16 --subnet-name devops-subnet --subnet-prefix 10.104.1.0/24 az network nsg create -g "$RG" --name devops-nsg az network nsg rule create -g "$RG" --nsg-name devops-nsg --name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 22 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name devops-nsg --name allow-woodpecker --priority 110 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 80 --access Allow --protocol Tcp az network nsg rule create -g "$RG" --nsg-name devops-nsg --name allow-gitea --priority 120 \
--source-address-prefixes "<your-mgmt-cidr>" --destination-port-ranges 3000 --access Allow --protocol Tcp
# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:gitea-woodpecker-ubuntu-24-04:default:latest
az vm create -g "$RG" --name "$VM_NAME" --image "$IMAGE_URN" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username azureuser --ssh-key-values "$SSH_KEY" \
--vnet-name devops-vnet --subnet devops-subnet --nsg devops-nsg --public-ip-sku StandardConnect via SSH
ssh azureuser@<vm-ip>Retrieve the per-VM administrator login
On first boot, woodpecker-firstboot.service generates a Gitea administrator password that is unique to your VM. It also generates fresh server secrets, an agent secret and an OAuth client secret. The login is written to a root-only file. No shared or default credentials ship in the image.
Read the file with sudo:
sudo cat /root/woodpecker-credentials.txtThe file records the Woodpecker URL, the Gitea URL, and the gitadmin username and password. Keep a copy somewhere safe.
Verify the stack and the OAuth wiring
Confirm that all four services are active:
systemctl is-active gitea.service woodpecker-server.service woodpecker-agent.service nginx.serviceCheck the Woodpecker health endpoint, which is open, and the bundled Gitea health endpoint through nginx:
curl -s -o /dev/null -w 'woodpecker healthz: %{http_code}\n' http://127.0.0.1/healthz
curl -s http://127.0.0.1:3000/api/healthz | head -c 40; echoConfirm that the Gitea administrator login works. The first request returns 200 with credentials and the second returns 401 without them:
curl -s -o /dev/null -w 'with creds: %{http_code}\n' -u "gitadmin:<GITEA_ADMIN_PASSWORD>" http://127.0.0.1:3000/api/v1/user
curl -s -o /dev/null -w 'without creds: %{http_code}\n' http://127.0.0.1:3000/api/v1/userConfirm that Woodpecker points at the bundled Gitea and that its /authorize endpoint redirects into the Gitea OAuth flow with the wired client id:
grep -E '^WOODPECKER_(HOST|GITEA_URL|GITEA_CLIENT)=' /etc/woodpecker/server.env curl -s -o /dev/null -w 'oauth redirect: %{redirect_url}\n' -m 10 http://127.0.0.1:8000/authorize | sed 's/&state=.*//'Sign in to Woodpecker through Gitea
Browse to http://<vm-ip>/. The Woodpecker sign-in page offers a single button that signs you in through the bundled Gitea forge.
Click the button and sign in with the gitadmin username and password from Step 4. Then click Authorize on the Gitea consent screen. You return to Woodpecker signed in. The bundled Gitea administrator is also the Woodpecker administrator.
Run your first pipeline
Create a repository in the bundled Gitea at http://<vm-ip>:3000/ and add a .woodpecker.yml file to it. In Woodpecker, click Add repository, enable the repository, and push a commit.
Gitea's webhook triggers Woodpecker, and the agent runs each step in a Docker container. Here is a minimal pipeline:
steps: - name: smoke image: alpine:3.20 commands: - echo "hello from sac" - uname -smThe run appears in Woodpecker with per-step logs and a green result when the container exits 0.
You can also run a pipeline locally against the Docker backend, without pushing, using the bundled CLI. This is handy for testing a .woodpecker.yml:
cat > /tmp/.woodpecker.yml <<'YAML' steps: - name: smoke image: alpine:3.20 commands: - echo "hello from sac" YAML cd /tmp && sudo WOODPECKER_BACKEND=docker woodpecker-cli exec --backend-engine docker .woodpecker.ymlPoint Woodpecker at an external forge (optional)
To use an external GitHub, Gitea, Forgejo or GitLab forge instead of the bundled one, register an OAuth application on that forge.
Then edit /etc/woodpecker/server.env and set WOODPECKER_GITEA_URL (or the GitHub or GitLab equivalents), WOODPECKER_GITEA_CLIENT and WOODPECKER_GITEA_SECRET. Restart the server:
sudo systemctl restart woodpecker-server.serviceProduction hardening
- Encrypt web traffic. Terminate HTTPS in front of ports 80 and 3000 with Azure Application Gateway, a load balancer or your own reverse proxy. Alternatively, install a certificate with
certboton a public DNS name and front nginx. - Backups. Back up
/var/lib/woodpecker(Gitea repositories and both SQLite databases). - Scaling. To run more pipeline steps in parallel, increase
WOODPECKER_MAX_WORKFLOWSin/etc/woodpecker/agent.envor add more agents.
Operations and support
Manage the stack with systemctl for the gitea, woodpecker-server, woodpecker-agent and nginx services. The Woodpecker health endpoint http://<vm-ip>/healthz is open for monitoring.
SecureAnyCloud provides 24/7 technical support by email and chat for deployment, pointing Woodpecker at an external forge, pipeline authoring, agent scaling, TLS termination and upgrades.
Deploy on Azure
Launch Gitea + Woodpecker CI DevOps Stack 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