Woodpecker CI on AWS User Guide
Overview
This image runs Woodpecker CI, the simple yet powerful open source continuous integration and delivery engine. Pipelines are defined as plain YAML in a .woodpecker.yml file in your repository, and each step runs in an isolated container, so builds are reproducible and easy to reason about.
Woodpecker has no standalone user database of its own; it authenticates users by OAuth against a Git forge. To make this image a self contained appliance, it bundles the Gitea self hosted Git service on the same instance and pre wires the OAuth handshake between Gitea and Woodpecker. The result is a complete source control and CI/CD pair: you push code to the bundled Gitea, add a pipeline file, enable the repository in Woodpecker, and your build runs on a local Woodpecker agent using the Docker backend.
The Woodpecker server and agent and the Gitea binary are installed under /usr/local/bin. Every application port binds to the loopback interface, and nginx publishes the Woodpecker web interface on port 80 and the bundled Gitea on port 3000. The Woodpecker store and the Gitea database and git repositories live at /var/lib/woodpecker, which is a dedicated, independently resizable EBS data volume.
The administrator password is generated on the first boot of every deployed instance, so two instances launched from the same Amazon Machine Image never share a password. It is written to /root/woodpecker-credentials.txt with mode 0600 so that only the root user can read it. On first boot the image also rotates the Gitea server secrets and the Woodpecker agent secret, recreates the OAuth application against the instance's own public address, and wires the OAuth callback URL to that address.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network, port 80 for the Woodpecker web interface, and port 3000 for the bundled Gitea forge
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Step 1: Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for Woodpecker CI. Select the cloudimg listing and choose Select, then Continue on the subscription summary.
Pick an instance type of t3.small or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that opens port 22 from your management network, port 80 for Woodpecker, and port 3000 for the bundled Gitea. Leave the root volume at the default size or larger.
Select Launch instance. First boot initialisation takes a short time after the instance state becomes Running and the status checks pass, while the image rotates secrets and wires the OAuth callback to the instance address.
Step 2: Launch the Instance from the AWS CLI
The following block launches an instance from the cloudimg Woodpecker CI Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens ports 22, 80 and 3000 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type t3.small \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=woodpecker}]'
When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.
Step 3: Connect to Your Instance
Connect over SSH using your key pair and the login user for your operating system variant.
| OS variant | SSH login user |
|---|---|
| Ubuntu 24.04 | ubuntu |
ssh -i <key-name>.pem ubuntu@<public-ip>
Step 4: Retrieve the Administrator Password
The administrator login is unique to your instance and was generated on first boot. Read it as root:
sudo cat /root/woodpecker-credentials.txt
The file lists the Woodpecker URL, the bundled Gitea URL, the administrator user (gitadmin) and the generated password. The same administrator signs in to both Gitea and Woodpecker. Keep this password somewhere safe.
Step 5: Confirm the Services Are Running
Over SSH, confirm the four services are active and that the public ports are listening:
sudo systemctl is-active gitea woodpecker-server woodpecker-agent nginx
sudo ss -tlnp | grep -E ':(80|3000) '
You should see all four services reported as active, nginx listening on port 80 for Woodpecker and port 3000 for Gitea. The Woodpecker health endpoint is open and answers on the loopback through nginx:
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthz
A 200 or 204 confirms the Woodpecker server is healthy.
Step 6: Sign In to Woodpecker
The Woodpecker web interface is served on port 80 by nginx. In a browser, go to:
http://<instance-public-ip>/
Choose Login. Because Woodpecker authenticates through the bundled Gitea, you are redirected to the Gitea sign in page on port 3000. Sign in as gitadmin with the password from the credentials file, then choose Authorize Application on the OAuth consent screen. You are returned to Woodpecker, signed in.

The OAuth application, its client credentials, and the callback URL are all configured for you. You do not need to create anything in Gitea by hand.
Step 7: Add a Repository and Run a Pipeline
Push a repository to the bundled Gitea (or create one in the Gitea web interface on port 3000), and add a .woodpecker.yml file to it. A minimal pipeline looks like this:
when:
- event: [push, manual]
steps:
- name: build
image: alpine
commands:
- echo "Building on Woodpecker CI"
- uname -a
In Woodpecker choose Add repository, then Enable next to your repository. Enabling the repository registers a webhook in Gitea so that every push triggers a pipeline. Push a commit, and the Woodpecker agent runs the pipeline in containers using the Docker backend.

The repository, its commits, the .woodpecker.yml pipeline file, and the green CI status for each commit are all visible in the bundled Gitea on port 3000.

Step 8: The Data Volume
The Woodpecker store and the Gitea database and git repositories live on a dedicated EBS volume mounted at /var/lib/woodpecker. This keeps the application data off the operating system disk and lets you resize or snapshot it independently. Confirm the mount with:
df -h /var/lib/woodpecker
To grow the store, expand the EBS volume in the AWS console, then grow the filesystem on the instance with sudo resize2fs on the underlying device.
Step 9: Point Woodpecker at an External Forge
If you would rather use your own GitHub, Gitea, Forgejo or GitLab instead of the bundled Gitea, point Woodpecker at it by editing the server environment file and registering an OAuth application in your forge. The Woodpecker server configuration lives at /etc/woodpecker/server.env:
sudo cat /etc/woodpecker/server.env
Create an OAuth application in your external forge with the authorization callback URL http://<instance-public-ip>/authorize, then set the forge driver, forge URL and the OAuth client id and secret in /etc/woodpecker/server.env. For an external Gitea or Forgejo the keys are WOODPECKER_GITEA=true, WOODPECKER_GITEA_URL, WOODPECKER_GITEA_CLIENT and WOODPECKER_GITEA_SECRET; for GitHub use the WOODPECKER_GITHUB keys and for GitLab the WOODPECKER_GITLAB keys, as described in the Woodpecker documentation. Restart the server to apply the change:
sudo systemctl restart woodpecker-server
If you no longer need the bundled Gitea you can stop and disable it with sudo systemctl disable --now gitea. Leave it enabled if you still want a local forge alongside your external one.
Step 10: Enable HTTPS
The Woodpecker and Gitea interfaces are served over plain HTTP on ports 80 and 3000 by nginx. For production use, place them behind TLS. Obtain a certificate for your domain (for example with a managed certificate on an Application Load Balancer in front of the instance, or with Certbot installed on the instance), then configure nginx to listen on 443 with your certificate and proxy to the Woodpecker and Gitea backends exactly as the bundled site does for HTTP. When you move to HTTPS, update WOODPECKER_HOST and the Gitea ROOT_URL to the https:// URL and update the OAuth application's callback URL to match. Restrict the security group so the ports are reachable only from the networks that use the service.
Step 11: Backup and Maintenance
Back up the appliance by snapshotting the /var/lib/woodpecker EBS volume, which captures the Woodpecker store and the Gitea database and git repositories. Apply operating system security updates with sudo apt-get update && sudo apt-get upgrade and reboot when a new kernel is installed; all four services start automatically on boot, and the OAuth callback and forge URLs are re wired to the current public address on each boot.
Support
This image is published and supported by cloudimg. Support covers deployment, pointing Woodpecker at an external forge, pipeline authoring, agent scaling, TLS termination and upgrades. Contact cloudimg through the support channel listed on the AWS Marketplace listing.
All product and company names are trademarks or registered trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.