feat: Update to Gitea CI/CD
Some checks failed
Deploy to Staging / Build Images (push) Has been cancelled
Deploy to Staging / Deploy to Staging (push) Has been cancelled
Deploy to Staging / Verify Staging (push) Has been cancelled
Deploy to Staging / Notify Staging Ready (push) Has been cancelled
Deploy to Staging / Notify Staging Failure (push) Has been cancelled

This commit is contained in:
Eric Gullickson
2025-12-29 21:09:32 -06:00
parent 83d79da3aa
commit eaab8c061a
9 changed files with 795 additions and 6 deletions

View File

@@ -0,0 +1,41 @@
# act_runner configuration template
# Managed by Ansible - do not edit manually
log:
level: info
runner:
file: .runner
capacity: 1
envs: {}
env_file: .env
timeout: 3h
shutdown_timeout: 0s
insecure: false
fetch_timeout: 5s
fetch_interval: 2s
github_mirror: ''
labels:
- "{{ runner_labels }}"
cache:
enabled: true
dir: ""
host: ""
port: 0
external_server: ""
container:
network: ""
privileged: false
options:
workdir_parent:
valid_volumes: []
docker_host: ""
force_pull: true
force_rebuild: false
require_docker: false
docker_timeout: 0s
host:
workdir_parent:

View File

@@ -0,0 +1,338 @@
---
# MotoVaultPro Production Runner Deployment Playbook
# Deploys act_runner for Gitea Actions on the production server
#
# Usage:
# ansible-playbook -i inventory.yml deploy-production-runner.yml --ask-become-pass
#
# Required variables (set in inventory or pass with -e):
# gitea_runner_token: Registration token from Gitea
# gitea_registry_token: Access token for package registry
# gitea_username: Username for registry login (default: egullickson)
#
# Optional variables:
# act_runner_version: Version of act_runner to install (default: 0.2.13)
# gitea_instance: Gitea server URL (default: https://git.motovaultpro.com)
- name: Deploy MotoVaultPro Production Runner
hosts: production
become: true
vars:
act_runner_version: "0.2.13"
gitea_instance: "https://git.motovaultpro.com"
gitea_username: "egullickson"
runner_name: "Production Server"
runner_labels: "prod:host"
app_root: "/opt/motovaultpro"
repo_url: "https://git.motovaultpro.com/egullickson/motovaultpro.git"
tasks:
# ============================================
# System Update and Prerequisites
# ============================================
- name: Update apt cache
apt:
update_cache: true
cache_valid_time: 3600
- name: Upgrade all packages
apt:
upgrade: dist
when: upgrade_packages | default(false)
- name: Install required packages
apt:
name:
- curl
- git
- ca-certificates
- gnupg
- jq
state: present
# ============================================
# Docker Installation
# ============================================
- name: Create keyrings directory
file:
path: /etc/apt/keyrings
state: directory
mode: '0755'
- name: Add Docker GPG key
shell: |
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
args:
creates: /etc/apt/keyrings/docker.gpg
- name: Get Ubuntu codename
command: lsb_release -cs
register: ubuntu_codename
changed_when: false
- name: Get architecture
command: dpkg --print-architecture
register: system_arch
changed_when: false
- name: Add Docker repository
apt_repository:
repo: "deb [arch={{ system_arch.stdout }} signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ubuntu_codename.stdout }} stable"
state: present
filename: docker
- name: Install Docker packages
apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
state: present
update_cache: true
- name: Ensure Docker service is running
systemd:
name: docker
state: started
enabled: true
# ============================================
# act_runner Installation
# ============================================
- name: Download act_runner binary
get_url:
url: "https://gitea.com/gitea/act_runner/releases/download/v{{ act_runner_version }}/act_runner-{{ act_runner_version }}-linux-amd64"
dest: /usr/local/bin/act_runner
mode: '0755'
- name: Verify act_runner installation
command: act_runner --version
register: act_runner_check
changed_when: false
- name: Display act_runner version
debug:
msg: "act_runner version: {{ act_runner_check.stdout }}"
# ============================================
# act_runner User Setup
# ============================================
- name: Create act_runner user
user:
name: act_runner
system: true
shell: /bin/bash
create_home: true
- name: Add act_runner to docker group
user:
name: act_runner
groups: docker
append: true
- name: Create act_runner config directory
file:
path: /etc/act_runner
state: directory
owner: act_runner
group: act_runner
mode: '0755'
# ============================================
# Runner Registration
# ============================================
- name: Check if runner is already registered
stat:
path: /etc/act_runner/.runner
register: runner_registered
- name: Deploy act_runner config
template:
src: config.yaml.j2
dest: /etc/act_runner/config.yaml
owner: act_runner
group: act_runner
mode: '0644'
notify: Restart act_runner
- name: Register runner with Gitea
shell: |
su - act_runner -c "cd /etc/act_runner && act_runner register --no-interactive \
--instance {{ gitea_instance }} \
--token {{ gitea_runner_token }} \
--name '{{ runner_name }}' \
--labels '{{ runner_labels }}'"
when: not runner_registered.stat.exists
no_log: true
# ============================================
# Systemd Service
# ============================================
- name: Create act_runner systemd service
copy:
dest: /etc/systemd/system/act_runner.service
content: |
[Unit]
Description=Gitea Actions Runner
After=docker.service network.target
[Service]
ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml
WorkingDirectory=/etc/act_runner
User=act_runner
Group=act_runner
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
mode: '0644'
notify: Restart act_runner
- name: Enable and start act_runner service
systemd:
name: act_runner
state: started
enabled: true
daemon_reload: true
# ============================================
# Production Environment Setup
# ============================================
- name: Create application directory
file:
path: "{{ app_root }}"
state: directory
owner: act_runner
group: act_runner
mode: '0755'
- name: Clone repository
shell: |
if [ ! -d "{{ app_root }}/.git" ]; then
su - act_runner -c "git clone {{ repo_url }} {{ app_root }}"
fi
args:
creates: "{{ app_root }}/.git"
- name: Create production secrets directory
file:
path: "{{ app_root }}/secrets/production"
state: directory
owner: act_runner
group: act_runner
mode: '0700'
- name: Create data directories
file:
path: "{{ app_root }}/{{ item }}"
state: directory
owner: '1001'
group: '1001'
mode: '0755'
loop:
- data/backups
- data/documents
# ============================================
# Docker Registry Authentication
# ============================================
- name: Create Docker config directory for act_runner
file:
path: /home/act_runner/.docker
state: directory
owner: act_runner
group: act_runner
mode: '0700'
- name: Configure Docker registry authentication
copy:
dest: /home/act_runner/.docker/config.json
content: |
{
"auths": {
"git.motovaultpro.com": {
"auth": "{{ (gitea_username + ':' + gitea_registry_token) | b64encode }}"
}
}
}
owner: act_runner
group: act_runner
mode: '0600'
no_log: true
when: gitea_registry_token is defined
# ============================================
# Maintenance Scripts
# ============================================
- name: Create Docker cleanup script
copy:
dest: /usr/local/bin/docker-cleanup.sh
content: |
#!/bin/bash
# Remove unused Docker resources older than 7 days
docker system prune -af --filter "until=168h"
docker volume prune -f
mode: '0755'
- name: Schedule Docker cleanup cron job
cron:
name: "Docker cleanup"
minute: "0"
hour: "3"
job: "/usr/local/bin/docker-cleanup.sh >> /var/log/docker-cleanup.log 2>&1"
# ============================================
# Production-Specific Security Hardening
# ============================================
- name: Set restrictive permissions on secrets
file:
path: "{{ app_root }}/secrets"
state: directory
owner: act_runner
group: act_runner
mode: '0700'
recurse: true
- name: Ensure no world-readable files in secrets
shell: find {{ app_root }}/secrets -type f -exec chmod 600 {} \;
changed_when: false
handlers:
- name: Restart act_runner
systemd:
name: act_runner
state: restarted
daemon_reload: true
post_tasks:
- name: Display runner status
command: systemctl status act_runner
register: runner_status
changed_when: false
ignore_errors: true
- name: Show deployment summary
debug:
msg: |
================================================
Production Runner Deployment Complete
================================================
Runner Name: {{ runner_name }}
Runner Labels: {{ runner_labels }}
Gitea Instance: {{ gitea_instance }}
Application Root: {{ app_root }}
Verify at: {{ gitea_instance }}/egullickson/motovaultpro/settings/actions/runners
Useful commands:
sudo systemctl status act_runner
sudo journalctl -u act_runner -f
docker ps
IMPORTANT: Ensure production secrets are configured in:
{{ app_root }}/secrets/production/
================================================

View File

@@ -0,0 +1,319 @@
---
# MotoVaultPro Staging/Build Runner Deployment Playbook
# Deploys act_runner for Gitea Actions on the build/staging server
#
# Usage:
# ansible-playbook -i inventory.yml deploy-staging-runner.yml --ask-become-pass
#
# Required variables (set in inventory or pass with -e):
# gitea_runner_token: Registration token from Gitea
# gitea_registry_token: Access token for package registry
# gitea_username: Username for registry login (default: egullickson)
#
# Optional variables:
# act_runner_version: Version of act_runner to install (default: 0.2.13)
# gitea_instance: Gitea server URL (default: https://git.motovaultpro.com)
- name: Deploy MotoVaultPro Staging/Build Runner
hosts: staging
become: true
vars:
act_runner_version: "0.2.13"
gitea_instance: "https://git.motovaultpro.com"
gitea_username: "egullickson"
runner_name: "Build/Staging Server"
runner_labels: "stage:host"
app_root: "/opt/motovaultpro"
repo_url: "https://git.motovaultpro.com/egullickson/motovaultpro.git"
tasks:
# ============================================
# System Update and Prerequisites
# ============================================
- name: Update apt cache
apt:
update_cache: true
cache_valid_time: 3600
- name: Upgrade all packages
apt:
upgrade: dist
when: upgrade_packages | default(false)
- name: Install required packages
apt:
name:
- curl
- git
- ca-certificates
- gnupg
- jq
state: present
# ============================================
# Docker Installation
# ============================================
- name: Create keyrings directory
file:
path: /etc/apt/keyrings
state: directory
mode: '0755'
- name: Add Docker GPG key
shell: |
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
args:
creates: /etc/apt/keyrings/docker.gpg
- name: Get Ubuntu codename
command: lsb_release -cs
register: ubuntu_codename
changed_when: false
- name: Get architecture
command: dpkg --print-architecture
register: system_arch
changed_when: false
- name: Add Docker repository
apt_repository:
repo: "deb [arch={{ system_arch.stdout }} signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu {{ ubuntu_codename.stdout }} stable"
state: present
filename: docker
- name: Install Docker packages
apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
state: present
update_cache: true
- name: Ensure Docker service is running
systemd:
name: docker
state: started
enabled: true
# ============================================
# act_runner Installation
# ============================================
- name: Download act_runner binary
get_url:
url: "https://gitea.com/gitea/act_runner/releases/download/v{{ act_runner_version }}/act_runner-{{ act_runner_version }}-linux-amd64"
dest: /usr/local/bin/act_runner
mode: '0755'
- name: Verify act_runner installation
command: act_runner --version
register: act_runner_check
changed_when: false
- name: Display act_runner version
debug:
msg: "act_runner version: {{ act_runner_check.stdout }}"
# ============================================
# act_runner User Setup
# ============================================
- name: Create act_runner user
user:
name: act_runner
system: true
shell: /bin/bash
create_home: true
- name: Add act_runner to docker group
user:
name: act_runner
groups: docker
append: true
- name: Create act_runner config directory
file:
path: /etc/act_runner
state: directory
owner: act_runner
group: act_runner
mode: '0755'
# ============================================
# Runner Registration
# ============================================
- name: Check if runner is already registered
stat:
path: /etc/act_runner/.runner
register: runner_registered
- name: Deploy act_runner config
template:
src: config.yaml.j2
dest: /etc/act_runner/config.yaml
owner: act_runner
group: act_runner
mode: '0644'
notify: Restart act_runner
- name: Register runner with Gitea
shell: |
su - act_runner -c "cd /etc/act_runner && act_runner register --no-interactive \
--instance {{ gitea_instance }} \
--token {{ gitea_runner_token }} \
--name '{{ runner_name }}' \
--labels '{{ runner_labels }}'"
when: not runner_registered.stat.exists
no_log: true
# ============================================
# Systemd Service
# ============================================
- name: Create act_runner systemd service
copy:
dest: /etc/systemd/system/act_runner.service
content: |
[Unit]
Description=Gitea Actions Runner
After=docker.service network.target
[Service]
ExecStart=/usr/local/bin/act_runner daemon --config /etc/act_runner/config.yaml
WorkingDirectory=/etc/act_runner
User=act_runner
Group=act_runner
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
mode: '0644'
notify: Restart act_runner
- name: Enable and start act_runner service
systemd:
name: act_runner
state: started
enabled: true
daemon_reload: true
# ============================================
# Staging Environment Setup
# ============================================
- name: Create application directory
file:
path: "{{ app_root }}"
state: directory
owner: act_runner
group: act_runner
mode: '0755'
- name: Clone repository
shell: |
if [ ! -d "{{ app_root }}/.git" ]; then
su - act_runner -c "git clone {{ repo_url }} {{ app_root }}"
fi
args:
creates: "{{ app_root }}/.git"
- name: Create staging secrets directory
file:
path: "{{ app_root }}/secrets/staging"
state: directory
owner: act_runner
group: act_runner
mode: '0700'
- name: Create data directories
file:
path: "{{ app_root }}/{{ item }}"
state: directory
owner: '1001'
group: '1001'
mode: '0755'
loop:
- data/backups
- data/documents
# ============================================
# Docker Registry Authentication
# ============================================
- name: Create Docker config directory for act_runner
file:
path: /home/act_runner/.docker
state: directory
owner: act_runner
group: act_runner
mode: '0700'
- name: Configure Docker registry authentication
copy:
dest: /home/act_runner/.docker/config.json
content: |
{
"auths": {
"git.motovaultpro.com": {
"auth": "{{ (gitea_username + ':' + gitea_registry_token) | b64encode }}"
}
}
}
owner: act_runner
group: act_runner
mode: '0600'
no_log: true
when: gitea_registry_token is defined
# ============================================
# Maintenance Scripts
# ============================================
- name: Create Docker cleanup script
copy:
dest: /usr/local/bin/docker-cleanup.sh
content: |
#!/bin/bash
# Remove unused Docker resources older than 7 days
docker system prune -af --filter "until=168h"
docker volume prune -f
mode: '0755'
- name: Schedule Docker cleanup cron job
cron:
name: "Docker cleanup"
minute: "0"
hour: "3"
job: "/usr/local/bin/docker-cleanup.sh >> /var/log/docker-cleanup.log 2>&1"
handlers:
- name: Restart act_runner
systemd:
name: act_runner
state: restarted
daemon_reload: true
post_tasks:
- name: Display runner status
command: systemctl status act_runner
register: runner_status
changed_when: false
ignore_errors: true
- name: Show deployment summary
debug:
msg: |
================================================
Staging/Build Runner Deployment Complete
================================================
Runner Name: {{ runner_name }}
Runner Labels: {{ runner_labels }}
Gitea Instance: {{ gitea_instance }}
Application Root: {{ app_root }}
Verify at: {{ gitea_instance }}/egullickson/motovaultpro/settings/actions/runners
Useful commands:
sudo systemctl status act_runner
sudo journalctl -u act_runner -f
docker ps
================================================

View File

@@ -0,0 +1,44 @@
---
# MotoVaultPro Ansible Inventory Example
# Copy this file to inventory.yml and fill in your values
#
# Usage:
# cp inventory.yml.example inventory.yml
# # Edit inventory.yml with your server IPs and tokens
# ansible-playbook -i inventory.yml deploy-staging-runner.yml --ask-become-pass
all:
children:
staging:
hosts:
staging.motovaultpro.com:
ansible_host: "172.30.1.37"
# Required: Get from Gitea -> Settings -> Actions -> Runners
gitea_runner_token: "szyvEDd2rRh4BettOTKORD1n2Vh47P1RIH19wLYN"
# Required: Get from Gitea -> Settings -> Applications
# Needs read:packages and write:packages scopes
gitea_registry_token: "0ca4ca2b6e84cf53df778ed7eed30d1e1900dcef"
# Optional overrides
# gitea_username: "egullickson"
# act_runner_version: "0.2.13"
# upgrade_packages: false
production:
hosts:
motovaultpro.com:
ansible_host: "172.30.1.36"
# Required: Get from Gitea -> Settings -> Actions -> Runners
gitea_runner_token: "OTwUZsoEUBjomGUVrOU4NxpYiUf2yQcEfYprt6rU"
# Required: Get from Gitea -> Settings -> Applications
# Needs read:packages and write:packages scopes
gitea_registry_token: "0ca4ca2b6e84cf53df778ed7eed30d1e1900dcef"
# Optional overrides
# gitea_username: "egullickson"
# act_runner_version: "0.2.13"
# upgrade_packages: false

View File

@@ -0,0 +1,48 @@
---
# MotoVaultPro Ansible Inventory Example
# Copy this file to inventory.yml and fill in your values
#
# Usage:
# cp inventory.yml.example inventory.yml
# # Edit inventory.yml with your server IPs and tokens
# ansible-playbook -i inventory.yml deploy-staging-runner.yml --ask-become-pass
all:
children:
staging:
hosts:
staging.motovaultpro.com:
ansible_host: "YOUR_STAGING_SERVER_IP"
ansible_user: "root" # or your SSH user
ansible_ssh_private_key_file: "~/.ssh/id_rsa"
# Required: Get from Gitea -> Settings -> Actions -> Runners
gitea_runner_token: "YOUR_RUNNER_REGISTRATION_TOKEN"
# Required: Get from Gitea -> Settings -> Applications
# Needs read:packages and write:packages scopes
gitea_registry_token: "YOUR_REGISTRY_ACCESS_TOKEN"
# Optional overrides
# gitea_username: "egullickson"
# act_runner_version: "0.2.13"
# upgrade_packages: false
production:
hosts:
motovaultpro.com:
ansible_host: "YOUR_PRODUCTION_SERVER_IP"
ansible_user: "root" # or your SSH user
ansible_ssh_private_key_file: "~/.ssh/id_rsa"
# Required: Get from Gitea -> Settings -> Actions -> Runners
gitea_runner_token: "YOUR_RUNNER_REGISTRATION_TOKEN"
# Required: Get from Gitea -> Settings -> Applications
# Needs read:packages and write:packages scopes
gitea_registry_token: "YOUR_REGISTRY_ACCESS_TOKEN"
# Optional overrides
# gitea_username: "egullickson"
# act_runner_version: "0.2.13"
# upgrade_packages: false