Gitea repo init; Woodpecker pipeline init; much CI/CD structure outlined in ./infra, incl. docker-compose.yaml, cicd-playbook.yaml, new cicd vault, & config files for gitea, woodpecker & ansible
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
src/db.sqlite3
|
src/db.sqlite3
|
||||||
|
.claude
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,6 +1,9 @@
|
|||||||
# Created by https://www.toptal.com/developers/gitignore/api/django
|
# Created by https://www.toptal.com/developers/gitignore/api/django
|
||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=django
|
# Edit at https://www.toptal.com/developers/gitignore?templates=django
|
||||||
|
|
||||||
|
### Claude ###
|
||||||
|
.claude
|
||||||
|
|
||||||
### Django ###
|
### Django ###
|
||||||
*.log
|
*.log
|
||||||
*.pot
|
*.pot
|
||||||
|
|||||||
7
.woodpecker.yaml
Normal file
7
.woodpecker.yaml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
steps:
|
||||||
|
- name: test
|
||||||
|
image: python:3.13-slim
|
||||||
|
commands:
|
||||||
|
- "pip install -r requirements.txt"
|
||||||
|
- "cd ./src"
|
||||||
|
- "python manage.py test apps"
|
||||||
3
ansible.cfg
Normal file
3
ansible.cfg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = infra/inventory.ini
|
||||||
|
vault_password_file = ~/.vault-pass.txt
|
||||||
114
infra/cicd-playbook.yaml
Normal file
114
infra/cicd-playbook.yaml
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
- hosts: cicd
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Install Docker
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: docker.io
|
||||||
|
state: latest
|
||||||
|
update_cache: true
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Install Nginx
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: nginx
|
||||||
|
state: latest
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Add out user to the docker group, so we don't need sudo/become
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: '{{ ansible_user }}'
|
||||||
|
groups: docker
|
||||||
|
append: true # don't remove any existing groups
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Reset ssh connection to allow the user/group change to take effect
|
||||||
|
ansible.builtin.meta: reset_connection
|
||||||
|
|
||||||
|
- name: Install docker-compose-plugin & certbot
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- docker-compose-v2
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-nginx
|
||||||
|
state: latest
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Create /opt/cicd/ directory tree
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "/opt/cicd/nginx"
|
||||||
|
state: directory
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Cp docker-compose.yaml to server
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: cicd/docker-compose.yaml
|
||||||
|
dest: /opt/cicd/docker-compose.yaml
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Template .env to /opt/cicd/
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: cicd/.env.j2
|
||||||
|
dest: /opt/cicd/.env
|
||||||
|
mode: "0600"
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Deploy nginx config (Gitea)
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: cicd/nginx/gitea.conf
|
||||||
|
dest: /etc/nginx/sites-available/gitea
|
||||||
|
become: true
|
||||||
|
notify: Restart nginx
|
||||||
|
|
||||||
|
- name: Deploy nginx config (Woodpecker)
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: cicd/nginx/woodpecker.conf
|
||||||
|
dest: /etc/nginx/sites-available/woodpecker
|
||||||
|
become: true
|
||||||
|
notify: Restart nginx
|
||||||
|
|
||||||
|
- name: Enable nginx site (Gitea)
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /etc/nginx/sites-available/gitea
|
||||||
|
dest: /etc/nginx/sites-enabled/gitea
|
||||||
|
state: link
|
||||||
|
become: true
|
||||||
|
notify: Restart nginx
|
||||||
|
|
||||||
|
- name: Enable nginx site (Woodpecker)
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: /etc/nginx/sites-available/woodpecker
|
||||||
|
dest: /etc/nginx/sites-enabled/woodpecker
|
||||||
|
state: link
|
||||||
|
become: true
|
||||||
|
notify: Restart nginx
|
||||||
|
|
||||||
|
- name: Remove default nginx site
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/nginx/sites-enabled/default
|
||||||
|
state: absent
|
||||||
|
become: true
|
||||||
|
notify: Restart nginx
|
||||||
|
|
||||||
|
- name: Obtain SSL certs via certbot
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >
|
||||||
|
certbot --nginx
|
||||||
|
-d gitea.earthmanrpg.me
|
||||||
|
-d ci.earthmanrpg.me
|
||||||
|
--non-interactive
|
||||||
|
--agree-tos
|
||||||
|
-m discodedisco@outlook.com
|
||||||
|
creates: /etc/letsencrypt/live/gitea.earthmanrpg.me/fullchain.pem
|
||||||
|
become: true
|
||||||
|
|
||||||
|
- name: Run docker compose -f /opt/cicd/docker-compose.yaml up -d
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: docker compose -f /opt/cicd/docker-compose.yaml up -d
|
||||||
|
become: true
|
||||||
|
|
||||||
|
handlers:
|
||||||
|
- name: Restart nginx
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: nginx
|
||||||
|
state: restarted
|
||||||
|
become: true
|
||||||
4
infra/cicd/.env.j2
Normal file
4
infra/cicd/.env.j2
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
WOODPECKER_ADMIN={{ woodpecker_admin }}
|
||||||
|
WOODPECKER_AGENT_SECRET={{ woodpecker_agent_secret }}
|
||||||
|
WOODPECKER_GITEA_CLIENT={{ woodpecker_gitea_client }}
|
||||||
|
WOODPECKER_GITEA_SECRET={{ woodpecker_gitea_secret }}
|
||||||
58
infra/cicd/docker-compose.yaml
Normal file
58
infra/cicd/docker-compose.yaml
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
services:
|
||||||
|
gitea:
|
||||||
|
image: docker.gitea.com/gitea:1.24
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
- USER_UID=1000
|
||||||
|
- USER_GID=1000
|
||||||
|
- GITEA__server__ROOT_URL=https://gitea.earthmanrpg.me/
|
||||||
|
- GITEA__server__DOMAIN=gitea.earthmanrpg.me
|
||||||
|
- GITEA__server__SSH_DOMAIN=gitea.earthmanrpg.me
|
||||||
|
- GITEA__webhook__ALLOWED_HOST_LIST=external,loopback
|
||||||
|
volumes:
|
||||||
|
- ./data/gitea:/data # Gitea stores repos, db, config here
|
||||||
|
- /etc/timezone:/etc/timezone:ro
|
||||||
|
- /etc/localtime:/etc/localtime:ro
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:3000:3000" # http (only localhost, nginx proxies)
|
||||||
|
- "222:22" # ssh (public, for git push)
|
||||||
|
networks:
|
||||||
|
- cicd
|
||||||
|
|
||||||
|
woodpecker-server:
|
||||||
|
image: woodpeckerci/woodpecker-server:v3
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- gitea
|
||||||
|
environment:
|
||||||
|
- WOODPECKER_HOST=https://ci.earthmanrpg.me
|
||||||
|
- WOODPECKER_OPEN=false
|
||||||
|
- WOODPECKER_ADMIN=${WOODPECKER_ADMIN}
|
||||||
|
- WOODPECKER_GITEA=true
|
||||||
|
- WOODPECKER_GITEA_URL=https://gitea.earthmanrpg.me
|
||||||
|
- WOODPECKER_GITEA_CLIENT=${WOODPECKER_GITEA_CLIENT}
|
||||||
|
- WOODPECKER_GITEA_SECRET=${WOODPECKER_GITEA_SECRET}
|
||||||
|
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||||
|
volumes:
|
||||||
|
- ./data/woodpecker-server:/var/lib/woodpecker
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8000:8000" # (only nginx proxies)
|
||||||
|
networks:
|
||||||
|
- cicd
|
||||||
|
|
||||||
|
woodpecker-agent:
|
||||||
|
image: woodpeckerci/woodpecker-agent:v3
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
- woodpecker-server
|
||||||
|
environment:
|
||||||
|
- WOODPECKER_SERVER=woodpecker-server:9000
|
||||||
|
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
|
||||||
|
- WOODPECKER_MAX_WORKFLOWS=2
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
|
networks:
|
||||||
|
- cicd
|
||||||
|
|
||||||
|
networks:
|
||||||
|
cicd:
|
||||||
14
infra/cicd/nginx/gitea.conf
Normal file
14
infra/cicd/nginx/gitea.conf
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name gitea.earthmanrpg.me;
|
||||||
|
|
||||||
|
client_max_body_size 100m;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:3000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
}
|
||||||
16
infra/cicd/nginx/woodpecker.conf
Normal file
16
infra/cicd/nginx/woodpecker.conf
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name ci.earthmanrpg.me;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://127.0.0.1:8000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# WebSocket support (Woodpecker live log streaming)
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
}
|
||||||
|
}
|
||||||
18
infra/group_vars/cicd/vault.yaml
Normal file
18
infra/group_vars/cicd/vault.yaml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
|
32353432336330376365646535626462343239653737383565353163623230393338633536653231
|
||||||
|
3536303839613765643136366535333962376665306662620a383634393561653139306139366631
|
||||||
|
34663365316264656235396538653035366437663030383962373936336464306632333662623737
|
||||||
|
3834366363383135330a643064383065653565636334636336366138383464663562363030313636
|
||||||
|
30356332663332613565313339633036653463636264643531383231613739653061333134333337
|
||||||
|
36643365303637653635613838626466353163386331383864623936326636303734326566626561
|
||||||
|
32633562336663303866376335363935343031363465353834303133376363376665333363343535
|
||||||
|
35616532616264663631626135353134623965613539336562353963363534336261663530343331
|
||||||
|
30636332633538313838363434386331323837376663666463393736383830363966373662316539
|
||||||
|
39343466626633313734363732386135333636663735646430616130353765616133393165366231
|
||||||
|
62613130306164323938373964313938613634396665363161646264323332316664656265643231
|
||||||
|
35393032343263316464333530623365303430623235363862393435646433616566336136353236
|
||||||
|
34636630373530393464663839656661313364333830383966353739346335643635393030396335
|
||||||
|
30653332306163346431353535613338323163333032333435613139383366336338326635363165
|
||||||
|
34353033346362646131353339666561353766366239643661313334646365666236616232623865
|
||||||
|
37636162613334353632346664343034303861393833363535343063623831613735303762643064
|
||||||
|
31303161306364356436393665363939643736353238333037393936303136336566
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
$ANSIBLE_VAULT;1.1;AES256
|
|
||||||
33333861646565323863616363316265346132643135656533613763336462656361353562396163
|
|
||||||
6461313530323231383264373737323934346239316232340a356130646163636436663162386438
|
|
||||||
30636530373663643166616665313738303437636562643035303138613861656165663939613433
|
|
||||||
3465316130343732660a376536373136636162316665386536363536306130383033623735396634
|
|
||||||
66383262643630356536633366373933313637646539643137356330316463356139613738386661
|
|
||||||
34663231656232666630653162653732363431613461396464623133303965636432626536306634
|
|
||||||
64373530313532353531633263383335653239386530343330326237343862386436633666646235
|
|
||||||
31613530383834656462366535643030356562313237363735386337356165663564336564623862
|
|
||||||
34623863623738653735393734336635616135383036306231623464653432616265626233306230
|
|
||||||
63646466323135363466393832636466646434303564653032323366346430306336363435653761
|
|
||||||
30336437373231376261326264616131653833616236623365393334303834626162343761623037
|
|
||||||
36666665663866643263383835626336353030626337303461396665343731666465653662396164
|
|
||||||
34306261356130363037643637303632663830383331346334313336663163303730306265393031
|
|
||||||
39653231373139616465326561313633306433653461653931663164363565363636316433323933
|
|
||||||
61333536323936306538343336663966633161633565666231393261643062636239323264623364
|
|
||||||
38376266393937376133366561663931356236396131376137653536636539613738356466363334
|
|
||||||
32326165316434636631613366376235633337356135333531623861343039346261656239613036
|
|
||||||
65303836323538373832646531343234666330363161343337623539633464303161343765363331
|
|
||||||
35386233303563346662633239346363373931333764383233623161313965623266656364383037
|
|
||||||
32393738356532346665613031346338363738666265303765363438663062663237353033393262
|
|
||||||
6137
|
|
||||||
@@ -1,7 +1,10 @@
|
|||||||
[staging]
|
[staging]
|
||||||
staging.earthmanrpg.me
|
staging.earthmanrpg.me ansible_user=discoman ansible_ssh_private_key_file=~/.ssh/id_ed25519_wsl_python-tdd
|
||||||
|
|
||||||
[production]
|
[production]
|
||||||
www.earthmanrpg.me
|
www.earthmanrpg.me ansible_user=discoman ansible_ssh_private_key_file=~/.ssh/id_ed25519_wsl_python-tdd
|
||||||
earthmanrpg.me
|
earthmanrpg.me ansible_user=discoman ansible_ssh_private_key_file=~/.ssh/id_ed25519_wsl_python-tdd
|
||||||
dashboard.earthmanrpg.me
|
dashboard.earthmanrpg.me ansible_user=discoman ansible_ssh_private_key_file=~/.ssh/id_ed25519_wsl_python-tdd
|
||||||
|
|
||||||
|
[cicd]
|
||||||
|
gitea.earthmanrpg.me ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_ed25519_wsl_python-tdd
|
||||||
|
|||||||
Reference in New Issue
Block a user