Compare commits

..

3 Commits

Author SHA1 Message Date
f3c313e610 update bricktracker to 1.3.1
All checks were successful
Podman DDNS Image / build-and-push-ddns (push) Successful in 1m8s
2026-02-16 11:16:09 -05:00
52c6dac263 transition to container_ over podman_ 2026-02-16 10:44:38 -05:00
d4fbbb185f rename podman_ projects to container_ 2026-02-11 11:34:02 -05:00
102 changed files with 1059 additions and 162 deletions

View File

@@ -3,10 +3,10 @@ run-name: Build and Push the Custom Caddy Image with Route53 DNS Certbot
on:
push:
paths:
- active/podman_caddy/**
- active/container_caddy/**
- .gitea/workflows/caddy.yaml
schedule:
- cron: '@daily'
- cron: "@daily"
jobs:
build-and-push-ddns:
runs-on: ubuntu-latest
@@ -23,8 +23,8 @@ jobs:
- name: Build and push Docker image
uses: https://github.com/docker/build-push-action@v5
with:
context: ${{ gitea.workspace }}/active/podman_caddy
file: ${{ gitea.workspace }}/active/podman_caddy/Containerfile
context: ${{ gitea.workspace }}/active/container_caddy
file: ${{ gitea.workspace }}/active/container_caddy/Containerfile
push: true
tags: "gitea.reeseapps.com/services/caddy:latest,gitea.reeseapps.com/services/caddy:${{gitea.sha}}"
no-cache: true

View File

@@ -3,10 +3,10 @@ run-name: Build and Push the Podman DDNS Image
on:
push:
paths:
- active/podman_ddns/**
- active/container_ddns/**
- .gitea/workflows/ddns.yaml
schedule:
- cron: '@daily'
- cron: "@daily"
jobs:
build-and-push-ddns:
runs-on: ubuntu-latest
@@ -23,8 +23,8 @@ jobs:
- name: Build and push Docker image
uses: https://github.com/docker/build-push-action@v5
with:
context: ${{ gitea.workspace }}/active/podman_ddns
file: ${{ gitea.workspace }}/active/podman_ddns/Containerfile
context: ${{ gitea.workspace }}/active/container_ddns
file: ${{ gitea.workspace }}/active/container_ddns/Containerfile
push: true
tags: "gitea.reeseapps.com/services/ddns:latest,gitea.reeseapps.com/services/ddns:${{gitea.sha}}"
no-cache: true

1
.gitignore vendored
View File

@@ -11,3 +11,4 @@ TODO.md
eicar.com
*.pp
*.mod
*.log

View File

@@ -40,6 +40,7 @@ or give me access to your servers.
- ["find ." shortcuts](#find--shortcuts)
- [tmux](#tmux)
- [bash](#bash)
- [Bulk File/Folder Renaming](#bulk-filefolder-renaming)
- [SSH Setup](#ssh-setup)
- [Git GPG Commit Signing](#git-gpg-commit-signing)
- [Important Dates and Times](#important-dates-and-times)
@@ -91,15 +92,15 @@ find . -type d -exec chmod 755 {} \;
Here are some handy references for default bash variables
```text
$0 The name of the script being executed.
$1-$9 The first nine command-line arguments.
$# The number of command-line arguments.
$* All command-line arguments as a single string.
$@ All command-line arguments as an array.
$? The exit status of the last executed command.
$$ The process ID of the current shell.
$! The process ID of the last background command.
$- Shows the current shell options or flags.
`$0` The name of the script being executed.
`$1-$9` The first nine command-line arguments.
`$#` The number of command-line arguments.
`$*` All command-line arguments as a single string.
`$@` All command-line arguments as an array.
`$?` The exit status of the last executed command.
`$$` The process ID of the current shell.
`$!` The process ID of the last background command.
`$-` Shows the current shell options or flags.
```
And here are the meanings of the shell options
@@ -118,6 +119,15 @@ So to check if you are in an interactive shell:
[ $- == *i* ]] && Some command here
```
### Bulk File/Folder Renaming
```bash
for change_dir in $(ls | grep 'podman_*'); do
new_name=$(echo $change_dir | sed 's/podman_/container_/g')
mv $change_dir $new_name`;
done
```
## SSH Setup
Generate a key (password protect it!)
@@ -197,16 +207,15 @@ signed you'll see an output. If not, nothing will show.
## Important Dates and Times
| Time | Day | Description |
| ----- | -------- | ---------------------------------- |
| 00:00 | All | Automated builds |
| 00:00 | All | NAS Snapshots |
| 02:00 | All | Backups |
| 04:00 | All | Bare Metal Server Security Updates |
| 05:00 | All | VM Server Security Updates |
| 05:00 | All | Unifi Protect Firmware Updates |
| 06:00 | All | Unifi Network Firmware Updates |
| 06:00 | Saturday | Truenas Disk Scrub |
| Time | Day | Description |
| ----- | --- | ---------------------------------- |
| 00:00 | All | Automated builds |
| 00:00 | All | NAS Snapshots |
| 02:00 | All | Backups |
| 04:00 | All | Bare Metal Server Security Updates |
| 05:00 | All | VM Server Security Updates |
| 05:00 | All | Unifi Protect Firmware Updates |
| 06:00 | All | Unifi Network Firmware Updates |
## Project Lifecycle
@@ -296,7 +305,7 @@ Assuming your project name is `my-project` and it runs on `podman`
1. Create a new directory called `podman_my-project` under the `active`
directory
2. Copy the readme template: `cp project_readme_template.md
active/podman_my-project/my-project.md`
active/container_my-project/my-project.md`
3. Populate `my-project.md` as you work through the install process
4. Create a directory called `secrets` in `podman_my-project`. This will be
automatically gitignored. Put all secrets here.

View File

@@ -2,6 +2,14 @@
<https://gitea.baerentsen.space/FrederikBaerentsen/BrickTracker/src/branch/master/docs/quickstart.md>
## Update
```bash
scp active/container_bricktracker/connorbricktracker-compose.yaml bricktracker:
ssh bricktracker
docker compose -f connorbricktracker-compose.yaml up -d
```
## Setup
### Create the bricktracker user
@@ -34,7 +42,7 @@ mkdir -p /home/bricktracker/.config/containers/systemd
bricktracker:
container_name: BrickTracker
restart: unless-stopped
image: gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.2.2
image: gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.3.1
ports:
- "3333:3333"
volumes:

View File

@@ -2,7 +2,7 @@ services:
bricktracker:
container_name: BrickTracker
restart: unless-stopped
image: gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.2.2
image: gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.3.1
ports:
- "3333:3333"
volumes:

View File

@@ -62,15 +62,15 @@ Now you can install the Caddy service with something like:
# Base Proxy
ansible-playbook \
-i ansible/inventory.yaml \
active/podman_caddy/install_caddy_proxy.yaml
active/container_caddy/install_caddy_proxy.yaml
# Deskwork (AI) Proxy
ansible-playbook \
-i ansible/inventory.yaml \
active/podman_caddy/install_caddy_deskwork.yaml
active/container_caddy/install_caddy_deskwork.yaml
```
See ansible playbook [install_caddy.yaml](/active/podman_caddy/install_caddy.yaml)
See ansible playbook [install_caddy.yaml](/active/container_caddy/install_caddy.yaml)
### Manual
@@ -135,6 +135,6 @@ Before you can create a Caddyfile you need records that point to your server.
You can either create them manually in your DNS provider of choice or use the provided
ddns service:
1. Update the [ddns caddy records](/active/podman_ddns/secrets/caddy_records.yaml)
2. (Optional) Update the Caddyfile at `active/podman_caddy/secrets/Caddyfile`
3. Run the [caddy ansible playbook](/active/podman_caddy/caddy.md#install-caddy)
1. Update the [ddns caddy records](/active/container_ddns/secrets/caddy_records.yaml)
2. (Optional) Update the Caddyfile at `active/container_caddy/secrets/Caddyfile`
3. Run the [caddy ansible playbook](/active/container_caddy/caddy.md#install-caddy)

View File

@@ -20,7 +20,7 @@
## Setup certbot Project
- [ ] Copy and rename this folder to active/podman_certbot
- [ ] Copy and rename this folder to active/container_certbot
- [ ] Find and replace certbot with the name of the service.
- [ ] Create the rootless user to run the podman containers
- [ ] Write the compose.yaml spec for your service
@@ -65,8 +65,8 @@ Run the following to convert a compose.yaml into the various `.container` files
podman run \
--security-opt label=disable \
--rm \
-v $(pwd)/active/podman_certbot/:/compose \
-v $(pwd)/active/podman_certbot/quadlets:/quadlets \
-v $(pwd)/active/container_certbot/:/compose \
-v $(pwd)/active/container_certbot/quadlets:/quadlets \
quay.io/k9withabone/podlet \
-f /quadlets \
-i \
@@ -75,7 +75,7 @@ compose /compose/compose.yaml
# Copy the files to the server
export PODMAN_SERVER=
scp -r active/podman_certbot/quadlets/. $PODMAN_SERVER:/home/certbot/.config/containers/systemd/
scp -r active/container_certbot/quadlets/. $PODMAN_SERVER:/home/certbot/.config/containers/systemd/
ssh $PODMAN_SERVER chown -R certbot:certbot /home/certbot/.config/containers/systemd/
```
@@ -107,8 +107,8 @@ systemctl --user enable --now podman-auto-update.timer
### Expose certbot
1. If you need a domain, follow the [DDNS instructions](/active/podman_ddns/ddns.md#install-a-new-ddns-service)
2. For a web service, follow the [Caddy instructions](/active/podman_caddy/caddy.md#adding-a-new-caddy-record)
1. If you need a domain, follow the [DDNS instructions](/active/container_ddns/ddns.md#install-a-new-ddns-service)
2. For a web service, follow the [Caddy instructions](/active/container_caddy/caddy.md#adding-a-new-caddy-record)
3. Finally, follow your OS's guide for opening ports via its firewall service.
#### firewalld

View File

@@ -0,0 +1 @@
3.13

View File

@@ -59,7 +59,7 @@ Now you can install the DDNS service with something like:
ansible-playbook \
-i ansible/inventory.yaml \
-l proxy \
active/podman_ddns/install_ddns.yaml
active/container_ddns/install_ddns.yaml
```
See ansible playbook [install_ddns.yaml](/install_ddns.yaml)
@@ -75,8 +75,8 @@ multiple servers. If you have a podman server, it'll have its own
ansible-playbook \
-i ansible/inventory.yaml \
-l caddy \
active/podman_ddns/install_ddns.yaml \
-e "@active/podman_ddns/secrets/records.yaml"
active/container_ddns/install_ddns.yaml \
-e "@active/container_ddns/secrets/records.yaml"
```
## Development

View File

@@ -25,7 +25,7 @@ Prereqs
2. Create a gitea user and update gitea-compose.yaml with the correct UID
```bash
scp active/podman_gitea/gitea-compose.yaml gitea:
scp active/container_gitea/gitea-compose.yaml gitea:
docker compose -f gitea-compose.yaml up -d
```
@@ -72,22 +72,22 @@ exit
```bash
# Run this in Homelab, not on the server.
mkdir $(pwd)/active/podman_gitea/quadlets
mkdir $(pwd)/active/container_gitea/quadlets
# Generate the systemd service
podman run \
--network none \
--rm \
-v $(pwd)/active/podman_gitea/compose:$(pwd)/active/podman_gitea/compose:z \
-v $(pwd)/active/podman_gitea/quadlets:$(pwd)/active/podman_gitea/quadlets:z \
-v $(pwd)/active/container_gitea/compose:$(pwd)/active/container_gitea/compose:z \
-v $(pwd)/active/container_gitea/quadlets:$(pwd)/active/container_gitea/quadlets:z \
quay.io/k9withabone/podlet \
-f $(pwd)/active/podman_gitea/quadlets \
-f $(pwd)/active/container_gitea/quadlets \
-i \
--overwrite \
compose $(pwd)/active/podman_gitea/compose/compose.yaml
compose $(pwd)/active/container_gitea/compose/compose.yaml
# Copy the files to the server
scp -r $(pwd)/active/podman_gitea/quadlets/. 3dserver:/home/gitea/.config/containers/systemd/
scp -r $(pwd)/active/container_gitea/quadlets/. 3dserver:/home/gitea/.config/containers/systemd/
```
### Install Quadlets
@@ -127,7 +127,7 @@ systemctl --user enable --now podman-auto-update.timer
```bash
# Upload quadlets and restart
export PODMAN_SERVER=3dserver
scp -r active/podman_gitea/quadlets/. $PODMAN_SERVER:/home/gitea/.config/containers/systemd/
scp -r active/container_gitea/quadlets/. $PODMAN_SERVER:/home/gitea/.config/containers/systemd/
ssh $PODMAN_SERVER chown -R gitea:gitea /home/gitea/.config/containers/systemd/
ssh $PODMAN_SERVER

View File

@@ -13,14 +13,14 @@ podman run \
--name=grafana \
--volume grafana-storage:/var/lib/grafana \
--network=systemd-graphite \
grafana/grafana-enterprise > active/podman_grafana/grafana.container
grafana/grafana-enterprise > active/container_grafana/grafana.container
```
Copy the graphite.container and graphite.network file to the server you want to run it on
```bash
export PODMAN_SERVER=
scp active/podman_grafana/grafana.container $PODMAN_SERVER:/etc/containers/systemd/
scp active/container_grafana/grafana.container $PODMAN_SERVER:/etc/containers/systemd/
ssh $PODMAN_SERVER systemctl daemon-reload
ssh $PODMAN_SERVER systemctl enable --now grafana.service

View File

@@ -7,7 +7,7 @@
```bash
# Generate the network
podman run ghcr.io/containers/podlet --description Graphite \
podman network create --ipv6 graphite > active/podman_graphite/graphite.network
podman network create --ipv6 graphite > active/container_graphite/graphite.network
# Generate the systemd container service
podman run ghcr.io/containers/podlet --description Graphite \
@@ -23,15 +23,15 @@ podman run \
-v graphite_configs:/opt/graphite/conf \
-v graphite_data:/opt/graphite/storage \
-v graphite_statsd_config:/opt/statsd/config \
ghcr.io/deniszh/graphite-statsd > active/podman_graphite/graphite.container
ghcr.io/deniszh/graphite-statsd > active/container_graphite/graphite.container
```
Copy the graphite.container and graphite.network file to the server you want to run it on
```bash
export PODMAN_SERVER=
scp active/podman_graphite/graphite.network $PODMAN_SERVER:/etc/containers/systemd/
scp active/podman_graphite/graphite.container $PODMAN_SERVER:/etc/containers/systemd/
scp active/container_graphite/graphite.network $PODMAN_SERVER:/etc/containers/systemd/
scp active/container_graphite/graphite.container $PODMAN_SERVER:/etc/containers/systemd/
ssh $PODMAN_SERVER systemctl daemon-reload
ssh $PODMAN_SERVER systemctl start graphite.network

View File

@@ -22,7 +22,7 @@
## Setup immich Project
- [x] Copy and rename this folder to active/podman_immich
- [x] Copy and rename this folder to active/container_immich
- [x] Find and replace immich with the name of the service.
- [x] Create the rootless user to run the podman containers
- [ ] Write the compose.yaml spec for your service
@@ -36,8 +36,8 @@
<https://docs.immich.app/install/docker-compose/>
```bash
scp active/podman_immich/release-compose.yaml immich:
scp active/podman_immich/release-env immich:.env
scp active/container_immich/release-compose.yaml immich:
scp active/container_immich/release-env immich:.env
mkdir /srv/immich
docker compose -f release-compose.yaml up -d
@@ -62,10 +62,10 @@ mkdir -p /home/immich/.config/containers/systemd
```bash
# Pull the compose file
wget -O active/podman_immich/release-compose.yaml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -O active/container_immich/release-compose.yaml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
# Pull the .env file
wget -O active/podman_immich/release-env https://github.com/immich-app/immich/releases/latest/download/example.env
wget -O active/container_immich/release-env https://github.com/immich-app/immich/releases/latest/download/example.env
```
2. Edit the compose.yaml. Replace all environment variables with their correct values.
@@ -84,8 +84,8 @@ Run the following to convert a compose.yaml into the various `.container` files
podman run \
--security-opt label=disable \
--rm \
-v $(pwd)/active/podman_immich/compose:/compose \
-v $(pwd)/active/podman_immich/quadlets:/quadlets \
-v $(pwd)/active/container_immich/compose:/compose \
-v $(pwd)/active/container_immich/quadlets:/quadlets \
quay.io/k9withabone/podlet \
-f /quadlets \
-i \
@@ -94,7 +94,7 @@ compose /compose/compose.yaml
# Copy the files to the server
export PODMAN_SERVER=3dserver
scp -r active/podman_immich/quadlets/. $PODMAN_SERVER:/home/immich/.config/containers/systemd/
scp -r active/container_immich/quadlets/. $PODMAN_SERVER:/home/immich/.config/containers/systemd/
ssh $PODMAN_SERVER chown -R immich:immich /home/immich/.config/containers/systemd/
```
@@ -122,8 +122,8 @@ systemctl --user enable --now podman-auto-update.timer
### Expose immich
1. If you need a domain, follow the [DDNS instructions](/active/podman_ddns/ddns.md#install-a-new-ddns-service)
2. For a web service, follow the [Caddy instructions](/active/podman_caddy/caddy.md#adding-a-new-caddy-record)
1. If you need a domain, follow the [DDNS instructions](/active/container_ddns/ddns.md#install-a-new-ddns-service)
2. For a web service, follow the [Caddy instructions](/active/container_caddy/caddy.md#adding-a-new-caddy-record)
3. Finally, follow your OS's guide for opening ports via its firewall service.
#### firewalld

View File

@@ -32,7 +32,7 @@ They have podman rootless instructions!
```bash
export PODMAN_SERVER=3dserver
scp -r active/podman_jellyfin/quadlets/. $PODMAN_SERVER:/home/jellyfin/.config/containers/systemd/
scp -r active/container_jellyfin/quadlets/. $PODMAN_SERVER:/home/jellyfin/.config/containers/systemd/
ssh $PODMAN_SERVER chown -R jellyfin:jellyfin /home/jellyfin/.config/containers/systemd/
ssh $PODMAN_SERVER
@@ -50,7 +50,7 @@ They have podman rootless instructions!
```bash
# Upload quadlets and restart
export PODMAN_SERVER=3dserver
scp -r active/podman_jellyfin/quadlets/. $PODMAN_SERVER:/home/jellyfin/.config/containers/systemd/
scp -r active/container_jellyfin/quadlets/. $PODMAN_SERVER:/home/jellyfin/.config/containers/systemd/
ssh $PODMAN_SERVER chown -R jellyfin:jellyfin /home/jellyfin/.config/containers/systemd/
ssh $PODMAN_SERVER

View File

@@ -21,7 +21,7 @@
## Setup keycloak Project
- [ ] Copy and rename this folder to active/podman_keycloak
- [ ] Copy and rename this folder to active/container_keycloak
- [ ] Find and replace keycloak with the name of the service.
- [ ] Create the rootless user to run the podman containers
- [ ] Write the compose.yaml spec for your service
@@ -78,8 +78,8 @@ Run the following to convert a compose.yaml into the various `.container` files
podman run \
--security-opt label=disable \
--rm \
-v $(pwd)/active/podman_keycloak/:/compose \
-v $(pwd)/active/podman_keycloak/quadlets:/quadlets \
-v $(pwd)/active/container_keycloak/:/compose \
-v $(pwd)/active/container_keycloak/quadlets:/quadlets \
quay.io/k9withabone/podlet \
-f /quadlets \
-i \
@@ -88,7 +88,7 @@ compose /compose/compose.yaml
# Copy the files to the server
export PODMAN_SERVER=
scp -r active/podman_keycloak/quadlets/. $PODMAN_SERVER:/home/keycloak/.config/containers/systemd/
scp -r active/container_keycloak/quadlets/. $PODMAN_SERVER:/home/keycloak/.config/containers/systemd/
ssh $PODMAN_SERVER chown -R keycloak:keycloak /home/keycloak/.config/containers/systemd/
```
@@ -120,8 +120,8 @@ systemctl --user enable --now podman-auto-update.timer
### Expose keycloak
1. If you need a domain, follow the [DDNS instructions](/active/podman_ddns/ddns.md#install-a-new-ddns-service)
2. For a web service, follow the [Caddy instructions](/active/podman_caddy/caddy.md#adding-a-new-caddy-record)
1. If you need a domain, follow the [DDNS instructions](/active/container_ddns/ddns.md#install-a-new-ddns-service)
2. For a web service, follow the [Caddy instructions](/active/container_caddy/caddy.md#adding-a-new-caddy-record)
3. Finally, follow your OS's guide for opening ports via its firewall service.
#### firewalld

View File

@@ -18,7 +18,7 @@
## Setup matrix Project
- [x] Copy and rename this folder to active/podman_matrix
- [x] Copy and rename this folder to active/container_matrix
- [x] Find and replace matrix with the name of the service.
- [x] Create the rootless user to run the podman containers
- [x] Write the compose.yaml spec for your service
@@ -57,8 +57,8 @@ On your local machine:
podman run \
--security-opt label=disable \
--rm \
-v $(pwd)/active/podman_matrix/compose:/compose \
-v $(pwd)/active/podman_matrix/quadlets:/quadlets \
-v $(pwd)/active/container_matrix/compose:/compose \
-v $(pwd)/active/container_matrix/quadlets:/quadlets \
quay.io/k9withabone/podlet \
-f /quadlets \
-i \
@@ -66,10 +66,10 @@ quay.io/k9withabone/podlet \
compose /compose/compose.yaml
# Copy the files to the server
scp -r active/podman_matrix/quadlets/. matrix:~/.config/containers/systemd/
scp -r active/container_matrix/quadlets/. matrix:~/.config/containers/systemd/
# Copy the compose files to the server
scp -r active/podman_matrix/compose/. matrix:~/.config//
scp -r active/container_matrix/compose/. matrix:~/.config//
```
```bash
@@ -96,8 +96,8 @@ ghcr.io/matrix-construct/tuwunel:latest \
### Expose matrix
1. If you need a domain, follow the [DDNS instructions](/active/podman_ddns/ddns.md#install-a-new-ddns-service)
2. For a web service, follow the [Caddy instructions](/active/podman_caddy/caddy.md#adding-a-new-caddy-record)
1. If you need a domain, follow the [DDNS instructions](/active/container_ddns/ddns.md#install-a-new-ddns-service)
2. For a web service, follow the [Caddy instructions](/active/container_caddy/caddy.md#adding-a-new-caddy-record)
3. Finally, follow your OS's guide for opening ports via its firewall service.
#### firewalld

View File

@@ -34,8 +34,8 @@ podman run \
--security-opt label=disable \
--userns keep-id \
--rm \
-v $(pwd)/active/podman_minecraft:/compose \
-v $(pwd)/active/podman_minecraft/quadlets:/quadlets \
-v $(pwd)/active/container_minecraft:/compose \
-v $(pwd)/active/container_minecraft/quadlets:/quadlets \
quay.io/k9withabone/podlet \
-f /quadlets \
-i \
@@ -43,7 +43,7 @@ quay.io/k9withabone/podlet \
compose /compose/compose.yaml
# Copy the files to the server
scp -r active/podman_minecraft/quadlets/. minecraft:~/.config/containers/systemd/
scp -r active/container_minecraft/quadlets/. minecraft:~/.config/containers/systemd/
```
### Install Quadlets
@@ -78,10 +78,10 @@ ssh minecraft systemctl --user restart minecraft
## Expose minecraft
1. Create your minecraft ddns record first [following these docs](/active/podman_ddns/ddns.md#)
1. Create your minecraft ddns record first [following these docs](/active/container_ddns/ddns.md#)
2. Create a SRV record in your DNS provider like the following:
active/podman_minecraft/secrets/reeseapps_records.json:
active/container_minecraft/secrets/reeseapps_records.json:
```json
{
@@ -105,7 +105,7 @@ ssh minecraft systemctl --user restart minecraft
```
```bash
aws route53 change-resource-record-sets --hosted-zone-id $(cat active/aws_route53/secrets/reeseapps-zoneid) --change-batch file://active/podman_minecraft/secrets/reeseapps_records.json
aws route53 change-resource-record-sets --hosted-zone-id $(cat active/aws_route53/secrets/reeseapps-zoneid) --change-batch file://active/container_minecraft/secrets/reeseapps_records.json
```
3. Test your record with `nslookup`

View File

@@ -36,7 +36,7 @@
1. Create Fedora VM
2. [Install Docker](https://docs.docker.com/engine/install/fedora/)
3. Create and mount a directory at `/srv/nextcloud-data`
4. `scp active/podman_nextcloud/nextcloud-compose.yaml nextcloud:`
4. `scp active/container_nextcloud/nextcloud-compose.yaml nextcloud:`
5. `docker compose -f nextcloud-compose.yaml up -d`
## Install with Rootless Podman
@@ -87,7 +87,7 @@ On the operator
```bash
# Copy the quadlet files
scp \
active/podman_nextcloud/nextcloud-aio-mastercontainer.container \
active/container_nextcloud/nextcloud-aio-mastercontainer.container \
3dserver:/home/nextcloud/.config/containers/systemd/
ssh chown -R nextcloud:nextcloud /home/nextcloud/.config/containers/systemd/

View File

@@ -24,7 +24,12 @@ stream {
listen 2222;
listen [::]:2222;
proxy_pass gitea.reeselink.com:2222;
}
server {
listen 8080;
listen [::]:8080;
proxy_pass unifi-external.reeselink.com:2222;
}
server {

View File

@@ -1,13 +1,9 @@
# Ngnix
## TCP Stream Proxy
## Initial Install
```bash
# Get the initial configuration
scp active/podman_nginx/nginx.conf proxy:/etc/nginx/nginx.conf
```
```bash
vim /etc/containers/systemd/nginx.container
```
@@ -30,7 +26,11 @@ Restart=always
WantedBy=default.target
```
## Update the Configuration
```bash
scp active/container_nginx/nginx.conf proxy:/etc/nginx/nginx.conf
ssh proxy
systemctl daemon-reload
systemctl start nginx
```

View File

@@ -39,10 +39,10 @@ systemctl enable --now btrfs-monitor.timer
```bash
# Update Caddy
ansible-playbook -i ansible/inventory.yaml -l proxy active/podman_caddy/install_caddy.yaml
ansible-playbook -i ansible/inventory.yaml -l proxy active/container_caddy/install_caddy.yaml
# Update DDNS
ansible-playbook -i ansible/inventory.yaml -l proxy active/podman_ddns/install_ddns.yaml
ansible-playbook -i ansible/inventory.yaml -l proxy active/container_ddns/install_ddns.yaml
```
## Disk Mounts
@@ -98,7 +98,7 @@ composer-cli compose image \
# Convert the build to raw
qemu-img convert -f qcow2 -O raw \
/srv/smb/pool0/ducoterra/images/builds/fedora-43-base.qcow2 \
/srv/vm/pool1/fedora-43-base.raw
/srv/vm/pool1/fedora-boot.raw
# Install (Change password for default user ducoterra!)
virt-install \
@@ -110,7 +110,7 @@ virt-install \
--network bridge:bridge0 \
--graphics none \
--console pty,target.type=virtio \
--import --disk "path=/srv/vm/pool1/gitlab.raw,bus=virtio"
--import --disk "path=/srv/vm/pool1/fedora-boot.raw,bus=virtio"
# convert a cloud-init image to raw
qemu-img convert -f qcow2 -O raw \

View File

@@ -35,7 +35,7 @@
- [VLLM](#vllm)
- [Install the whole thing with quadlets (TM)](#install-the-whole-thing-with-quadlets-tm)
- [Install the update script](#install-the-update-script)
- [Voice Cloning](#voice-cloning)
- [Install Guest Open Webui with Start/Stop Services](#install-guest-open-webui-with-startstop-services)
## BIOS
@@ -208,7 +208,7 @@ hf download --local-dir /home/ai/models/text/qwen3-coder-30b-a3b-instruct ggml-o
# qwen3-coder-next
mkdir /home/ai/models/text/qwen3-coder-next
hf download --local-dir /home/ai/models/text/qwen3-coder-next --include "unsloth/Qwen3-Coder-Next-GGUF Q5_K_M/*.gguf"
hf download --local-dir /home/ai/models/text/qwen3-coder-next unsloth/Qwen3-Coder-Next-GGUF --include " 5_K_M/*.gguf"
# qwen3-vl-30b-thinking
mkdir /home/ai/models/text/qwen3-vl-30b-thinking
@@ -223,6 +223,10 @@ hf download --local-dir /home/ai/models/text/qwen3-vl-8b-instruct Qwen/Qwen3-VL-
# qwen3-4b-2507-abliterated
mkdir /home/ai/models/text/qwen3-4b-2507-abliterated
hf download --local-dir /home/ai/models/text/qwen3-4b-2507-abliterated prithivMLmods/Qwen3-4B-2507-abliterated-GGUF Qwen3-4B-Thinking-2507-abliterated-GGUF/Qwen3-4B-Thinking-2507-abliterated.Q4_K_M.gguf
# qwen3-48b-a4b-abliterated
mkdir /home/ai/models/text/qwen3-48b-a4b-abliterated
hf download --local-dir /home/ai/models/text/qwen3-48b-a4b-abliterated DavidAU/Qwen3-48B-A4B-Savant-Commander-Distill-12X-Closed-Open-Heretic-Uncensored-GGUF Qwen3-48B-A4B-Savant-Commander-Dstll-12X-Cl-Op-Hrtic-Uncen-Q4_K_M.gguf
```
##### GLM
@@ -231,6 +235,16 @@ hf download --local-dir /home/ai/models/text/qwen3-4b-2507-abliterated prithivML
# glm-4.7-flash-30b
mkdir /home/ai/models/text/glm-4.7-flash-30b
hf download --local-dir /home/ai/models/text/glm-4.7-flash-30b unsloth/GLM-4.7-Flash-GGUF GLM-4.7-Flash-Q4_K_M.gguf
# glm-4.6v
mkdir /home/ai/models/text/glm-4.6v
hf download --local-dir /home/ai/models/text/glm-4.6v unsloth/GLM-4.6V-GGUF --include "Q4_K_M/*.gguf"
hf download --local-dir /home/ai/models/text/glm-4.6v unsloth/GLM-4.6V-GGUF mmproj-F16.gguf
# glm-4.6v-flash
mkdir /home/ai/models/text/glm-4.6v-flash
hf download --local-dir /home/ai/models/text/glm-4.6v-flash unsloth/GLM-4.6V-Flash-GGUF GLM-4.6V-Flash-Q4_K_M.gguf
hf download --local-dir /home/ai/models/text/glm-4.6v-flash unsloth/GLM-4.6V-Flash-GGUF mmproj-F16.gguf
```
##### Llama
@@ -556,4 +570,12 @@ chmod +x update-script.sh
./update-script.sh
```
## Voice Cloning
## Install Guest Open Webui with Start/Stop Services
```bash
scp -r active/device_framework_desktop/systemd/. deskwork-ai:.config/systemd/user/
ssh deskwork-ai
systemctl --user daemon-reload
systemctl --user enable open-webui-guest-start.timer
systemctl --user enable open-webui-guest-stop.timer
```

View File

@@ -24,11 +24,14 @@ Exec=-l 0.0.0.0 \
--diffusion-model /models/image/flux2-klein/flux-2-klein-9b-Q4_0.gguf \
--vae /models/image/flux2-klein/ae.safetensors \
--llm /models/image/flux2-klein/Qwen3-8B-Q4_K_M.gguf \
-v \
--cfg-scale 1.0 \
--sampling-method euler \
-v \
--steps 4 \
--vae-conv-direct
--vae-conv-direct \
--offload-to-cpu \
--diffusion-conv-direct \
--seed -1 \
--steps 5
[Service]
Restart=always

View File

@@ -24,9 +24,9 @@ Exec=-l 0.0.0.0 \
--diffusion-model /models/image/z-turbo/z_image_turbo-Q4_K.gguf \
--vae /models/image/z-turbo/ae.safetensors \
--llm /models/image/z-turbo/qwen_3_4b.safetensors \
-v \
--cfg-scale 1.0 \
--vae-conv-direct \
-v \
--seed -1 \
--steps 8

View File

@@ -0,0 +1,32 @@
[Unit]
Description=An Open Webui Frontend for Local AI Services for Guests
[Container]
# Shared AI external pod
Pod=ai-external.pod
# Open Webui base image
Image=ghcr.io/open-webui/open-webui:main
# Nothing too complicated here. Open Webui will basically configure itself.
Volume=open-webui-data-guest:/app/backend/data
# WEBUI_SECRET_KEY is required to prevent logout on Restart
EnvironmentFile=/home/ai/.env/open-webui-env-guest
# ai-external is the primary network
Network=ai-external.network
Network=ai-internal.network
# open-webui
PublishPort=8081:8081/tcp
[Service]
Restart=on-failure
RestartSec=5
# Extend Timeout to allow time to pull the image
TimeoutStartSec=900
[Install]
# Start by default on boot
WantedBy=multi-user.target default.target

View File

@@ -1,42 +0,0 @@
[Unit]
Description=A Stable Diffusion CPP Server for Editing Images
[Container]
# Shared AI pod
Pod=ai.pod
# Vulkan image for AMD GPU
Image=localhost/stable-diffusion-cpp:latest
# Shared models directory
Volume=/home/ai/models:/models:z
# GPU Device
AddDevice=/dev/kfd
AddDevice=/dev/dri
# Override entrypoint to use server
Entrypoint=/sd-server
# Server args
Exec=-l 0.0.0.0 \
--listen-port 1235 \
--diffusion-model /models/image/flux-1-kontext/flux1-kontext-dev-Q4_K_M.gguf \
--vae /models/image/flux-1-kontext/ae.safetensors \
--clip_l /models/image/flux-1-kontext/clip_l.safetensors \
--t5xxl /models/image/flux-1-kontext/t5xxl_fp16.safetensors \
--cfg-scale 1.0 \
--sampling-method euler \
--vae-conv-direct \
--seed -1 \
--steps 28 \
-v
[Service]
Restart=always
# Extend Timeout to allow time to pull the image
TimeoutStartSec=900
[Install]
# Start by default on boot
WantedBy=multi-user.target default.target

View File

@@ -0,0 +1,8 @@
[Unit]
Description=Start open-webui-guest on schedule
Wants=open-webui-guest.service
After=open-webui-guest.service
[Service]
Type=oneshot
ExecStart=/bin/systemctl --user start open-webui-guest.service

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Timer to start open-webui-guest at 08:00 MonFri
[Timer]
OnCalendar=Mon..Fri *-*-* 08:00:00
Persistent=true
Unit=open-webui-guest-start.service
[Install]
WantedBy=timers.target

View File

@@ -0,0 +1,7 @@
[Unit]
Description=Stop open-webui-guest on schedule
After=open-webui-guest.service
[Service]
Type=oneshot
ExecStart=/bin/systemctl --user stop open-webui-guest.service

View File

@@ -0,0 +1,10 @@
[Unit]
Description=Timer to stop open-webui-guest at 18:00 MonFri
[Timer]
OnCalendar=Mon..Fri *-*-* 18:00:00
Persistent=true
Unit=open-webui-guest-stop.service
[Install]
WantedBy=timers.target

View File

@@ -5,10 +5,15 @@ fedora:
jellyfin:
nextcloud:
proxy:
backup:
bricktracker:
minecraft:
borg-root:
elk:
hardware:
hosts:
deskwork-root:
driveripper:
caddy:
hosts:

View File

@@ -0,0 +1 @@
3.13

View File

@@ -0,0 +1,9 @@
# Update
Updates every server in the fleet
## Usage
```bash
uv run automations/updates/main.py
```

View File

@@ -0,0 +1,57 @@
import subprocess
import time
import yaml
from tqdm import tqdm
def main():
print("Retrieving hosts")
with open("ansible/inventory.yaml", "r") as f:
all_hosts = yaml.load(f, yaml.SafeLoader)
fedora_hosts = all_hosts["fedora"]["hosts"].keys()
with open("update.log", "w") as log_file:
for _, host in enumerate(tqdm(fedora_hosts, desc="Running system updates")):
log_file.write(f"Updating {host}\n")
log_file.flush()
subprocess.run(
["ssh", host, "dnf", "upgrade", "-y"],
stdout=log_file,
stderr=log_file,
check=True,
)
log_file.write(f"Rebooting {host}\n")
log_file.flush()
subprocess.run(
["ssh", host, "reboot"],
stdout=log_file,
stderr=log_file,
check=True,
)
time.sleep(5) # wait for reboot to take effect
booted = False
max_attempts = 5 # seconds
cur_attempts = 0 # seconds
while cur_attempts > max_attempts or not booted:
try:
subprocess.run(
["ssh", host, "echo"],
stdout=log_file,
stderr=log_file,
check=True,
timeout=2,
)
booted = True
except Exception as e:
cur_attempts += 1
log_file.write(f"Waiting for {host} to reboot\n")
log_file.flush()
time.sleep(5)
if cur_attempts >= max_attempts:
exit(1)
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,12 @@
[project]
name = "updates"
version = "0.1.0"
description = "Update servers based on ansible inventory"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"pyyaml>=6.0.3",
"tqdm>=4.67.3",
"types-pyyaml>=6.0.12.20250915",
"types-tqdm>=4.67.3.20260205",
]

121
automations/updates/uv.lock generated Normal file
View File

@@ -0,0 +1,121 @@
version = 1
revision = 3
requires-python = ">=3.13"
[[package]]
name = "colorama"
version = "0.4.6"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" },
]
[[package]]
name = "pyyaml"
version = "6.0.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" },
{ url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" },
{ url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" },
{ url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" },
{ url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" },
{ url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" },
{ url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" },
{ url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" },
{ url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" },
{ url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" },
{ url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" },
{ url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" },
{ url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" },
{ url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" },
{ url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" },
{ url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" },
{ url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" },
{ url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" },
{ url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" },
{ url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" },
{ url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" },
{ url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" },
{ url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" },
{ url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" },
{ url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" },
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" },
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" },
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" },
]
[[package]]
name = "tqdm"
version = "4.67.3"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "colorama", marker = "sys_platform == 'win32'" },
]
sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" },
]
[[package]]
name = "types-pyyaml"
version = "6.0.12.20250915"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7e/69/3c51b36d04da19b92f9e815be12753125bd8bc247ba0470a982e6979e71c/types_pyyaml-6.0.12.20250915.tar.gz", hash = "sha256:0f8b54a528c303f0e6f7165687dd33fafa81c807fcac23f632b63aa624ced1d3", size = 17522, upload-time = "2025-09-15T03:01:00.728Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/bd/e0/1eed384f02555dde685fff1a1ac805c1c7dcb6dd019c916fe659b1c1f9ec/types_pyyaml-6.0.12.20250915-py3-none-any.whl", hash = "sha256:e7d4d9e064e89a3b3cae120b4990cd370874d2bf12fa5f46c97018dd5d3c9ab6", size = 20338, upload-time = "2025-09-15T03:00:59.218Z" },
]
[[package]]
name = "types-requests"
version = "2.32.4.20260107"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "urllib3" },
]
sdist = { url = "https://files.pythonhosted.org/packages/0f/f3/a0663907082280664d745929205a89d41dffb29e89a50f753af7d57d0a96/types_requests-2.32.4.20260107.tar.gz", hash = "sha256:018a11ac158f801bfa84857ddec1650750e393df8a004a8a9ae2a9bec6fcb24f", size = 23165, upload-time = "2026-01-07T03:20:54.091Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/1c/12/709ea261f2bf91ef0a26a9eed20f2623227a8ed85610c1e54c5805692ecb/types_requests-2.32.4.20260107-py3-none-any.whl", hash = "sha256:b703fe72f8ce5b31ef031264fe9395cac8f46a04661a79f7ed31a80fb308730d", size = 20676, upload-time = "2026-01-07T03:20:52.929Z" },
]
[[package]]
name = "types-tqdm"
version = "4.67.3.20260205"
source = { registry = "https://pypi.org/simple" }
dependencies = [
{ name = "types-requests" },
]
sdist = { url = "https://files.pythonhosted.org/packages/53/46/790b9872523a48163bdda87d47849b4466017640e5259d06eed539340afd/types_tqdm-4.67.3.20260205.tar.gz", hash = "sha256:f3023682d4aa3bbbf908c8c6bb35f35692d319460d9bbd3e646e8852f3dd9f85", size = 17597, upload-time = "2026-02-05T04:03:19.721Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/cc/da/7f761868dbaa328392356fab30c18ab90d14cce86b269e7e63328f29d4a3/types_tqdm-4.67.3.20260205-py3-none-any.whl", hash = "sha256:85c31731e81dc3c5cecc34c6c8b2e5166fafa722468f58840c2b5ac6a8c5c173", size = 23894, upload-time = "2026-02-05T04:03:18.48Z" },
]
[[package]]
name = "updates"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "pyyaml" },
{ name = "tqdm" },
{ name = "types-pyyaml" },
{ name = "types-tqdm" },
]
[package.metadata]
requires-dist = [
{ name = "pyyaml", specifier = ">=6.0.3" },
{ name = "tqdm", specifier = ">=4.67.3" },
{ name = "types-pyyaml", specifier = ">=6.0.12.20250915" },
{ name = "types-tqdm", specifier = ">=4.67.3.20260205" },
]
[[package]]
name = "urllib3"
version = "2.6.3"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/c7/24/5f1b3bdffd70275f6661c76461e25f024d5a38a46f04aaca912426a2b1d3/urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed", size = 435556, upload-time = "2026-01-07T16:24:43.925Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/39/08/aaaad47bc4e9dc8c725e68f9d04865dbcb2052843ff09c97b08904852d84/urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4", size = 131584, upload-time = "2026-01-07T16:24:42.685Z" },
]

13
pyproject.toml Normal file
View File

@@ -0,0 +1,13 @@
[project]
name = "homelab"
version = "0.1.0"
requires-python = ">=3.13"
dependencies = [
"click==8.2.1",
"mkdocs>=1.6.1",
"openai>=2.21.0",
"pyyaml>=6.0.3",
"tqdm>=4.67.3",
"types-pyyaml>=6.0.12.20250915",
"types-tqdm>=4.67.3.20260205",
]

View File

@@ -1,6 +1,6 @@
# IPv4 Proxy
**DEPRECATED** Replaced by [Caddy](/active/podman_caddy/caddy.md)
**DEPRECATED** Replaced by [Caddy](/active/container_caddy/caddy.md)
This project aims to serve those without an IPv6 ISP by forwarding IPv4 requests to the
correct destination. This is accomplished by SSL preread and port mapping. This service

Some files were not shown because too many files have changed in this diff Show More