Add hi (74.50.113.232) with Forgejo + Caddy, bootstrapped support.vntx.net

- DNS: hi.mcintire.me A/AAAA, git.mcintire.me A/AAAA updated to new host
- forgejo role: Docker Compose deployment with SQLite, INSTALL_LOCK, admin user creation
- Caddyfile-hi.j2: reverse proxy git.mcintire.me -> localhost:3000
- tailscale role: skip connect when no auth key; dynamic repo suite
- debian role: fix Signed-By for debian.sources on trixie
- curl added to base Debian packages
- support.vntx.net: added to vntx_servers, DNS, host_vars
This commit is contained in:
Graham McIntire 2026-07-24 13:12:33 -05:00
parent 8018ce0eb1
commit 292758900e
No known key found for this signature in database
GPG key ID: F4ABF488E6029E59
15 changed files with 323 additions and 5 deletions

View file

@ -72,6 +72,8 @@ vntx_net_zone:
ip: 204.110.191.221
- name: net
ip: 104.238.146.79
- name: support
ip: 204.110.191.231
- name: uisp
ip: 204.110.191.224
- name: dns

17
ansible/host_vars/hi.yml Normal file
View file

@ -0,0 +1,17 @@
---
ansible_python_interpreter: /usr/bin/python3
tailscale_skip_connect: true
firewall_allow_rules:
- port: 22
proto: tcp
comment: SSH
- port: 80
proto: tcp
comment: HTTP
- port: 443
proto: tcp
comment: HTTPS
- port: 2222
proto: tcp
comment: Forgejo SSH

View file

@ -0,0 +1,16 @@
---
ansible_host: 204.110.191.231
ansible_python_interpreter: /usr/bin/python3
ansible_ssh_common_args: '-o StrictHostKeyChecking=accept-new'
tailscale_skip_connect: true
firewall_allow_rules:
- port: 22
proto: tcp
comment: SSH
- port: 80
proto: tcp
comment: HTTP
- port: 443
proto: tcp
comment: HTTPS

View file

@ -8,6 +8,7 @@ unimus.vntx.net
monitor.vntx.net
librenms.vntx.net
uisp.vntx.net
support.vntx.net ansible_host=204.110.191.231
[librenms_servers]
librenms.vntx.net
@ -18,6 +19,7 @@ monitor.vntx.net
[home_servers]
skippy.w5isp.com
mail.mcintire.me ansible_host=107.174.178.20
hi ansible_host=74.50.113.232
dokku.w5isp.com
aprs.w5isp.com
prom.w5isp.com ansible_host=10.0.19.31
@ -28,8 +30,15 @@ prom.w5isp.com
[node_exporter_servers:children]
prometheus_servers
[tailscale_servers]
hi
support.vntx.net
[dokku_servers]
[forgejo_servers]
hi
[aprsc_servers]
aprs.w5isp.com
@ -38,6 +47,7 @@ skippy.w5isp.com
netbox.vntx.net
uisp.vntx.net
logs.vntx.net
hi
[netbox_servers]
netbox.vntx.net

View file

@ -15,6 +15,15 @@
community.general.timezone:
name: "{{ timezone }}"
- name: Install and configure Tailscale
hosts: tailscale_servers
become: true
gather_facts: true
tags:
- tailscale
roles:
- tailscale
- name: Apply firewall configuration
hosts: all:!proxmox_servers:!irc_limited
become: true
@ -355,6 +364,15 @@
roles:
- dokku
- name: Install and configure Forgejo
hosts: forgejo_servers
become: true
gather_facts: true
tags:
- forgejo
roles:
- forgejo
- name: Configure node_exporter targets
hosts: node_exporter_servers
become: true

View file

@ -45,6 +45,7 @@ base_common_packages:
base_packages_by_os_family:
Debian:
- sudo
- curl
- jq
- sysstat
- smartmontools

View file

@ -0,0 +1,17 @@
{
servers {
protocols h1 h2
}
admin off
persist_config off
}
git.mcintire.me {
reverse_proxy http://127.0.0.1:3000
encode gzip
log {
output file /var/log/caddy/git.mcintire.me.log
format json
}
}

View file

@ -28,6 +28,13 @@
path: /etc/apt/sources.list.d/ppa-linuxfactory-or-kr.list
state: absent
- name: "Add Signed-By to debian.sources mirror entries"
ansible.builtin.replace:
path: /etc/apt/sources.list.d/debian.sources
regexp: '(URIs: mirror\+file://[^\n]+)\n(Suites:[^\n]+)\n(Components:[^\n]+)'
replace: '\1\n\2\n\3\nSigned-By: /usr/share/keyrings/debian-archive-keyring.gpg'
when: ansible_facts['distribution_release'] == 'trixie'
- name: "Install updates"
ansible.builtin.apt:
name: "*"

View file

@ -0,0 +1,9 @@
---
forgejo_version: "10"
forgejo_http_port: 3000
forgejo_ssh_port: 2222
forgejo_hostname: git.mcintire.me
forgejo_data_dir: /opt/forgejo
forgejo_admin_user: graham
forgejo_admin_email: graham@mcintire.me
forgejo_admin_password: "{{ lookup('env', 'FORGEJO_ADMIN_PASSWORD') | default('changeme123', true) }}"

View file

@ -0,0 +1,5 @@
---
- name: restart forgejo
ansible.builtin.command: docker compose restart
args:
chdir: "{{ forgejo_data_dir }}"

View file

@ -0,0 +1,145 @@
---
- name: Install prerequisites
ansible.builtin.apt:
name:
- ca-certificates
- curl
- gnupg
- apt-transport-https
state: present
update_cache: true
- name: Check if Docker is installed
ansible.builtin.command: which docker
register: docker_installed
changed_when: false
failed_when: false
- name: Add Docker GPG key
ansible.builtin.get_url:
url: https://download.docker.com/linux/debian/gpg
dest: /usr/share/keyrings/docker-archive-keyring.asc
mode: '0644'
when: docker_installed.rc != 0
- name: Add Docker repository
ansible.builtin.deb822_repository:
name: docker
types: deb
uris: https://download.docker.com/linux/debian
suites: "{{ ansible_facts['distribution_release'] }}"
components: stable
architectures: "{{ ansible_facts['architecture'] | replace('x86_64', 'amd64') }}"
signed_by: /usr/share/keyrings/docker-archive-keyring.asc
state: present
when: docker_installed.rc != 0
- name: Install Docker packages
ansible.builtin.apt:
name:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-compose-plugin
state: present
update_cache: true
when: docker_installed.rc != 0
- name: Ensure Docker service is started and enabled
ansible.builtin.systemd:
name: docker
state: started
enabled: true
- name: Add ansible user to docker group
ansible.builtin.user:
name: ansible
groups: docker
append: true
- name: Create Forgejo data directory
ansible.builtin.file:
path: "{{ forgejo_data_dir }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Deploy docker-compose.yml
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ forgejo_data_dir }}/docker-compose.yml"
owner: root
group: root
mode: '0644'
- name: Check if Forgejo is running
ansible.builtin.command:
cmd: docker compose ps --services --filter "status=running"
chdir: "{{ forgejo_data_dir }}"
register: forgejo_running
changed_when: false
failed_when: false
- name: Stop and remove stale Forgejo container
ansible.builtin.command:
cmd: docker compose down -v
chdir: "{{ forgejo_data_dir }}"
when: "'forgejo' in forgejo_running.stdout_lines | default([])"
- name: Clean Forgejo data for fresh install
ansible.builtin.file:
path: "{{ forgejo_data_dir }}/data"
state: absent
- name: Recreate Forgejo data directory
ansible.builtin.file:
path: "{{ forgejo_data_dir }}"
state: directory
owner: root
group: root
mode: '0755'
- name: Start Forgejo with INSTALL_LOCK
ansible.builtin.command:
cmd: docker compose up -d
chdir: "{{ forgejo_data_dir }}"
register: forgejo_started
- name: Wait for Forgejo to be ready
ansible.builtin.uri:
url: http://127.0.0.1:3000/
method: GET
status_code: 200
register: web_ready
retries: 30
delay: 2
until: web_ready.status == 200
changed_when: false
- name: Check if admin user exists
ansible.builtin.uri:
url: http://127.0.0.1:3000/api/v1/users/{{ forgejo_admin_user }}
method: GET
status_code: [200, 404]
register: admin_check
changed_when: false
- name: Create admin user via docker exec
ansible.builtin.command:
cmd: >
docker exec -u git -w /data/gitea forgejo forgejo admin user create
--config /data/gitea/conf/app.ini
--username {{ forgejo_admin_user }}
--password {{ forgejo_admin_password }}
--email {{ forgejo_admin_email }}
--admin
when: admin_check.status == 404
no_log: true
- name: Verify admin user exists
ansible.builtin.uri:
url: http://127.0.0.1:3000/api/v1/users/{{ forgejo_admin_user }}
method: GET
status_code: 200
changed_when: false

View file

@ -0,0 +1,34 @@
services:
forgejo:
image: codeberg.org/forgejo/forgejo:{{ forgejo_version }}
container_name: forgejo
restart: unless-stopped
networks:
- forgejo
volumes:
- {{ forgejo_data_dir }}/data:/data
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
ports:
- "127.0.0.1:{{ forgejo_http_port }}:3000"
- "0.0.0.0:{{ forgejo_ssh_port }}:22"
environment:
- USER_UID=1000
- USER_GID=1000
- FORGEJO__server__ROOT_URL=https://{{ forgejo_hostname }}
- FORGEJO__server__SSH_DOMAIN={{ forgejo_hostname }}
- FORGEJO__server__HTTP_PORT={{ forgejo_http_port }}
- FORGEJO__server__SSH_PORT={{ forgejo_ssh_port }}
- FORGEJO__server__DOMAIN={{ forgejo_hostname }}
- FORGEJO__database__DB_TYPE=sqlite3
- FORGEJO__database__PATH=/data/gitea/gitea.db
- FORGEJO__security__INSTALL_LOCK=true
- FORGEJO__service__DISABLE_REGISTRATION=true
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 10s
timeout: 5s
retries: 10
networks:
forgejo:

View file

@ -11,7 +11,7 @@
name: tailscale
types: deb
uris: https://pkgs.tailscale.com/stable/debian
suites: bookworm
suites: "{{ ansible_facts['distribution_release'] }}"
components: main
signed_by: /usr/share/keyrings/tailscale-archive-keyring.gpg
state: present
@ -31,7 +31,10 @@
- name: Connect to Tailscale
ansible.builtin.command: "tailscale up --authkey={{ tailscale_authkey }} {{ tailscale_args | default('') }}"
when: tailscale_status.rc != 0 or 'BackendState":"Running"' not in tailscale_status.stdout
when:
- not (tailscale_skip_connect | default(false))
- tailscale_authkey | length > 0
- tailscale_status.rc != 0 or 'BackendState":"Running"' not in tailscale_status.stdout
register: tailscale_up
changed_when: tailscale_up.rc == 0
@ -39,11 +42,14 @@
ansible.builtin.command: tailscale ip -4
register: tailscale_ip_result
changed_when: false
failed_when: false
- name: Set Tailscale IP fact
ansible.builtin.set_fact:
tailscale_ip: "{{ tailscale_ip_result.stdout | trim }}"
when: tailscale_ip_result.rc == 0
- name: Display Tailscale IP
ansible.builtin.debug:
msg: "Tailscale IP: {{ tailscale_ip }}"
when: tailscale_ip_result.rc == 0

View file

@ -1219,7 +1219,16 @@ resource "cloudflare_dns_record" "mcintire_me_a_git" {
zone_id = cloudflare_zone.mcintire_me.id
type = "A"
name = "git"
content = "172.245.56.83"
content = "74.50.113.232"
proxied = false
ttl = 86400
}
resource "cloudflare_dns_record" "mcintire_me_a_hi" {
zone_id = cloudflare_zone.mcintire_me.id
type = "A"
name = "hi"
content = "74.50.113.232"
proxied = false
ttl = 86400
}
@ -1233,6 +1242,28 @@ resource "cloudflare_dns_record" "mcintire_me_a_vm1" {
ttl = 86400
}
# =============================================================================
# mcintire.me - AAAA records
# =============================================================================
resource "cloudflare_dns_record" "mcintire_me_aaaa_git" {
zone_id = cloudflare_zone.mcintire_me.id
type = "AAAA"
name = "git"
content = "2604:4500:0009:003d:1c00:bfff:fe00:0464"
proxied = false
ttl = 86400
}
resource "cloudflare_dns_record" "mcintire_me_aaaa_hi" {
zone_id = cloudflare_zone.mcintire_me.id
type = "AAAA"
name = "hi"
content = "2604:4500:0009:003d:1c00:bfff:fe00:0464"
proxied = false
ttl = 86400
}
# =============================================================================
# mcintire.me - MX records
# =============================================================================

View file

@ -24,7 +24,7 @@ module "flatcar_resolver1" {
storage_root = "local-lvm"
storage_ignition = "local"
butane_conf = "${path.module}/flatcar-resolver.bu"
butane_snippet_path = "${path.module}"
butane_snippet_path = path.module
network_devices = [
{
@ -57,7 +57,7 @@ module "flatcar_resolver2" {
storage_root = "local-lvm"
storage_ignition = "local"
butane_conf = "${path.module}/flatcar-resolver2.bu"
butane_snippet_path = "${path.module}"
butane_snippet_path = path.module
network_devices = [
{