All checks were successful
Deploy to Staging / Build Images (push) Successful in 21s
Deploy to Staging / Deploy to Staging (push) Successful in 28s
Deploy to Staging / Verify Staging (push) Successful in 7s
Deploy to Staging / Notify Staging Ready (push) Successful in 6s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
341 lines
10 KiB
YAML
341 lines
10 KiB
YAML
---
|
|
# 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: Configure passwordless sudo for act_runner
|
|
copy:
|
|
dest: /etc/sudoers.d/act_runner
|
|
content: |
|
|
# Allow act_runner to run commands without password for CI/CD operations
|
|
# This is required because Gitea Actions runners don't have a TTY
|
|
act_runner ALL=(ALL) NOPASSWD: ALL
|
|
mode: '0440'
|
|
validate: 'visudo -cf %s'
|
|
|
|
- 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 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 secrets are configured in:
|
|
{{ app_root }}/secrets/app/
|
|
================================================
|