In this tutorial we will setup Gitea as our version control system, and we will setup Woodpecker Ci (Server and Agent) to run our builds from a simple pipeline that we define in yaml, and the best is that our builds runs on containers. We will run these on docker and make use of docker-compose.

What is Woodpecker

Taken from their documentation: “Woodpecker is a simple CI engine with great extensibility. It runs your pipelines inside containers, so if you are already using them in your daily workflow, you’ll love Woodpecker for sure.”

You can read more about them here

About

This stack will boot the following:

  • Gitea (Version Control)
  • Woodpecker Server (Control Plane)
  • Woodpecker Agent (Responsible for running builds)

The source code for this can be found on my Github Repository

Requirements

We will need the IP Address of your workstation (LAN), in order to enable the containers to communicate with each other (woodpecker-server and gitea).

This can be retrieved by running:

ifconfig $(netstat -rn | grep -E "^default|^0.0.0.0" | head -1 | awk '{print $NF}') | grep 'inet ' | awk '{print $2}' | grep -Eo '([0-9]*\.){3}[0-9]*'

In my case the output is:

192.168.0.182

Set that to the environment:

export IP_ADDRESS=$(ifconfig $(netstat -rn | grep -E "^default|^0.0.0.0" | head -1 | awk '{print $NF}') | grep 'inet ' | awk '{print $2}' | grep -Eo '([0-9]*\.){3}[0-9]*')

# or

export IP_ADDRESS=192.168.0.182 # replace with your ip address

Gitea

Run the gitea container:

docker-compose up -d woodpecker-gitea

Access gitea on http://git.${IP_ADDRESS}.nip.io:3000, to display the url in your terminal:

echo http://git.${IP_ADDRESS}.nip.io:3000

Most of the defaults should be populated as we defined them in our environments section of our compose, at the bottom, provide the administrator details, then select “Install Gitea”:

woodpecker-ci-image

Then you should be redirected to the main gitea menu:

woodpecker-ci-image

At this point in time we need to setup a OAuth application in order for our Woodpecker Server to authenticate with Gitea. Select the profile at the right top corner, then select settings:

woodpecker-ci-image

Then select the “Applications” tab, then under “Manage OAuth2 Applications”, provide the following:

  • Application Name: Woodpecker CI
  • Redirect URI: http://ci.your-ip-address.nip.io:8000/authorize

woodpecker-ci-image

Then click “Create Application” and you should get the following values:

  • Client ID: c587c627-cc4e-4fb1-a196-97736051090b # values has been deleted
  • Client Secret: u92Jvf-gxj_phcRnHWjwpmJv0NXoWthNGsXybds6CuE= # values has been deleted

Then select “Save”

Woodpecker

Time to configure the woodpecker server and agent, and all that we need to configure is the .env file so that we can make woodpecker aware of the gitea client and secret and as well as the woodpecker agent secret which is a shared secret between the woodpecker server and agent.

First let’s create a agent secret:

$ openssl rand -base64 32
V5og1c7yAa5aZw7n7pjP86+jCkdRl3VakEy+EjC7vO8=

Then we will populate the gitea client and secret that we retrieved from gitea, and the agent secret that we received from the openssl command in the .env file:

WOODPECKER_AGENT_SECRET=V5og1c7yAa5aZw7n7pjP86+jCkdRl3VakEy+EjC7vO8=
WOODPECKER_GITEA_CLIENT=c587c627-cc4e-4fb1-a196-97736051090b
WOODPECKER_GITEA_SECRET=u92Jvf-gxj_phcRnHWjwpmJv0NXoWthNGsXybds6CuE=

Once that is in place, we can start the woodpecker server and agent containers:

docker-compose up -d

Now access woodpecker server on http://ci.${IP_ADDRESS}.nip.io:8000, to return the address in your terminal:

echo http://ci.${IP_ADDRESS}.nip.io:8000

On the initial page we will see the login screen:

woodpecker-ci-image

Once we select login, we will be redirected to gitea where it will ask us if we authorize woodpecker ci (the application that we created) to access our gitea account:

woodpecker-ci-image

Select “Authorize Application”, then we will be logged into woodpecker server:

woodpecker-ci-image

Head back to gitea, and from the top right hand corner, select “+” and select “New Repository”:

woodpecker-ci-image

Provide a repository name and select “Initialize Repository”:

woodpecker-ci-image

Then select “Create Repository”:

woodpecker-ci-image

Head back to woodpecker server, then on the right hand side select “Add Repository”:

woodpecker-ci-image

Then select “Reload Repositories”, and you should see your repository appear:

woodpecker-ci-image

Then select “enable” and you should see a view with no builds:

woodpecker-ci-image

Head back to gitea, select “new file”, name the file .woodpecker.yml and provide this basic pipeline yaml:

pipeline:
  first-job:
    image: busybox
    commands:
      - echo "first run"

And what we do, we specify that our build should run a container from a busybox image, and run the command echo first run.

Commit the file to the master branch, then head back to woodpecker server, we will see that from the pipeline overview page, that our build succeeded:

woodpecker-ci-image

When we select the build, we can see our build consisted of a clone step and our step which we called “first-job”:

woodpecker-ci-image

Example Pipelines

The following pipeline will run a mysql service container and our build step will use a container from the mysql image, to test the connectivity to the mysql service, it will retry until it establishes a connection and then exit:

pipeline:
  build:
    image: mysql:5.7
    commands:
      - while ! mysqladmin ping -h mysql-server -u woodpecker -pwoodpecker --silent; do sleep 1; done

services:
  mysql-server:
    image: mysql:5.7
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: yes
      MYSQL_DATABASE: woodpecker
      MYSQL_USER: woodpecker
      MYSQL_PASSWORD: woodpecker

The following pipeline will run two steps in parallel (run-one and run-two) as they share the same group name, then step run-three will run after that, and we define the pipeline to only trigger when the branches includes master and any prefixes starts with releases/. The pipeline will not trigger on branches starting with test/1.0.0 and test/1.1.*:

pipeline:
  run-one:
    image: busybox
    group: first
    commands:
      - echo "first run"

  run-two:
    image: busybox
    group: first
    commands:
      - echo "second run"

  run-three:
    image: ubuntu
    commands:
      - echo hi
when:
  branch:
    include: [ master, release/* ]
    exclude: [ test/1.0.0, test/1.1.* ]

For more information on the pipeline syntax, view:

For more examples, see their repository:

Thank You

Thanks for reading, if you like the project, feel free to star, fork or share it, check out my website, read my newsletter or follow me at @ruanbekker on Twitter.