Published: Aug 3, 2023 by Isaac Johnson
In our last post we covered Gitea setup on a temporary cluster and explored the basics of Organizations and Repositories.
Today we’ll look at Actions, Runners and Branch Protections. We’ll also take the time to create a properly exposed Gitea instance using helm with a supported non-containerized backend database. We’ll also demonstrate setting up the Mailer block to use Sendgrid.
Gitea Actions
Much like Github Actions, Gitea Actions are a method of running workflows directly out of our Gitea code repository. It is still a relatively new feature (going live just in 1.19) and is disabled by default.
$ helm upgrade gitea --set gitea.config.actions.ENABLED=true gitea-charts/gitea
coalesce.go:175: warning: skipped value for memcached.initContainers: Not a table.
Release "gitea" has been upgraded. Happy Helming!
NAME: gitea
LAST DEPLOYED: Mon Jul 17 14:01:40 2023
NAMESPACE: default
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
echo "Visit http://127.0.0.1:3000 to use your application"
kubectl --namespace default port-forward svc/gitea-http 3000:3000
I can see the change reflected in the inline config
$ kubectl get secret gitea-inline-config -o yaml | head -n4
apiVersion: v1
data:
_generals_: ""
actions: RU5BQkxFRD10cnVl
$ echo RU5BQkxFRD10cnVl | base64 --decode
I can now go to site adminstration and see a Runners section. There I can create a new runner with a token
To add the runner, I’ll want to add a DinD version. We can see an example here which I modified to run two runners and use local-path storage
$ cat gitea-dind.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: act-runner-vol
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-path
---
apiVersion: v1
data:
token: YTRGdDZ2WG9GZm1Pd3pKM3pDOGFrbTVFazlJVFpCV1NGeUJpaTZ1ZQ==
kind: Secret
metadata:
name: runner-secret
type: Opaque
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: act-runner
name: act-runner
spec:
replicas: 2
selector:
matchLabels:
app: act-runner
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: act-runner
spec:
restartPolicy: Always
volumes:
- name: docker-certs
emptyDir: {}
- name: runner-data
persistentVolumeClaim:
claimName: act-runner-vol
containers:
- name: runner
image: gitea/act_runner:nightly
command: ["sh", "-c", "while ! nc -z localhost 2376 </dev/null; do echo 'waiting for docker daemon...'; sleep 5; done; /sbin/tini -- /opt/act/run.sh"]
env:
- name: DOCKER_HOST
value: tcp://localhost:2376
- name: DOCKER_CERT_PATH
value: /certs/client
- name: DOCKER_TLS_VERIFY
value: "1"
- name: GITEA_INSTANCE_URL
value: http://gitea-http.default.svc.cluster.local:3000
- name: GITEA_RUNNER_REGISTRATION_TOKEN
valueFrom:
secretKeyRef:
name: runner-secret
key: token
volumeMounts:
- name: docker-certs
mountPath: /certs
- name: runner-data
mountPath: /data
- name: daemon
image: docker:23.0.6-dind
env:
- name: DOCKER_TLS_CERTDIR
value: /certs
securityContext:
privileged: true
volumeMounts:
- name: docker-certs
mountPath: /certs
I applied and then checked on the PVC and runner creation
$ kubectl apply -f gitea-dind.yaml
persistentvolumeclaim/act-runner-vol created
secret/runner-secret created
deployment.apps/act-runner created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-gitea-0 Bound pvc-bffada16-6a38-4968-be79-604ede967b13 10Gi RWO local-path 8h
data-gitea-postgresql-0 Bound pvc-1c317391-7d2c-405d-a505-d8fe42c44f03 10Gi RWO local-path 8h
act-runner-vol Bound pvc-b15a377c-8d9f-427f-9e52-d9b6cf457dc0 1Gi RWO local-path 7s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-78cc4c645b-lxpbc 1/1 Running 0 5d6h
ngrok-669dd5fdd8-lxdkg 1/1 Running 2 (28h ago) 7d6h
vote-front-azure-vote-1688994153-6fdc76bdd9-vk92z 1/1 Running 1 (28h ago) 5d6h
vote-back-azure-vote-1688994153-7b76fb69b9-xxzgc 1/1 Running 1 (28h ago) 7d6h
gitea-memcached-8666cf9db5-s2p4q 1/1 Running 0 8h
gitea-postgresql-0 1/1 Running 0 8h
gitea-0 1/1 Running 0 20m
act-runner-84f56cb5c4-9nsnm 2/2 Running 0 19s
act-runner-84f56cb5c4-rdtwq 2/2 Running 0 17s
I could now see one runner already registered
Let’s create a simple hello-world action
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ mkdir -p .gitea/workflows
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ touch .gitea/workflows/hello.yaml
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ vi .gitea/workflows/hello.yaml
$ cat .gitea/workflows/hello.yaml
name: Gitea Actions Demo
run-name: $ is testing out Gitea Actions 🚀
on: [push]
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a $ event."
- run: echo "🐧 This job is now running on a $ server hosted by Gitea!"
- run: echo "🔎 The name of your branch is $ and your repository is $."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The $ repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: List files in the repository
run: |
ls $
- run: echo "🍏 This job's status is $."
I’ll now add and push
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git commit -m "first try"
[feature 41dfeef] first try
1 file changed, 18 insertions(+)
create mode 100644 .gitea/workflows/hello.yaml
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git push
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 784 bytes | 784.00 KiB/s, done.
Total 5 (delta 1), reused 0 (delta 0)
remote:
remote: Create a new pull request for 'feature':
remote: http://git.example.com/FreshBrewed/PublicShared/compare/main...feature
remote:
remote: . Processing 1 references
remote: Processed 1 references in total
To http://localhost:3000/FreshBrewed/PublicShared.git
* [new branch] feature -> feature
I put it in a feature branch which I would not expect to execute. I’ll need to create a PR
I merged then removed the branch
Initially I didn’t see any actions run. This was because I needed to enable actions on the repository
I can see the actions, but it’s set to trigger on a push
I’ll switch to main and push an empty commit to trigger a run
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git checkout main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git pull
remote: Enumerating objects: 6, done.
remote: Counting objects: 100% (6/6), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (4/4), 893 bytes | 893.00 KiB/s, done.
From http://localhost:3000/FreshBrewed/PublicShared
4e71d4c..5966983 main -> origin/main
* [new tag] 0.1.0 -> 0.1.0
Updating 4e71d4c..5966983
Fast-forward
.gitea/workflows/hello.yaml | 18 ++++++++++++++++++
Feature.md | 1 +
2 files changed, 19 insertions(+)
create mode 100644 .gitea/workflows/hello.yaml
create mode 100644 Feature.md
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git commit --allow-empty -m "push an empty commit to trigger an action run"
[main df3f35c] push an empty commit to trigger an action run
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git push
Enumerating objects: 1, done.
Counting objects: 100% (1/1), done.
Writing objects: 100% (1/1), 211 bytes | 211.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
remote: . Processing 1 references
remote: Processed 1 references in total
To http://localhost:3000/FreshBrewed/PublicShared.git
5966983..df3f35c main -> main
I can now see it running
The first step took a bit but the rest were quick
I can expand some of the steps to see the outputs
Secrets
Say our Runner needs to do something that requires a secret, for instance, update an S3 bucket or GCP cloud bucket. We would need AWS Secret Access Keys and secrets or a GCP SA json.
This is where Secrets come to play
We can create a new secret in Secrets
I can now see the entry under Secrets
I’ll try and show the secret
$ cat .gitea/workflows/hello.yaml
name: Gitea Actions Demo
run-name: $ is testing out Gitea Actions 🚀
on: [push]
jobs:
Explore-Gitea-Actions:
runs-on: ubuntu-latest
steps:
- run: echo "🎉 The job was automatically triggered by a $ event."
- run: echo "🐧 This job is now running on a $ server hosted by Gitea!"
- run: echo "🔎 The name of your branch is $ and your repository is $."
- name: Check out repository code
uses: actions/checkout@v3
- run: echo "💡 The $ repository has been cloned to the runner."
- run: echo "🖥️ The workflow is now ready to test your code on the runner."
- name: secretstep
run: echo "$MYSECVAL -- $MYSECRET"
env:
MYSECVAL: $
- name: List files in the repository
run: |
export
ls $
env:
MYSECVAL: $
- run: echo "🍏 This job's status is $."
- run: echo "🍏 This job's status is $."
We can see that it is properly exposed as an env var
Branch protections
You can tell I pushed directly to main when I made my most recent change. Generally we want to ensure PRs are created on restricted branches.
An easy way to do this is to use Branch Protection.
We can go to “Branches” and click “Add New Rule” to create a proper branch branch protection rule
I would like to make sure only gitea_admin can push. I’ll require approvals from the admin, block on rejected reviews, dismiss stale approvals and block if the PR is outdated.
Since I’m locally logged in as ‘builder’, we can see my direct push to main was rejected
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ vi .gitea/workflows/hello.yaml
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git add .gitea/workflows/hello.yaml
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git commit -m 'remove a debug step'
[main 535ecc7] remove a debug step
1 file changed, 4 deletions(-)
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git push
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 400 bytes | 400.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0)
remote:
remote: Gitea: Not allowed to push to protected branch main
To http://localhost:3000/FreshBrewed/PublicShared.git
! [remote rejected] main -> main (pre-receive hook declined)
error: failed to push some refs to 'http://localhost:3000/FreshBrewed/PublicShared.git'
I’ll switch to a feature branch and try again
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git checkout -b feature-remove-debug-step-in-workflow
Switched to a new branch 'feature-remove-debug-step-in-workflow'
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ git push
fatal: The current branch feature-remove-debug-step-in-workflow has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin feature-remove-debug-step-in-workflow
builder@DESKTOP-QADGF36:~/Workspaces/PublicShared$ darf
git push --set-upstream origin feature-remove-debug-step-in-workflow [enter/↑/↓/ctrl+c]
Enumerating objects: 9, done.
Counting objects: 100% (9/9), done.
Delta compression using up to 16 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (5/5), 400 bytes | 400.00 KiB/s, done.
Total 5 (delta 2), reused 0 (delta 0)
remote:
remote: Create a new pull request for 'feature-remove-debug-step-in-workflow':
remote: http://git.example.com/FreshBrewed/PublicShared/compare/main...feature-remove-debug-step-in-workflow
remote:
remote: . Processing 1 references
remote: Processed 1 references in total
To http://localhost:3000/FreshBrewed/PublicShared.git
* [new branch] feature-remove-debug-step-in-workflow -> feature-remove-debug-step-in-workflow
Branch 'feature-remove-debug-step-in-workflow' set up to track remote branch 'feature-remove-debug-step-in-workflow' from 'origin'.
I can now make a new PR
If I am logged in as gitea_admin, there really are no blocks. So I logged out and came back as builder to create the PR
Unfortunately I am an admin as builder as well so I could force a merge
Make it live
We’ve had some fun on a demo cluster. I can clearly see this is something I’m going to want to keep. So let’s move this to production.
I’ll create and apply an A record
$ cat r53-gitea.json
{
"Comment": "CREATE gitea fb.s A record ",
"Changes": [
{
"Action": "CREATE",
"ResourceRecordSet": {
"Name": "gitea.freshbrewed.science",
"Type": "A",
"TTL": 300,
"ResourceRecords": [
{
"Value": "75.72.238.228"
}
]
}
}
]
}
$ aws route53 change-resource-record-sets --hosted-zone-id Z39E8QFU0F9PZP --change-batch file://r53-gitea.json
{
"ChangeInfo": {
"Id": "/change/C01488602LUSLC1J41O82",
"Status": "PENDING",
"SubmittedAt": "2023-07-18T10:45:41.728Z",
"Comment": "CREATE gitea fb.s A record "
}
}
I thought about keeping it simple with a series of set commands and adding Ingress after the fact, but let’s try and use a proper values file
$ cat values.yaml
gitea:
admin:
username: "builder"
password: "NOTMYPASSWORDCLEARLY"
email: "isaac.johnson@gmail.com"
config:
actions:
ENABLED: true
server:
DOMAIN: gitea.freshbrewed.science
ROOT_URL: https://gitea.freshbrewed.science/
metrics:
enabled: true
global:
storageClass: "managed-nfs-storage"
ingress:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
ingress.kubernetes.io/proxy-body-size: "0"
ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.org/client-max-body-size: "0"
nginx.org/proxy-connect-timeout: "600"
nginx.org/proxy-read-timeout: "600"
enabled: true
hosts:
- host: gitea.freshbrewed.science
paths:
- path: /
pathType: ImplementationSpecific
tls:
- hosts:
- gitea.freshbrewed.science
secretName: gitea-tls
Then install
$ helm upgrade --install gitea -f values.yaml gitea-charts/gitea
coalesce.go:175: warning: skipped value for memcached.initContainers: Not a table.
Release "gitea" has been upgraded. Happy Helming!
NAME: gitea
LAST DEPLOYED: Tue Jul 18 06:10:59 2023
NAMESPACE: default
STATUS: deployed
REVISION: 2
NOTES:
1. Get the application URL by running these commands:
https://gitea.freshbrewed.science/
It took a full three and half minutes to get the cert through, but when it was complete, I could see the instance
I can login with the admin account I specified earlier
I realized one consequence is the built-in containerized database
$ kubectl get pods | grep gitea
gitea-memcached-5bd6f8f89d-lvbxt 1/1 Running 0 13m
gitea-postgresql-0 1/1 Running 0 13m
gitea-0 1/1 Running 0 13m
If I’m going to put source code here, I need a more permanent DB
While PostgreSQL isn’t in the app list for Synology, MariaDB (MySQL) is.
I’ll install (again, using the new DS220+ NAS)
I’ll need to enable TCP/IP on 3306 if I want Kubernetes to be able to access it
I’ll want to setup an account for gitea. As a forcing function to ensure it is listening on 3306, I’ll do the steps locally.
First I need to get mysql client binaries (I do a lot more PSQL than MySQL)
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
libappstream-glib8 liblttng-ust-ctl4 liblttng-ust0 python3-crcmod xdg-dbus-proxy
Use 'sudo apt autoremove' to remove them.
The following additional packages will be installed:
mariadb-common mysql-common
The following NEW packages will be installed:
mariadb-client-core-10.3 mariadb-common mysql-common
0 upgraded, 3 newly installed, 0 to remove and 318 not upgraded.
Need to get 5878 kB of archives.
After this operation, 28.4 MB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://archive.ubuntu.com/ubuntu focal/main amd64 mysql-common all 5.8+1.0.5ubuntu2 [7496 B]
Get:2 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 mariadb-common all 1:10.3.38-0ubuntu0.20.04.1 [15.9 kB]
Get:3 http://archive.ubuntu.com/ubuntu focal-updates/universe amd64 mariadb-client-core-10.3 amd64 1:10.3.38-0ubuntu0.20.04.1 [5855 kB]
Fetched 5878 kB in 1s (9156 kB/s)
Selecting previously unselected package mysql-common.
(Reading database ... 210532 files and directories currently installed.)
Preparing to unpack .../mysql-common_5.8+1.0.5ubuntu2_all.deb ...
Unpacking mysql-common (5.8+1.0.5ubuntu2) ...
Selecting previously unselected package mariadb-common.
Preparing to unpack .../mariadb-common_1%3a10.3.38-0ubuntu0.20.04.1_all.deb ...
Unpacking mariadb-common (1:10.3.38-0ubuntu0.20.04.1) ...
Selecting previously unselected package mariadb-client-core-10.3.
Preparing to unpack .../mariadb-client-core-10.3_1%3a10.3.38-0ubuntu0.20.04.1_amd64.deb ...
Unpacking mariadb-client-core-10.3 (1:10.3.38-0ubuntu0.20.04.1) ...
Setting up mysql-common (5.8+1.0.5ubuntu2) ...
update-alternatives: using /etc/mysql/my.cnf.fallback to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Setting up mariadb-common (1:10.3.38-0ubuntu0.20.04.1) ...
update-alternatives: using /etc/mysql/mariadb.cnf to provide /etc/mysql/my.cnf (my.cnf) in auto mode
Setting up mariadb-client-core-10.3 (1:10.3.38-0ubuntu0.20.04.1) ...
Processing triggers for man-db (2.9.1-1) ...
...
While, from a networking perspective, I can connect. MariaDB doesn’t like remote access from my desktop
builder@DESKTOP-QADGF36:~/Workspaces/ansible-playbooks$ mysql -u root -p --host=192.168.1.117
Enter password:
ERROR 1130 (HY000): Host 'DESKTOP-QADGF36' is not allowed to connect to this MariaDB server
I’ll need to do the commands locally for now (but I’ll test again back on the other desktop)
builder@DESKTOP-QADGF36:~/Workspaces/ansible-playbooks$ ssh ijohnson@192.168.1.117
ijohnson@192.168.1.117's password:
Using terminal commands to modify system configs, execute external binary
files, add files, or install unauthorized third-party apps may lead to system
damages or unexpected behavior, or cause data loss. Make sure you are aware of
the consequences of each command and proceed at your own risk.
Warning: Data should only be stored in shared folders. Data stored elsewhere
may be deleted when the system is updated/restarted.
ijohnson@sirnasilot:~$ mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.3.37-MariaDB Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
My MariaDB has password rules so I cannot do the simple passwords
MariaDB [(none)]> CREATE USER 'gitea'@'%' IDENTIFIED BY 'gitea1234';
ERROR 1819 (HY000): Your password does not satisfy the current policy requirements: [Minimal password length 10, Include mixed case, Include special characters, Exclude name of user from password]
I used a more painfully long complicated password (rather than fight MariaDB).
The end result (with a more complicated password, of course):
ijohnson@sirnasilot:~$ mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 10.3.37-MariaDB Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> set old_passwords=0;
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> CREATE USER 'gitea'@'%' IDENTIFIED BY 'NOTTHEPASSWORDIUSED';
Query OK, 0 rows affected (0.024 sec)
MariaDB [(none)]> CREATE DATABASE giteadb CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_unicode_ci';
Query OK, 1 row affected (0.000 sec)
MariaDB [(none)]> GRANT ALL PRIVILEGES ON giteadb.* TO 'gitea'@'%';
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.001 sec)
I can now test on the workstation
builder@DESKTOP-QADGF36:~/Workspaces/ansible-playbooks$ mysql -u gitea -p --host=192.168.1.117
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 12
Server version: 10.3.37-MariaDB Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>
I’ll now update my values.yaml file (again passwords are there but replaced below)
$ cat values.yaml
gitea:
admin:
username: "builder"
password: "NOPENOTMYPASSWORD"
email: "isaac.johnson@gmail.com"
config:
actions:
ENABLED: true
database:
DB_TYPE: mysql
HOST: 192.168.1.117
NAME: giteadb
USER: gitea
PASSWD: THEDBPASSWORDIUSED
SCHEMA: gitea
server:
DOMAIN: gitea.freshbrewed.science
ROOT_URL: https://gitea.freshbrewed.science/
metrics:
enabled: true
postgresql:
enabled: false
global:
storageClass: "managed-nfs-storage"
ingress:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
ingress.kubernetes.io/proxy-body-size: "0"
ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.org/client-max-body-size: "0"
nginx.org/proxy-connect-timeout: "600"
nginx.org/proxy-read-timeout: "600"
enabled: true
hosts:
- host: gitea.freshbrewed.science
paths:
- path: /
pathType: ImplementationSpecific
tls:
- hosts:
- gitea.freshbrewed.science
secretName: gitea-tls
Let’s upgrade to use the chart
$ helm upgrade --install gitea -f values.yaml gitea-charts/gitea
Release "gitea" has been upgraded. Happy Helming!
NAME: gitea
LAST DEPLOYED: Tue Jul 18 06:46:50 2023
NAMESPACE: default
STATUS: deployed
REVISION: 3
NOTES:
1. Get the application URL by running these commands:
https://gitea.freshbrewed.science/
I had some errors connecting. I granted more access rights to the gitea user to see if that would help (as this mariadb is just for gitea for now)
ijohnson@sirnasilot:~$ mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 23
Server version: 10.3.37-MariaDB Source distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'gitea'@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.000 sec)
MariaDB [(none)]> exit;
Bye
The startup was taking time
$ kubectl get pods gitea-0
NAME READY STATUS RESTARTS AGE
gitea-0 0/1 Init:2/3 0 4m12s
So I checked logs. Indeed, it just slowly builds and populates the database
$ kubectl logs gitea-0 configure-gitea | tail -n5
2023/07/18 11:58:28 models/db/engine.go:125:SyncAllTables() [I] [SQL] CREATE INDEX `IDX_gpg_key_key_id` ON `gpg_key` (`key_id`) [] - 2.189529088s
2023/07/18 11:58:30 models/db/engine.go:125:SyncAllTables() [I] [SQL] CREATE TABLE IF NOT EXISTS `gpg_key_import` (`key_id` CHAR(16) PRIMARY KEY NOT NULL, `content` MEDIUMTEXT NOT NULL) ENGINE=InnoDB DEFAULT CHARSET utf8mb4 ROW_FORMAT=DYNAMIC [] - 1.925290483s
2023/07/18 11:58:32 models/db/engine.go:125:SyncAllTables() [I] [SQL] CREATE TABLE IF NOT EXISTS `public_key` (`id` BIGINT(20) PRIMARY KEY AUTO_INCREMENT NOT NULL, `owner_id` BIGINT(20) NOT NULL, `name` VARCHAR(255) NOT NULL, `fingerprint` VARCHAR(255) NOT NULL, `content` MEDIUMTEXT NOT NULL, `mode` INT DEFAULT 2 NOT NULL, `type` INT DEFAULT 1 NOT NULL, `login_source_id` BIGINT(20) DEFAULT 0 NOT NULL, `created_unix` BIGINT(20) NULL, `updated_unix` BIGINT(20) NULL, `verified` TINYINT(1) DEFAULT false NOT NULL) ENGINE=InnoDB DEFAULT CHARSET utf8mb4 ROW_FORMAT=DYNAMIC [] - 1.224519258s
2023/07/18 11:58:33 models/db/engine.go:125:SyncAllTables() [I] [SQL] CREATE INDEX `IDX_public_key_fingerprint` ON `public_key` (`fingerprint`) [] - 1.41758808s
2023/07/18 11:58:34 models/db/engine.go:125:SyncAllTables() [I] [SQL] CREATE INDEX `IDX_public_key_owner_id` ON `public_key` (`owner_id`) [] - 1.26717571s
Maybe my MariaDB is non-performant, but in the end it took nearly 14m to come up
$ kubectl get pods gitea-0
NAME READY STATUS RESTARTS AGE
gitea-0 1/1 Running 0 15m
I signed in and found it to be just as performant as before.
My first step was to make a public organization
At the moment, it is enabled to allow anyone to create a Gitea account. That could spell trouble
I updated the values to add both a Sendgrid mailer, enable OpenID and disable self registration
$ cat values.yaml
gitea:
admin:
username: "builder"
password: "STILLNOTTHEREALPASSWORD"
email: "isaac.johnson@gmail.com"
config:
actions:
ENABLED: true
database:
DB_TYPE: mysql
HOST: 192.168.1.117
NAME: giteadb
USER: gitea
PASSWD: STILLNOTTHEREALPASSWORD
SCHEMA: gitea
mailer:
ENABLED: true
FROM: isaac@freshbrewed.science
MAILER_TYPE: smtp
SMTP_ADDR: smtp.sendgrid.net
SMTP_PORT: 465
USER: apikey
PASSWD: SG.STILLNOTTHEREALPASSWORD
openid:
ENABLE_OPENID_SIGNIN: false
ENABLE_OPENID_SIGNUP: false
server:
DOMAIN: gitea.freshbrewed.science
ROOT_URL: https://gitea.freshbrewed.science/
service:
DISABLE_REGISTRATION: true
metrics:
enabled: true
postgresql:
enabled: false
global:
storageClass: "managed-nfs-storage"
ingress:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
ingress.kubernetes.io/proxy-body-size: "0"
ingress.kubernetes.io/ssl-redirect: "true"
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-body-size: "0"
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.org/client-max-body-size: "0"
nginx.org/proxy-connect-timeout: "600"
nginx.org/proxy-read-timeout: "600"
enabled: true
hosts:
- host: gitea.freshbrewed.science
paths:
- path: /
pathType: ImplementationSpecific
tls:
- hosts:
- gitea.freshbrewed.science
secretName: gitea-tls
This time it took less than 20s for the pod to come up after i did a helm upgrade meaning the DB init steps really are just one time.
I now see this for registration
With sendgrid enabled, i can now properly handle password resets
Actions setup
Since I now have a proper instance, I best add some Actions Workers
I’ll create a new runner token
I really have a choice on the INSTANCE URL.
Since the runner is local to the cluster, I could just use the external name
- name: GITEA_INSTANCE_URL
value: https://gitea.freshbrewed.science
However, since it is in the same namespace, I’ll just do as before and go right to the service
- name: GITEA_INSTANCE_URL
value: http://gitea-http.default.svc.cluster.local:3000
I would need to former to launch this in a different cluster
$ kubectl apply -f gitea-dind-final.yaml
persistentvolumeclaim/act-runner-vol created
secret/runner-secret created
deployment.apps/act-runner created
I can now see two workers
$ kubectl get pods -l app=act-runner
NAME READY STATUS RESTARTS AGE
act-runner-658c549869-fkskt 2/2 Running 0 62s
act-runner-658c549869-n8wr8 2/2 Running 0 62s
and the same in Gitea
Summary
In Part 2 we have explored actions, using the Docker in Docker (DinD) yaml to launch local runners, and tested workflows. We looked at passing secrets to workflows and applying branch protections to ensure PRs on our Repositories.
We then pivoted to creating a production on-prem version in Kubernetes using an external MariaDB (MySQL) Database hosted on a NAS. Once setup, we updated our chart to disable user signup, add a properly mailer configuration for SendGrid and create the first public repo (live now at https://gitea.freshbrewed.science/FreshbrewedPublic).