overhauls of most service docs
All checks were successful
Podman DDNS Image / build-and-push-ddns (push) Successful in 33s
All checks were successful
Podman DDNS Image / build-and-push-ddns (push) Successful in 33s
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -6,4 +6,5 @@ volumes/
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
.venv/
|
.venv/
|
||||||
.mypy_cache
|
.mypy_cache
|
||||||
|
TODO.md
|
||||||
76
README.md
76
README.md
@@ -14,6 +14,8 @@ Status](https://gitea.reeseapps.com/services/homelab/actions/workflows/distoolbo
|
|||||||
- [Homelab](#homelab)
|
- [Homelab](#homelab)
|
||||||
- [Table of Contents](#table-of-contents)
|
- [Table of Contents](#table-of-contents)
|
||||||
- [Fun Facts](#fun-facts)
|
- [Fun Facts](#fun-facts)
|
||||||
|
- [Keyboard Shortcuts](#keyboard-shortcuts)
|
||||||
|
- [SSH Setup](#ssh-setup)
|
||||||
- [Important Dates and Times](#important-dates-and-times)
|
- [Important Dates and Times](#important-dates-and-times)
|
||||||
- [Project Lifecycle](#project-lifecycle)
|
- [Project Lifecycle](#project-lifecycle)
|
||||||
- [Project Types](#project-types)
|
- [Project Types](#project-types)
|
||||||
@@ -25,33 +27,77 @@ Status](https://gitea.reeseapps.com/services/homelab/actions/workflows/distoolbo
|
|||||||
|
|
||||||
## Fun Facts
|
## Fun Facts
|
||||||
|
|
||||||
|
### Keyboard Shortcuts
|
||||||
|
|
||||||
On linux, <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>u</kbd>, then, while holding
|
On linux, <kbd>ctrl</kbd>+<kbd>shift</kbd>+<kbd>u</kbd>, then, while holding
|
||||||
<kbd>ctrl</kbd>+<kbd>shift</kbd>, typing <kbd>b</kbd>+<kbd>0</kbd> will type a
|
<kbd>ctrl</kbd>+<kbd>shift</kbd>, typing <kbd>b</kbd>+<kbd>0</kbd> will type a
|
||||||
° (degree) symbol. Also you can enter any unicode symbol this way.
|
° (degree) symbol. Also you can enter any unicode symbol this way.
|
||||||
|
|
||||||
To generate an SSH key with the correct comment and type run:
|
In vim: `esc + o` will take you to the end of a file and insert a new line.
|
||||||
|
|
||||||
|
## SSH Setup
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export KEYGEN_USER=myuser
|
export REMOTE_USER=${USER}
|
||||||
export KEYGEN_HOST=something.com
|
export REMOTE_HOST=something.com
|
||||||
ssh-keygen -C ${KEYGEN_USER}@${KEYGEN_HOST} -f ~/.ssh/id_${KEYGEN_HOST} -t ed25519
|
export REMOTE_PORT=22
|
||||||
|
|
||||||
|
# The following is generated by the above variables. No tweaks necessary.
|
||||||
|
export KEY_NAME=~/.ssh/id_${REMOTE_USER}_${REMOTE_HOST}
|
||||||
|
export KEY_COMMENT="${USER}@${HOSTNAME}:${REMOTE_USER}@${REMOTE_HOST}"
|
||||||
|
|
||||||
|
# Pick one of the below key types
|
||||||
|
# ed25519
|
||||||
|
ssh-keygen -C ${KEY_COMMENT} -f ${KEY_NAME} -t ed25519
|
||||||
|
# rsa 4096
|
||||||
|
ssh-keygen -C ${KEY_COMMENT} -f ${KEY_NAME} -t rsa -b 4096
|
||||||
|
|
||||||
cat <<EOF >> ~/.ssh/config
|
cat <<EOF >> ~/.ssh/config
|
||||||
Host ${KEYGEN_HOST}
|
|
||||||
Hostname ${KEYGEN_HOST}
|
|
||||||
IdentityFile ~/.ssh/id_${KEYGEN_HOST}
|
|
||||||
User ${KEYGEN_USER}
|
|
||||||
Port 22
|
|
||||||
EOF
|
|
||||||
```
|
|
||||||
|
|
||||||
In vim: `esc + o` will take you to the end of a file and insert a new line.
|
Host ${REMOTE_HOST}
|
||||||
|
Hostname ${REMOTE_HOST}
|
||||||
|
IdentityFile ${KEY_NAME}
|
||||||
|
User ${REMOTE_USER}
|
||||||
|
Port ${REMOTE_PORT}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Copy the generated key to the server using password auth. Assumes password auth enabled.
|
||||||
|
ssh-copy-id -o PubkeyAuthentication=no -i ${KEY_NAME} ${REMOTE_USER}@${REMOTE_HOST}
|
||||||
|
|
||||||
|
# Log into the server with your key
|
||||||
|
ssh -i ${KEY_NAME} ${KEY_COMMENT}
|
||||||
|
# Copy authorized_keys to root
|
||||||
|
sudo cp ~/.ssh/authorized_keys /root/.ssh/authorized_keys
|
||||||
|
exit
|
||||||
|
|
||||||
|
# login and disable password auth
|
||||||
|
ssh ${REMOTE_HOST}
|
||||||
|
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/01-prohibit-password.conf
|
||||||
|
systemctl restart sshd
|
||||||
|
|
||||||
|
# OPTIONAL: Disable sudo password
|
||||||
|
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/01-nopasswd-wheel
|
||||||
|
|
||||||
|
exit
|
||||||
|
|
||||||
|
# Test if you can SSH with a password
|
||||||
|
ssh -o PubkeyAuthentication=no ducoterra@${SSH_HOST}.reeselink.com
|
||||||
|
|
||||||
|
# Test that you can log into the server with ssh config
|
||||||
|
ssh $SSH_HOST
|
||||||
|
```
|
||||||
|
|
||||||
## Important Dates and Times
|
## Important Dates and Times
|
||||||
|
|
||||||
- Machine updates happen at 4am on on Saturday
|
| Time | Day | Description |
|
||||||
- VM updates happen at 5am on Saturday
|
| ----- | -------- | ------------------------------ |
|
||||||
- Backups happen at 6am every day
|
| 00:00 | All | Automated builds |
|
||||||
|
| 00:00 | All | NAS Snapshots |
|
||||||
|
| 02:00 | All | Backups |
|
||||||
|
| 04:00 | Saturday | Server Hardware Updates |
|
||||||
|
| 05:00 | Saturday | Server VM Updates |
|
||||||
|
| 05:00 | All | Unifi Protect Firmware Updates |
|
||||||
|
| 06:00 | All | Unifi Network Firmware Updates |
|
||||||
|
|
||||||
## Project Lifecycle
|
## Project Lifecycle
|
||||||
|
|
||||||
|
|||||||
BIN
active/device_framework_16/icc_profile.icm
Normal file
BIN
active/device_framework_16/icc_profile.icm
Normal file
Binary file not shown.
@@ -5,11 +5,16 @@
|
|||||||
- [Schlage Door Lock](#schlage-door-lock)
|
- [Schlage Door Lock](#schlage-door-lock)
|
||||||
- [Philips Hue Lights](#philips-hue-lights)
|
- [Philips Hue Lights](#philips-hue-lights)
|
||||||
- [Shelly](#shelly)
|
- [Shelly](#shelly)
|
||||||
- [Relative Humidity Calculator](#relative-humidity-calculator)
|
- [Barometer](#barometer)
|
||||||
|
- [Relative Humidity Calculator](#relative-humidity-calculator)
|
||||||
- [Font Colors](#font-colors)
|
- [Font Colors](#font-colors)
|
||||||
- [Light Indicator for Voice Assistant](#light-indicator-for-voice-assistant)
|
- [Light Indicator for Voice Assistant](#light-indicator-for-voice-assistant)
|
||||||
- [Blank Button (Spacer)](#blank-button-spacer)
|
- [Blank Button (Spacer)](#blank-button-spacer)
|
||||||
- [Roku Remote](#roku-remote)
|
- [Roku Remote](#roku-remote)
|
||||||
|
- [Flair Vent Battery](#flair-vent-battery)
|
||||||
|
- [Voice](#voice)
|
||||||
|
- [Custom Sentences](#custom-sentences)
|
||||||
|
- [Notifications](#notifications)
|
||||||
|
|
||||||
## Setup and Configuration
|
## Setup and Configuration
|
||||||
|
|
||||||
@@ -48,7 +53,51 @@ is quicker to pick up and transmit device information. Note that "gateway mode"
|
|||||||
just enable bluetooth and rpc or select "active" from the configuration menu for the shelly
|
just enable bluetooth and rpc or select "active" from the configuration menu for the shelly
|
||||||
device.
|
device.
|
||||||
|
|
||||||
### Relative Humidity Calculator
|
#### Barometer
|
||||||
|
|
||||||
|
<https://www.thoughtco.com/how-to-read-a-barometer-3444043>
|
||||||
|
|
||||||
|
A barometric reading over 30.20 inHg is generally considered high, and high pressure is associated with clear skies and calm weather.
|
||||||
|
|
||||||
|
If the reading is over 30.20 inHg (102268.9 Pa or 1022.689 mb):
|
||||||
|
|
||||||
|
- Rising or steady pressure means continued fair weather.
|
||||||
|
- Slowly falling pressure means fair weather.
|
||||||
|
- Rapidly falling pressure means cloudy and warmer conditions.
|
||||||
|
|
||||||
|
A barometric reading in the range of 29.80 and 30.20 inHg can be considered normal, and normal pressure is associated with steady weather.
|
||||||
|
|
||||||
|
If the reading falls between 29.80 and 30.20 inHg (100914.4–102268.9 Pa or 1022.689–1009.144 mb):
|
||||||
|
|
||||||
|
- Rising or steady pressure means present conditions will continue.
|
||||||
|
- Slowly falling pressure means little change in the weather.
|
||||||
|
- Rapidly falling pressure means that rain is likely, or snow if it is cold enough.
|
||||||
|
|
||||||
|
A barometric reading below 29.80 inHg is generally considered low, and low pressure is associated with warm air and rainstorms.
|
||||||
|
|
||||||
|
If the reading is under 29.80 inHg (100914.4 Pa or 1009.144 mb):
|
||||||
|
|
||||||
|
- Rising or steady pressure indicates clearing and cooler weather.
|
||||||
|
- Slowly falling pressure indicates rain.
|
||||||
|
- Rapidly falling pressure indicates a storm is coming.
|
||||||
|
|
||||||
|
A basic automation would look like
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
It's {{ int(states("sensor.grouse_temp")) }} degrees and {{ states("weather.grouse_weather") }}. The relative humidity is {{ states("sensor.grouse_humidity") }}%. I'm seeing {{ int(states("sensor.grouse_wind_speed")) }}mph wind with gusts up to {{ int(states("sensor.grouse_wind_gust")) }}mph.
|
||||||
|
|
||||||
|
{% set pressure = float(states("sensor.grouse_rel_pressure")) %}
|
||||||
|
The barometer reads {{ pressure }}inHg.
|
||||||
|
{% if pressure > 30.20 %}
|
||||||
|
Fair weather is expected
|
||||||
|
{% elif pressure > 29.80 %}
|
||||||
|
Rain is possible
|
||||||
|
{% else %}
|
||||||
|
Rain is coming.
|
||||||
|
{% endif %}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Relative Humidity Calculator
|
||||||
|
|
||||||
<https://www.wikihow.com/Calculate-Humidity>
|
<https://www.wikihow.com/Calculate-Humidity>
|
||||||
|
|
||||||
@@ -335,4 +384,32 @@ cards:
|
|||||||
hold_action:
|
hold_action:
|
||||||
action: none
|
action: none
|
||||||
title: Left Living Room TV
|
title: Left Living Room TV
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Flair Vent Battery
|
||||||
|
|
||||||
|
Flair vents report low battery at 2.4v. 3v is nominal/full.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
{% set volt_min=2.4 %}
|
||||||
|
{% set volt_max=3.0 %}
|
||||||
|
{% set volt_diff_max=0.6 %}
|
||||||
|
|
||||||
|
{{ (min(float(states("sensor.main_bedroom_29bf_voltage")) - volt_min, volt_diff_max) / volt_diff_max) * 100 }}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Voice
|
||||||
|
|
||||||
|
### Custom Sentences
|
||||||
|
|
||||||
|
<https://developers.home-assistant.io/docs/voice/intent-recognition/template-sentence-syntax/#sentence-templates-syntax>
|
||||||
|
|
||||||
|
## Notifications
|
||||||
|
|
||||||
|
Notification Information:
|
||||||
|
|
||||||
|
<https://www.home-assistant.io/docs/automation/templating/>
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
Triggered by {{ trigger.entity_id }}, Date: {{ now().strftime('%Y-%m-%d') }}, Time: {{ now().strftime('%H:%M') }}
|
||||||
|
```
|
||||||
|
|||||||
21
active/notes_freedesktop/freedesktop.md
Normal file
21
active/notes_freedesktop/freedesktop.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Freedesktop Notes
|
||||||
|
|
||||||
|
Notes pertaining to the `.desktop` extension and desktop entries.
|
||||||
|
|
||||||
|
## Keys
|
||||||
|
|
||||||
|
<https://specifications.freedesktop.org/desktop-entry-spec/1.5/recognized-keys.html>
|
||||||
|
|
||||||
|
## Icons
|
||||||
|
|
||||||
|
<https://freedesktop.org/wiki/Specifications/icon-theme-spec/>
|
||||||
|
|
||||||
|
By default, apps should look in $HOME/.icons (for backwards compatibility), in $XDG_DATA_DIRS/icons and in /usr/share/pixmaps (in that order).
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Run a `.desktop` file from terminal with this:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
gtk-launch gnome-system-monitor.desktop
|
||||||
|
```
|
||||||
@@ -210,35 +210,7 @@ Now the status should be correct even after connecting/disconnecting when the co
|
|||||||
|
|
||||||
## SSH
|
## SSH
|
||||||
|
|
||||||
Generate a key with password protection:
|
See [README](/README.md#ssh-setup)
|
||||||
|
|
||||||
```bash
|
|
||||||
# Omit "-N 'password'" to have it prompt you
|
|
||||||
ssh-keygen -f ~/.ssh/test-key -N 'PASSWORD'
|
|
||||||
```
|
|
||||||
|
|
||||||
Change the password for an ssh key:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Use "-N ''" to remove the password
|
|
||||||
ssh-keygen -p -N 'PASSWORD' -f ~/.ssh/test-key
|
|
||||||
```
|
|
||||||
|
|
||||||
This is an example config entry in `~/.ssh/config`:
|
|
||||||
|
|
||||||
```conf
|
|
||||||
Host my-host
|
|
||||||
Hostname my-host.reeselink.com
|
|
||||||
User root
|
|
||||||
ProxyCommand none
|
|
||||||
ForwardAgent no
|
|
||||||
ForwardX11 no
|
|
||||||
Port 22
|
|
||||||
KeepAlive yes
|
|
||||||
IdentityFile ~/.ssh/id_my-host_rsa
|
|
||||||
```
|
|
||||||
|
|
||||||
You can ssh to that host with `ssh my-host` after adding a config entry.
|
|
||||||
|
|
||||||
## Templates
|
## Templates
|
||||||
|
|
||||||
@@ -652,7 +624,6 @@ Custom profiles are located at
|
|||||||
|
|
||||||
Sync this with something like Nextcloud.
|
Sync this with something like Nextcloud.
|
||||||
|
|
||||||
|
|
||||||
## Orca Slicer
|
## Orca Slicer
|
||||||
|
|
||||||
<https://github.com/SoftFever/OrcaSlicer>
|
<https://github.com/SoftFever/OrcaSlicer>
|
||||||
|
|||||||
@@ -14,55 +14,7 @@ and the operator will store information about each server.
|
|||||||
|
|
||||||
## Setup SSH
|
## Setup SSH
|
||||||
|
|
||||||
On the operator:
|
See [README](/README.md#ssh-setup)
|
||||||
|
|
||||||
```bash
|
|
||||||
export SSH_HOST=kube
|
|
||||||
ssh-keygen -t rsa -b 4096 -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${SSH_HOST}_rsa
|
|
||||||
|
|
||||||
# Note: If you get "too many authentication failures" it's likely because you have too many private
|
|
||||||
# keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it.
|
|
||||||
ssh-copy-id -o PubkeyAuthentication=no -i ~/.ssh/id_${SSH_HOST}_rsa.pub ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
ssh -i ~/.ssh/id_${SSH_HOST}_rsa -o 'PubkeyAuthentication=yes' ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
```
|
|
||||||
|
|
||||||
On the server:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Copy authorized_keys to root
|
|
||||||
sudo cp ~/.ssh/authorized_keys /root/.ssh/authorized_keys
|
|
||||||
|
|
||||||
# Change your password
|
|
||||||
passwd
|
|
||||||
|
|
||||||
sudo su -
|
|
||||||
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/01-prohibit-password.conf
|
|
||||||
echo '%sudo ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/01-nopasswd-sudo
|
|
||||||
systemctl restart ssh
|
|
||||||
```
|
|
||||||
|
|
||||||
On the operator:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cat <<EOF >> ~/.ssh/config
|
|
||||||
|
|
||||||
Host $SSH_HOST
|
|
||||||
Hostname ${SSH_HOST}.reeselink.com
|
|
||||||
User root
|
|
||||||
ProxyCommand none
|
|
||||||
ForwardAgent no
|
|
||||||
ForwardX11 no
|
|
||||||
Port 22
|
|
||||||
KeepAlive yes
|
|
||||||
IdentityFile ~/.ssh/id_${SSH_HOST}_rsa
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Test if you can SSH with a password
|
|
||||||
ssh -o PubkeyAuthentication=no ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
|
|
||||||
# Test that you can log into the server with ssh config
|
|
||||||
ssh $SSH_HOST
|
|
||||||
```
|
|
||||||
|
|
||||||
## Fail2Ban
|
## Fail2Ban
|
||||||
|
|
||||||
|
|||||||
@@ -285,4 +285,4 @@ output.eDP-2.enable \
|
|||||||
output.eDP-2.mode.1920x1080@60 \
|
output.eDP-2.mode.1920x1080@60 \
|
||||||
output.eDP-2.scale.1 \
|
output.eDP-2.scale.1 \
|
||||||
output.eDP-2.position.0,0
|
output.eDP-2.position.0,0
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
- [Fail2Ban](#fail2ban)
|
- [Fail2Ban](#fail2ban)
|
||||||
- [BTRFS Parent Volumes](#btrfs-parent-volumes)
|
- [BTRFS Parent Volumes](#btrfs-parent-volumes)
|
||||||
- [BTRFS Snapshots](#btrfs-snapshots)
|
- [BTRFS Snapshots](#btrfs-snapshots)
|
||||||
|
- [BTRFS Maintenance](#btrfs-maintenance)
|
||||||
- [TPM2 Luks Decryption](#tpm2-luks-decryption)
|
- [TPM2 Luks Decryption](#tpm2-luks-decryption)
|
||||||
- [Change your password](#change-your-password)
|
- [Change your password](#change-your-password)
|
||||||
- [Automatic Updates](#automatic-updates)
|
- [Automatic Updates](#automatic-updates)
|
||||||
@@ -73,48 +74,7 @@ and the operator will store information about each server.
|
|||||||
|
|
||||||
## Setup SSH
|
## Setup SSH
|
||||||
|
|
||||||
In this setup we'll allow ssh to the root user via key and keep the admin user for cockpit.
|
See [README](/README.md#ssh-setup)
|
||||||
|
|
||||||
On the operator:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
export SSH_HOST=kube
|
|
||||||
ssh-keygen -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${SSH_HOST}_rsa
|
|
||||||
|
|
||||||
# Note: If you get "too many authentication failures" it's likely because you have too many private
|
|
||||||
# keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it.
|
|
||||||
ssh-copy-id -o PubkeyAuthentication=no -i ~/.ssh/id_${SSH_HOST}_rsa.pub ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
ssh -i ~/.ssh/id_${SSH_HOST}_rsa ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
# Copy authorized_keys to root
|
|
||||||
sudo cp ~/.ssh/authorized_keys /root/.ssh/authorized_keys
|
|
||||||
exit
|
|
||||||
|
|
||||||
cat <<EOF >> ~/.ssh/config
|
|
||||||
|
|
||||||
Host ${SSH_HOST}
|
|
||||||
Hostname ${SSH_HOST}.reeselink.com
|
|
||||||
User root
|
|
||||||
Port 22
|
|
||||||
KeepAlive yes
|
|
||||||
IdentityFile ~/.ssh/id_${SSH_HOST}_rsa
|
|
||||||
EOF
|
|
||||||
|
|
||||||
ssh ${SSH_HOST}
|
|
||||||
# Disable password auth
|
|
||||||
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/01-prohibit-password.conf
|
|
||||||
systemctl restart sshd
|
|
||||||
|
|
||||||
# OPTIONAL: Disable sudo password
|
|
||||||
echo '%wheel ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/01-nopasswd-wheel
|
|
||||||
|
|
||||||
exit
|
|
||||||
|
|
||||||
# Test if you can SSH with a password
|
|
||||||
ssh -o PubkeyAuthentication=no ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
|
|
||||||
# Test that you can log into the server with ssh config
|
|
||||||
ssh $SSH_HOST
|
|
||||||
```
|
|
||||||
|
|
||||||
## DNF
|
## DNF
|
||||||
|
|
||||||
@@ -224,6 +184,13 @@ snapper -c root delete 1
|
|||||||
Note - you probably don't want to keep yearly snapshots.
|
Note - you probably don't want to keep yearly snapshots.
|
||||||
Edit `/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`.
|
Edit `/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`.
|
||||||
|
|
||||||
|
## BTRFS Maintenance
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start a scrub in the foreground (-B) at /
|
||||||
|
btrfs scrub start -B /
|
||||||
|
```
|
||||||
|
|
||||||
## TPM2 Luks Decryption
|
## TPM2 Luks Decryption
|
||||||
|
|
||||||
Mostly taken from here:
|
Mostly taken from here:
|
||||||
@@ -324,7 +291,7 @@ TODO
|
|||||||
|
|
||||||
## Common Storage Mounts
|
## Common Storage Mounts
|
||||||
|
|
||||||
Note: mount these before you install the relavant package!
|
Note: mount these before you install the relevant package!
|
||||||
|
|
||||||
1. For virtual machines: `/var/lib/libvirt`
|
1. For virtual machines: `/var/lib/libvirt`
|
||||||
2. For podman: `/var/lib/containers`
|
2. For podman: `/var/lib/containers`
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Apps
|
# Apps
|
||||||
|
|
||||||
- [Apps](#apps)
|
- [Apps](#apps)
|
||||||
|
- [Common CLI Apps](#common-cli-apps)
|
||||||
- [Gear Lever](#gear-lever)
|
- [Gear Lever](#gear-lever)
|
||||||
- [VSCode](#vscode)
|
- [VSCode](#vscode)
|
||||||
- [DNF](#dnf)
|
- [DNF](#dnf)
|
||||||
@@ -47,6 +48,11 @@
|
|||||||
- [KDiskMark](#kdiskmark)
|
- [KDiskMark](#kdiskmark)
|
||||||
- [Local Send](#local-send)
|
- [Local Send](#local-send)
|
||||||
- [Evolution](#evolution)
|
- [Evolution](#evolution)
|
||||||
|
- [Virtualization](#virtualization)
|
||||||
|
- [NVM](#nvm)
|
||||||
|
- [Ollama](#ollama)
|
||||||
|
- [UV](#uv)
|
||||||
|
- [Pipenv](#pipenv)
|
||||||
|
|
||||||
Flatpak installs are from Flathub unless otherwise noted.
|
Flatpak installs are from Flathub unless otherwise noted.
|
||||||
|
|
||||||
@@ -58,6 +64,66 @@ flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.f
|
|||||||
|
|
||||||
When prompted, prefer flathub.
|
When prompted, prefer flathub.
|
||||||
|
|
||||||
|
## Common CLI Apps
|
||||||
|
|
||||||
|
Some common apps you'll probably want available.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo dnf install \
|
||||||
|
# Advanced text editor for code editing and other tasks.
|
||||||
|
vim \
|
||||||
|
# Network bandwidth measuring tool.
|
||||||
|
iperf3 \
|
||||||
|
# Command-line interface for managing Kubernetes clusters.
|
||||||
|
kubectl \
|
||||||
|
# Package manager and deployment tool for Kubernetes.
|
||||||
|
helm \
|
||||||
|
# Utility to monitor real-time network usage of processes.
|
||||||
|
nethogs \
|
||||||
|
# DevOps configuration management tool.
|
||||||
|
ansible \
|
||||||
|
# Terminal multiplexer.
|
||||||
|
tmux \
|
||||||
|
# Multimedia player with support for a wide range of codecs and file formats.
|
||||||
|
ffmpeg \
|
||||||
|
# Microsoft Windows compatibility layer.
|
||||||
|
wine \
|
||||||
|
# Archive utility similar to GNU tar, used to package files into single archive files.
|
||||||
|
unzip \
|
||||||
|
# A terminal activity monitor (top clone).
|
||||||
|
btop \
|
||||||
|
# Command-line JSON processor.
|
||||||
|
jq \
|
||||||
|
# YAML-based configuration-as-code tool for command-line interfaces written in Go, Rust, Python, and more.
|
||||||
|
yq \
|
||||||
|
# An image manipulation software suite based on ImageMagick.
|
||||||
|
ImageMagick \
|
||||||
|
# The Go programming language environment including a toolchain (gc) and libraries.
|
||||||
|
go \
|
||||||
|
# Rust package manager and compiler installation utility.
|
||||||
|
rust rustup \
|
||||||
|
# Distributed version control system, Git extension that adds support for large files like multimedia assets.
|
||||||
|
git git-lfs \
|
||||||
|
# Provides traditional network tools such as ifconfig, netstat, hostname, etc., in a single package.
|
||||||
|
net-tools \
|
||||||
|
# Document conversion tool and markup language converter.
|
||||||
|
pandoc \
|
||||||
|
# Comprehensive LaTeX distribution for high-quality typesetting of documents.
|
||||||
|
texlive-latex \
|
||||||
|
# Generate strong passwords.
|
||||||
|
pwgen \
|
||||||
|
# Reattach to running processes
|
||||||
|
reptyr \
|
||||||
|
# Netcat, for basic tcp/udp operations
|
||||||
|
netcat \
|
||||||
|
# 7zip support
|
||||||
|
p7zip \
|
||||||
|
# Make
|
||||||
|
make \
|
||||||
|
# GCC for compile
|
||||||
|
gcc
|
||||||
|
```
|
||||||
|
|
||||||
## Gear Lever
|
## Gear Lever
|
||||||
|
|
||||||
I would recommend you install Gear Lever to manage App Images:
|
I would recommend you install Gear Lever to manage App Images:
|
||||||
@@ -296,6 +362,12 @@ At the very top of the config you can add a pin for a printer permanently with:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You'll need to open port 2021 udp
|
||||||
|
|
||||||
|
```bash
|
||||||
|
firewall-cmd --add-port=2021/udp --permanent
|
||||||
|
```
|
||||||
|
|
||||||
## Freecad
|
## Freecad
|
||||||
|
|
||||||
Benchy benchy benchy oh no, I can't do that, this is hard.
|
Benchy benchy benchy oh no, I can't do that, this is hard.
|
||||||
@@ -402,10 +474,11 @@ flatpak install io.github.thetumultuousunicornofdarkness.cpu-x
|
|||||||
|
|
||||||
## Ungoogled Chromium
|
## Ungoogled Chromium
|
||||||
|
|
||||||
Chrom
|
<https://github.com/ungoogled-software/ungoogled-chromium?tab=readme-ov-file#automated-or-maintained-builds>
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
flatpak install io.github.ungoogled_software.ungoogled_chromium
|
sudo dnf copr enable wojnilowicz/ungoogled-chromium
|
||||||
|
sudo dnf install ungoogled-chromium
|
||||||
```
|
```
|
||||||
|
|
||||||
## Signal
|
## Signal
|
||||||
@@ -507,4 +580,36 @@ You still use email? I still use email.
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
flatpak install org.gnome.Evolution
|
flatpak install org.gnome.Evolution
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Virtualization
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Virtualization
|
||||||
|
sudo dnf group install --with-optional virtualization
|
||||||
|
```
|
||||||
|
|
||||||
|
## NVM
|
||||||
|
|
||||||
|
<https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating>
|
||||||
|
|
||||||
|
## Ollama
|
||||||
|
|
||||||
|
<https://ollama.com/download>
|
||||||
|
|
||||||
|
Run the installation script as normal. Make sure you have the [ROCM](#rocm)
|
||||||
|
drivers installed for GPU acceleration. The script *should* automatically pull
|
||||||
|
the ROCM drivers after installing the base packages. If not, you should install
|
||||||
|
them manually.
|
||||||
|
|
||||||
|
For starting ollama as a service, follow the link below:
|
||||||
|
|
||||||
|
<https://github.com/ollama/ollama/blob/main/docs/linux.md#adding-ollama-as-a-startup-service-recommended>
|
||||||
|
|
||||||
|
## UV
|
||||||
|
|
||||||
|
<https://docs.astral.sh/uv/getting-started/installation/>
|
||||||
|
|
||||||
|
## Pipenv
|
||||||
|
|
||||||
|
<https://pipenv.pypa.io/en/latest/installation.html#installing-pipenv>
|
||||||
@@ -4,37 +4,28 @@
|
|||||||
- [Framework 16 Fixes](#framework-16-fixes)
|
- [Framework 16 Fixes](#framework-16-fixes)
|
||||||
- [Wake from Sleep](#wake-from-sleep)
|
- [Wake from Sleep](#wake-from-sleep)
|
||||||
- [Wrong keys pressed in the browser](#wrong-keys-pressed-in-the-browser)
|
- [Wrong keys pressed in the browser](#wrong-keys-pressed-in-the-browser)
|
||||||
- [Fix wifi disconnecting and reconnecting repeatedly on reboot/resume](#fix-wifi-disconnecting-and-reconnecting-repeatedly-on-rebootresume)
|
|
||||||
- [Wifi Powersave](#wifi-powersave)
|
|
||||||
- [Podman](#podman)
|
- [Podman](#podman)
|
||||||
- [Autostarting services with quadlets](#autostarting-services-with-quadlets)
|
- [Autostarting services with quadlets](#autostarting-services-with-quadlets)
|
||||||
- [Toolbox](#toolbox)
|
- [Toolbox](#toolbox)
|
||||||
- [Network](#network)
|
- [Network](#network)
|
||||||
|
- [Firewall](#firewall)
|
||||||
- [VLAN Setup with nmcli](#vlan-setup-with-nmcli)
|
- [VLAN Setup with nmcli](#vlan-setup-with-nmcli)
|
||||||
- [ZRAM](#zram)
|
- [ZRAM](#zram)
|
||||||
- [Libraries](#libraries)
|
- [Libraries](#libraries)
|
||||||
- [Common Libraries](#common-libraries)
|
- [Common Libraries](#common-libraries)
|
||||||
- [Apps](#apps)
|
|
||||||
- [Common CLI Apps](#common-cli-apps)
|
|
||||||
- [Ungoogled Chromium](#ungoogled-chromium)
|
|
||||||
- [VSCode](#vscode)
|
|
||||||
- [Virtualization](#virtualization)
|
|
||||||
- [NVM](#nvm)
|
|
||||||
- [Ollama](#ollama)
|
|
||||||
- [UV](#uv)
|
|
||||||
- [Pipenv](#pipenv)
|
|
||||||
- [Backups](#backups)
|
- [Backups](#backups)
|
||||||
- [BTRFS Snapshots](#btrfs-snapshots)
|
- [BTRFS Snapshots](#btrfs-snapshots)
|
||||||
- [ROCM](#rocm)
|
- [ROCM](#rocm)
|
||||||
- [Display](#display)
|
- [Display](#display)
|
||||||
- [Scripted Display Modes](#scripted-display-modes)
|
- [Scripted Display Modes](#scripted-display-modes)
|
||||||
|
- [Fixing generic Wayland icons on task alt tab](#fixing-generic-wayland-icons-on-task-alt-tab)
|
||||||
|
|
||||||
## Framework 16 Fixes
|
## Framework 16 Fixes
|
||||||
|
|
||||||
### Wake from Sleep
|
### Wake from Sleep
|
||||||
|
|
||||||
The keyboard/mouse can be pressed through the lid while in a backpack. Disable them to
|
The keyboard/mouse can be pressed through the lid while in a backpack. Disable
|
||||||
prevent wake from sleep.
|
them to prevent wake from sleep.
|
||||||
|
|
||||||
`/etc/udev/rules.d/69-suspend.rules`
|
`/etc/udev/rules.d/69-suspend.rules`
|
||||||
|
|
||||||
@@ -55,61 +46,15 @@ sudo udevadm control --reload-rules && sudo udevadm trigger
|
|||||||
|
|
||||||
### Wrong keys pressed in the browser
|
### Wrong keys pressed in the browser
|
||||||
|
|
||||||
Sometimes keys will stop working when using search bars or do strange things like move the page around. This seems to be caused by some "alt" keypress combination. Pressing "alt" twice fixes it.
|
Sometimes keys will stop working when using search bars or do strange things
|
||||||
|
like move the page around. This seems to be caused by some "alt" keypress
|
||||||
### Fix wifi disconnecting and reconnecting repeatedly on reboot/resume
|
combination. Pressing "alt" twice fixes it.
|
||||||
|
|
||||||
Create a file in `/etc/systemd/system/reset-iwlwifi.service` with the following content:
|
|
||||||
|
|
||||||
```conf
|
|
||||||
[Unit]
|
|
||||||
Description=Reload iwlwifi on wake-up
|
|
||||||
After=suspend.target
|
|
||||||
After=multi-user.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
ExecStartPre=rmmod iwlmvm iwlwifi
|
|
||||||
ExecStart=modprobe iwlwifi
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=suspend.target
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
systemctl daemon-reload
|
|
||||||
systemctl enable reset-iwlwifi.service
|
|
||||||
```
|
|
||||||
|
|
||||||
### Wifi Powersave
|
|
||||||
|
|
||||||
**NOTE: THIS DOESN'T WORK. IT CAUSES WIFI DISCONNECT AND RECONNECT ISSUES.**
|
|
||||||
|
|
||||||
<https://www.networkmanager.dev/docs/api/latest/settings-802-11-wireless.html>
|
|
||||||
|
|
||||||
<https://gist.github.com/jcberthon/ea8cfe278998968ba7c5a95344bc8b55>
|
|
||||||
|
|
||||||
<https://askubuntu.com/questions/1230525/ubuntu-20-04-network-performance-extremely-slow>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
vim /etc/NetworkManager/conf.d/wifi-powersave-off.conf
|
|
||||||
```
|
|
||||||
|
|
||||||
```conf
|
|
||||||
[connection]
|
|
||||||
# Values are 0 (use default), 1 (ignore/don't touch), 2 (disable) or 3 (enable).
|
|
||||||
wifi.powersave = 2
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
systemctl restart NetworkManager
|
|
||||||
```
|
|
||||||
|
|
||||||
## Podman
|
## Podman
|
||||||
|
|
||||||
Since you'll be using podman for most container-based services, you'll want to set the
|
Since you'll be using podman for most container-based services, you'll want to
|
||||||
the podman auth file to somewhere persistent, otherwise it'll get deleted every time you
|
set the the podman auth file to somewhere persistent, otherwise it'll get
|
||||||
reboot.
|
deleted every time you reboot.
|
||||||
|
|
||||||
Add this to your `.bashrc`:
|
Add this to your `.bashrc`:
|
||||||
|
|
||||||
@@ -122,8 +67,8 @@ Source that and then run `podman login` to create the file.
|
|||||||
|
|
||||||
### Autostarting services with quadlets
|
### Autostarting services with quadlets
|
||||||
|
|
||||||
If you want to run something as your user at boot (like a systemd process, think ollama) you can
|
If you want to run something as your user at boot (like a systemd process,
|
||||||
create a user quadlets like so:
|
think ollama) you can create a user quadlets like so:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Generate the .container file
|
# Generate the .container file
|
||||||
@@ -153,6 +98,65 @@ toolbox enter
|
|||||||
|
|
||||||
## Network
|
## Network
|
||||||
|
|
||||||
|
### Firewall
|
||||||
|
|
||||||
|
Set the default firewall to `drop`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
firewall-cmd --set-default-zone=drop
|
||||||
|
firewall-cmd --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
Allow KDE Connect via 1714-1764 tcp/udp
|
||||||
|
|
||||||
|
```bash
|
||||||
|
firewall-cmd --add-port=1714-1764/udp --add-port=1714-1764/tcp --permanent
|
||||||
|
```
|
||||||
|
|
||||||
|
You can check if the firewall is working via `nmap` from another machine
|
||||||
|
|
||||||
|
Note, add `-r` to scan ports in order.
|
||||||
|
|
||||||
|
Note, add `-vv` to increase verbosity.
|
||||||
|
|
||||||
|
Note, add `-A` to perform OS detection, host lookup, etc.
|
||||||
|
|
||||||
|
Note, use `-F` to perform a quick scan against common ports.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export NMAP_HOST=10.2.0.49
|
||||||
|
|
||||||
|
# Scan for common ports on TCP
|
||||||
|
nmap -sT $NMAP_HOST
|
||||||
|
|
||||||
|
# Scan all ports on TCP
|
||||||
|
nmap -sT -p- $NMAP_HOST
|
||||||
|
|
||||||
|
# Scan specific port on TCP
|
||||||
|
nmap -sT -p5432 $NMAP_HOST
|
||||||
|
|
||||||
|
# Scan range of ports on TCP
|
||||||
|
nmap -sT -p1024-9999 $NMAP_HOST
|
||||||
|
|
||||||
|
# Scan for common ports on UDP
|
||||||
|
nmap -sU $NMAP_HOST
|
||||||
|
|
||||||
|
# Skip host up checking
|
||||||
|
nmap -Pn -sT $NMAP_HOST
|
||||||
|
|
||||||
|
# Scan all ports for everything (takes a really really long time)
|
||||||
|
nmap -Pn -sT -sU -p- $NMAP_HOST
|
||||||
|
|
||||||
|
# Scan using TCP ACK Ping (More serious check that attempts to bypass firewall, See nmap man page)
|
||||||
|
nmap -PA -p- $NMAP_HOST
|
||||||
|
```
|
||||||
|
|
||||||
|
Then, while running a scan:
|
||||||
|
|
||||||
|
v / V: Increase / decrease the verbosity level d / D: Increase / decrease the
|
||||||
|
debugging Level p / P: Turn on / off packet tracing ?: Print a runtime
|
||||||
|
interaction help screen
|
||||||
|
|
||||||
### VLAN Setup with nmcli
|
### VLAN Setup with nmcli
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -199,106 +203,6 @@ xz-devel \
|
|||||||
libgle-devel
|
libgle-devel
|
||||||
```
|
```
|
||||||
|
|
||||||
## Apps
|
|
||||||
|
|
||||||
### Common CLI Apps
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo dnf install \
|
|
||||||
# Advanced text editor for code editing and other tasks.
|
|
||||||
vim \
|
|
||||||
# Network bandwidth measuring tool.
|
|
||||||
iperf3 \
|
|
||||||
# Command-line interface for managing Kubernetes clusters.
|
|
||||||
kubectl \
|
|
||||||
# Package manager and deployment tool for Kubernetes.
|
|
||||||
helm \
|
|
||||||
# Utility to monitor real-time network usage of processes.
|
|
||||||
nethogs \
|
|
||||||
# DevOps configuration management tool.
|
|
||||||
ansible \
|
|
||||||
# Terminal multiplexer.
|
|
||||||
tmux \
|
|
||||||
# Multimedia player with support for a wide range of codecs and file formats.
|
|
||||||
ffmpeg \
|
|
||||||
# Microsoft Windows compatibility layer.
|
|
||||||
wine \
|
|
||||||
# Archive utility similar to GNU tar, used to package files into single archive files.
|
|
||||||
unzip \
|
|
||||||
# A terminal activity monitor (top clone).
|
|
||||||
btop \
|
|
||||||
# Command-line JSON processor.
|
|
||||||
jq \
|
|
||||||
# YAML-based configuration-as-code tool for command-line interfaces written in Go, Rust, Python, and more.
|
|
||||||
yq \
|
|
||||||
# An image manipulation software suite based on ImageMagick.
|
|
||||||
ImageMagick \
|
|
||||||
# The Go programming language environment including a toolchain (gc) and libraries.
|
|
||||||
go \
|
|
||||||
# Rust package manager and compiler installation utility.
|
|
||||||
rust rustup \
|
|
||||||
# Distributed version control system, Git extension that adds support for large files like multimedia assets.
|
|
||||||
git git-lfs \
|
|
||||||
# Provides traditional network tools such as ifconfig, netstat, hostname, etc., in a single package.
|
|
||||||
net-tools \
|
|
||||||
# Document conversion tool and markup language converter.
|
|
||||||
pandoc \
|
|
||||||
# Comprehensive LaTeX distribution for high-quality typesetting of documents.
|
|
||||||
texlive-latex \
|
|
||||||
# Generate strong passwords.
|
|
||||||
pwgen \
|
|
||||||
# Reattach to running processes
|
|
||||||
reptyr \
|
|
||||||
# Netcat, for basic tcp/udp operations
|
|
||||||
netcat \
|
|
||||||
# 7zip support
|
|
||||||
p7zip
|
|
||||||
```
|
|
||||||
|
|
||||||
### Ungoogled Chromium
|
|
||||||
|
|
||||||
<https://github.com/ungoogled-software/ungoogled-chromium?tab=readme-ov-file#automated-or-maintained-builds>
|
|
||||||
|
|
||||||
```bash
|
|
||||||
sudo dnf copr enable wojnilowicz/ungoogled-chromium
|
|
||||||
sudo dnf install ungoogled-chromium
|
|
||||||
```
|
|
||||||
|
|
||||||
### VSCode
|
|
||||||
|
|
||||||
<https://code.visualstudio.com/docs/setup/linux#_rhel-fedora-and-centos-based-distributions>
|
|
||||||
|
|
||||||
### Virtualization
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Virtualization
|
|
||||||
sudo dnf group install --with-optional virtualization
|
|
||||||
```
|
|
||||||
|
|
||||||
### NVM
|
|
||||||
|
|
||||||
<https://github.com/nvm-sh/nvm?tab=readme-ov-file#installing-and-updating>
|
|
||||||
|
|
||||||
### Ollama
|
|
||||||
|
|
||||||
<https://ollama.com/download>
|
|
||||||
|
|
||||||
Run the installation script as normal. Make sure you have the [ROCM](#rocm) drivers installed
|
|
||||||
for GPU acceleration. The script *should* automatically pull the ROCM drivers after installing
|
|
||||||
the base packages. If not, you should install them manually.
|
|
||||||
|
|
||||||
For starting ollama as a service, follow the link below:
|
|
||||||
|
|
||||||
<https://github.com/ollama/ollama/blob/main/docs/linux.md#adding-ollama-as-a-startup-service-recommended>
|
|
||||||
|
|
||||||
### UV
|
|
||||||
|
|
||||||
<https://docs.astral.sh/uv/getting-started/installation/>
|
|
||||||
|
|
||||||
### Pipenv
|
|
||||||
|
|
||||||
<https://pipenv.pypa.io/en/latest/installation.html#installing-pipenv>
|
|
||||||
|
|
||||||
## Backups
|
## Backups
|
||||||
|
|
||||||
### BTRFS Snapshots
|
### BTRFS Snapshots
|
||||||
@@ -307,7 +211,8 @@ For starting ollama as a service, follow the link below:
|
|||||||
|
|
||||||
<http://snapper.io/manpages/snapper-configs.html>
|
<http://snapper.io/manpages/snapper-configs.html>
|
||||||
|
|
||||||
We'll be using snapper, a tool for automating and controlling snapshot behavior.
|
We'll be using snapper, a tool for automating and controlling snapshot
|
||||||
|
behavior.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
dnf install snapper dnf-plugin-snapper
|
dnf install snapper dnf-plugin-snapper
|
||||||
@@ -335,8 +240,8 @@ snapper -c root create --description "test snapshot"
|
|||||||
snapper -c root delete 1
|
snapper -c root delete 1
|
||||||
```
|
```
|
||||||
|
|
||||||
Note - you probably don't want to keep yearly snapshots.
|
Note - you probably don't want to keep yearly snapshots. Edit
|
||||||
Edit `/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`.
|
`/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`.
|
||||||
|
|
||||||
## ROCM
|
## ROCM
|
||||||
|
|
||||||
@@ -400,4 +305,41 @@ output.eDP-2.position.0,0 \
|
|||||||
output.eDP-2.primary \
|
output.eDP-2.primary \
|
||||||
output.eDP-2.mode.1920x1080@165 \
|
output.eDP-2.mode.1920x1080@165 \
|
||||||
output.eDP-2.scale.1'
|
output.eDP-2.scale.1'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Fixing generic Wayland icons on task alt tab
|
||||||
|
|
||||||
|
<https://epergo.com/posts/fix-generic-wayland-icon/>
|
||||||
|
|
||||||
|
1. Access Window Rules
|
||||||
|
|
||||||
|
Go to “System Settings > Window Management > Window Rules”.
|
||||||
|
|
||||||
|
2. Create a New Rule (If None Exist)
|
||||||
|
|
||||||
|
If the application does not have any rules already, create a new one:
|
||||||
|
|
||||||
|
1. Click on “Add New…”
|
||||||
|
2. Add a description (e.g., “Application settings for sublime_merge”)
|
||||||
|
3. Specify the “Window class (application)”
|
||||||
|
|
||||||
|
If you’re unsure of the value for the window class, click “Detect Window
|
||||||
|
Properties”, then click on the application window. A pop-up with the
|
||||||
|
detected properties will be shown, and you can select the correct value.
|
||||||
|
|
||||||
|
3. Add Property
|
||||||
|
|
||||||
|
1. Click on “Add Property” and select “Desktop File Name”.
|
||||||
|
|
||||||
|
4. Find the Correct Desktop File Name
|
||||||
|
|
||||||
|
Standard Applications: If the application is installed using your distro’s
|
||||||
|
repositories, check the name in /usr/share/applications/. Flatpak
|
||||||
|
Applications: If it’s a Flatpak package, check the name in
|
||||||
|
/var/lib/flatpak/exports/share/applications/. For example, for Obsidian, it
|
||||||
|
will be md.obsidian.Obsidian (do not include the .desktop suffix).
|
||||||
|
|
||||||
|
5. Apply Settings
|
||||||
|
|
||||||
|
Apply the new settings and close the application if it was open. The next
|
||||||
|
time you open the application, it should show the correct icon.
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
kscreen-doctor \
|
|
||||||
output.eDP-2.enable \
|
|
||||||
output.eDP-2.position.0,0 \
|
|
||||||
output.eDP-2.primary \
|
|
||||||
output.eDP-2.mode.1920x1080@60 \
|
|
||||||
output.eDP-2.scale.1
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
kscreen-doctor \
|
|
||||||
output.eDP-2.enable \
|
|
||||||
output.eDP-2.position.0,0 \
|
|
||||||
output.eDP-2.primary \
|
|
||||||
output.eDP-2.mode.2560x1600@165 \
|
|
||||||
output.eDP-2.scale.1.25
|
|
||||||
@@ -161,4 +161,4 @@ p = Path(\"%\"); \
|
|||||||
realpath = (str(p.parent) + '/' if str(p.parent) != '.' else '') + p.stem + '.mp4'; \
|
realpath = (str(p.parent) + '/' if str(p.parent) != '.' else '') + p.stem + '.mp4'; \
|
||||||
subprocess.run(['mkdir', '-p', to_folder + str(Path(realpath).parent)]); \
|
subprocess.run(['mkdir', '-p', to_folder + str(Path(realpath).parent)]); \
|
||||||
subprocess.run(['ffmpeg', '-i', '%', '-c', 'copy', to_folder + realpath])"
|
subprocess.run(['ffmpeg', '-i', '%', '-c', 'copy', to_folder + realpath])"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -17,9 +17,9 @@
|
|||||||
- [Cleaning up old snapshots](#cleaning-up-old-snapshots)
|
- [Cleaning up old snapshots](#cleaning-up-old-snapshots)
|
||||||
- [Creating and restoring snapshots](#creating-and-restoring-snapshots)
|
- [Creating and restoring snapshots](#creating-and-restoring-snapshots)
|
||||||
- [Filesystem ACLs](#filesystem-acls)
|
- [Filesystem ACLs](#filesystem-acls)
|
||||||
- [ISCSI Backup Volumes](#iscsi-backup-volumes)
|
- [ISCSI](#iscsi)
|
||||||
- [Create Backup ZVOL](#create-backup-zvol)
|
- [Create ZVOL](#create-zvol)
|
||||||
- [Create Backup ISCSI Target](#create-backup-iscsi-target)
|
- [Create ISCSI Target](#create-iscsi-target)
|
||||||
- [VMs](#vms)
|
- [VMs](#vms)
|
||||||
- [Converting zvol to qcow2](#converting-zvol-to-qcow2)
|
- [Converting zvol to qcow2](#converting-zvol-to-qcow2)
|
||||||
- [Converting qcow2 to zvol](#converting-qcow2-to-zvol)
|
- [Converting qcow2 to zvol](#converting-qcow2-to-zvol)
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
- [UPS Monitoring](#ups-monitoring)
|
- [UPS Monitoring](#ups-monitoring)
|
||||||
- [ZFS Size Data](#zfs-size-data)
|
- [ZFS Size Data](#zfs-size-data)
|
||||||
- [ZFS Rename](#zfs-rename)
|
- [ZFS Rename](#zfs-rename)
|
||||||
- [ISCSI](#iscsi)
|
- [ISCSI](#iscsi-1)
|
||||||
- [ISCSI Base Name](#iscsi-base-name)
|
- [ISCSI Base Name](#iscsi-base-name)
|
||||||
- [Archiving](#archiving)
|
- [Archiving](#archiving)
|
||||||
- [Deleting snapshots](#deleting-snapshots)
|
- [Deleting snapshots](#deleting-snapshots)
|
||||||
@@ -247,9 +247,9 @@ Dataset -> Dataset details (edit) -> Advanced Options -> ACL Type (inherit)
|
|||||||
setfacl -b -R /mnt/enc0/smb/media
|
setfacl -b -R /mnt/enc0/smb/media
|
||||||
```
|
```
|
||||||
|
|
||||||
## ISCSI Backup Volumes
|
## ISCSI
|
||||||
|
|
||||||
### Create Backup ZVOL
|
### Create ZVOL
|
||||||
|
|
||||||
1. Create a new dataset called "iscsi" and then a dataset under that called "backups"
|
1. Create a new dataset called "iscsi" and then a dataset under that called "backups"
|
||||||
1. Set sync to always
|
1. Set sync to always
|
||||||
@@ -258,18 +258,22 @@ setfacl -b -R /mnt/enc0/smb/media
|
|||||||
2. Create a new dataset under backups with the same name as your server hostname
|
2. Create a new dataset under backups with the same name as your server hostname
|
||||||
3. Set the size to something reasonable (Note you may need to "force size")
|
3. Set the size to something reasonable (Note you may need to "force size")
|
||||||
|
|
||||||
### Create Backup ISCSI Target
|
### Create ISCSI Target
|
||||||
|
|
||||||
1. In System -> Services -> ISCSI set the Base Name following [these rules](#iscsi-base-name)
|
In Shared -> Block (iSCSI) Shares Targets
|
||||||
2. In Shared -> ISCSI -> Authorized Access -> Create a new authorized access
|
|
||||||
|
1. Global Target Configuration -> Base Name
|
||||||
|
1. set the Base Name following [these rules](#iscsi-base-name)
|
||||||
|
2. Authorized Access -> Add
|
||||||
1. Group ID arbitrary - just pick a number you haven't used
|
1. Group ID arbitrary - just pick a number you haven't used
|
||||||
2. User: The connecting machine's ISCSI Base Name
|
2. Discovery Authentication: Chap
|
||||||
3. Secret: A 16 character password with no special characters
|
3. User: The connecting machine's ISCSI Base Name
|
||||||
3. Wizard -> Create New
|
4. Secret: A 16 character password with no special characters
|
||||||
1. Extent Name: `backup-<hostname>`
|
3. Extents -> Add
|
||||||
2. Extent Type: `Device`
|
1. Name: `some-name`
|
||||||
3. Extent Device: The ZVOL you just created
|
2. Type: `Device`
|
||||||
4. Extent Sharing Platform: `Modern OS`
|
3. Device: The ZVOL you just created
|
||||||
|
4. Sharing Platform: `Modern OS`
|
||||||
5. Protocol Options Portal: Either create new (0.0.0.0 and ::) or select your existing portal
|
5. Protocol Options Portal: Either create new (0.0.0.0 and ::) or select your existing portal
|
||||||
6. Protocol Options Initiators: The base name of the connecting machine following [these rules](#iscsi-base-name)
|
6. Protocol Options Initiators: The base name of the connecting machine following [these rules](#iscsi-base-name)
|
||||||
4. Targets -> Select the backup-<hostname> target -> Edit
|
4. Targets -> Select the backup-<hostname> target -> Edit
|
||||||
|
|||||||
@@ -16,55 +16,7 @@ and the operator will store information about each server.
|
|||||||
|
|
||||||
## Setup SSH
|
## Setup SSH
|
||||||
|
|
||||||
On the operator:
|
See [README](/README.md#ssh-setup)
|
||||||
|
|
||||||
```bash
|
|
||||||
export SSH_HOST=kube
|
|
||||||
ssh-keygen -t rsa -b 4096 -C ducoterra@${SSH_HOST}.reeselink.com -f ~/.ssh/id_${SSH_HOST}_rsa
|
|
||||||
|
|
||||||
# Note: If you get "too many authentication failures" it's likely because you have too many private
|
|
||||||
# keys in your ~/.ssh directory. Use `-o PubkeyAuthentication` to fix it.
|
|
||||||
ssh-copy-id -o PubkeyAuthentication=no -i ~/.ssh/id_${SSH_HOST}_rsa.pub ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
ssh -i ~/.ssh/id_${SSH_HOST}_rsa -o 'PubkeyAuthentication=yes' ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
```
|
|
||||||
|
|
||||||
On the server:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Copy authorized_keys to root
|
|
||||||
sudo cp ~/.ssh/authorized_keys /root/.ssh/authorized_keys
|
|
||||||
|
|
||||||
# Change your password
|
|
||||||
passwd
|
|
||||||
|
|
||||||
sudo su -
|
|
||||||
echo "PasswordAuthentication no" > /etc/ssh/sshd_config.d/01-prohibit-password.conf
|
|
||||||
echo '%sudo ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/01-nopasswd-sudo
|
|
||||||
systemctl restart ssh
|
|
||||||
```
|
|
||||||
|
|
||||||
On the operator:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cat <<EOF >> ~/.ssh/config
|
|
||||||
|
|
||||||
Host $SSH_HOST
|
|
||||||
Hostname ${SSH_HOST}.reeselink.com
|
|
||||||
User root
|
|
||||||
ProxyCommand none
|
|
||||||
ForwardAgent no
|
|
||||||
ForwardX11 no
|
|
||||||
Port 22
|
|
||||||
KeepAlive yes
|
|
||||||
IdentityFile ~/.ssh/id_${SSH_HOST}_rsa
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Test if you can SSH with a password
|
|
||||||
ssh -o PubkeyAuthentication=no ducoterra@${SSH_HOST}.reeselink.com
|
|
||||||
|
|
||||||
# Test that you can log into the server with ssh config
|
|
||||||
ssh $SSH_HOST
|
|
||||||
```
|
|
||||||
|
|
||||||
## Fail2Ban
|
## Fail2Ban
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
# Podman Server
|
|
||||||
|
|
||||||
## Notes
|
|
||||||
|
|
||||||
- create a btrfs subvolume for each user
|
|
||||||
68
active/podman_bricktracker/bricktracker.md
Normal file
68
active/podman_bricktracker/bricktracker.md
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
# Brick Tracker
|
||||||
|
|
||||||
|
<https://gitea.baerentsen.space/FrederikBaerentsen/BrickTracker/src/branch/master/docs/quickstart.md>
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Copy the `.env.sample` from <https://gitea.baerentsen.space/FrederikBaerentsen/BrickTracker/src/branch/master/.env.sample> to `.env`
|
||||||
|
2. Set the following:
|
||||||
|
1. `BK_AUTHENTICATION_PASSWORD`
|
||||||
|
2. `BK_AUTHENTICATION_KEY`
|
||||||
|
3. `BK_DATABASE_PATH`
|
||||||
|
4. `BK_INSTRUCTIONS_FOLDER`
|
||||||
|
5. `BK_MINIFIGURES_FOLDER`
|
||||||
|
6. `BK_PARTS_FOLDER`
|
||||||
|
7. `BK_REBRICKABLE_API_KEY`
|
||||||
|
8. `BK_SETS_FOLDER`
|
||||||
|
3. Create the docker compose yaml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
bricktracker:
|
||||||
|
container_name: BrickTracker
|
||||||
|
restart: unless-stopped
|
||||||
|
image: gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.2.2
|
||||||
|
ports:
|
||||||
|
- "3333:3333"
|
||||||
|
volumes:
|
||||||
|
- ./data:/var/lib/bricktracker
|
||||||
|
- ./static/instructions:/app/static/instructions
|
||||||
|
- ./static/minifigures:/app/static/minifigures
|
||||||
|
- ./static/parts:/app/static/parts
|
||||||
|
- ./static/sets:/app/static/sets
|
||||||
|
env_file: ".env"
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Start the service: `docker compose up -d`
|
||||||
|
|
||||||
|
## Caddy
|
||||||
|
|
||||||
|
1. Create the new DNS record for your website
|
||||||
|
2. Create the Caddyfile at `./Caddyfile`
|
||||||
|
|
||||||
|
```conf
|
||||||
|
https://connors-legos.reeseapps.com:443 {
|
||||||
|
reverse_proxy 127.0.0.1:3333
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Create the Caddy compose.yaml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
caddy:
|
||||||
|
image: caddy:<version>
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
- "443:443/udp"
|
||||||
|
volumes:
|
||||||
|
- ./Caddyfile:/etc/caddy/Caddyfile
|
||||||
|
- caddy_data:/data
|
||||||
|
- caddy_config:/config
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
caddy_data:
|
||||||
|
caddy_config:
|
||||||
|
```
|
||||||
16
active/podman_bricktracker/compose.yaml
Normal file
16
active/podman_bricktracker/compose.yaml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
services:
|
||||||
|
bricktracker:
|
||||||
|
container_name: BrickTracker
|
||||||
|
restart: unless-stopped
|
||||||
|
image: gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.2.2
|
||||||
|
ports:
|
||||||
|
- "3333:3333"
|
||||||
|
volumes:
|
||||||
|
- /home/connorbricktracker/data:/var/lib/bricktracker
|
||||||
|
- /home/connorbricktracker/static/instructions:/app/static/instructions
|
||||||
|
- /home/connorbricktracker/static/minifigures:/app/static/minifigures
|
||||||
|
- /home/connorbricktracker/static/parts:/app/static/parts
|
||||||
|
- /home/connorbricktracker/static/sets:/app/static/sets
|
||||||
|
env_file: "/home/connorbricktracker/.env"
|
||||||
|
security_opt:
|
||||||
|
- label=disable
|
||||||
17
active/podman_bricktracker/quadlets/bricktracker.container
Normal file
17
active/podman_bricktracker/quadlets/bricktracker.container
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
[Container]
|
||||||
|
ContainerName=BrickTracker
|
||||||
|
EnvironmentFile=/home/connorbricktracker/.env
|
||||||
|
Image=gitea.baerentsen.space/frederikbaerentsen/bricktracker:1.2.2
|
||||||
|
PublishPort=3333:3333
|
||||||
|
SecurityLabelDisable=true
|
||||||
|
Volume=/home/connorbricktracker/data:/var/lib/bricktracker
|
||||||
|
Volume=/home/connorbricktracker/static/instructions:/app/static/instructions
|
||||||
|
Volume=/home/connorbricktracker/static/minifigures:/app/static/minifigures
|
||||||
|
Volume=/home/connorbricktracker/static/parts:/app/static/parts
|
||||||
|
Volume=/home/connorbricktracker/static/sets:/app/static/sets
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -1,20 +1,10 @@
|
|||||||
# Caddy Reverse Proxy
|
# Caddy Reverse Proxy
|
||||||
|
|
||||||
- [Caddy Reverse Proxy](#caddy-reverse-proxy)
|
- [Caddy Reverse Proxy](#caddy-reverse-proxy)
|
||||||
- [DNS Records](#dns-records)
|
|
||||||
- [Install Caddy](#install-caddy)
|
- [Install Caddy](#install-caddy)
|
||||||
- [Ansible](#ansible)
|
- [Ansible](#ansible)
|
||||||
- [Manual](#manual)
|
- [Manual](#manual)
|
||||||
|
- [Adding a new Caddy Record](#adding-a-new-caddy-record)
|
||||||
## DNS Records
|
|
||||||
|
|
||||||
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. Run the [caddy ansible playbook](/active/podman_ddns/ddns.md#ansible-caddy-records)
|
|
||||||
|
|
||||||
## Install Caddy
|
## Install Caddy
|
||||||
|
|
||||||
@@ -101,4 +91,15 @@ WantedBy=default.target
|
|||||||
```bash
|
```bash
|
||||||
systemctl daemon-reload
|
systemctl daemon-reload
|
||||||
systemctl restart caddy
|
systemctl restart caddy
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Adding a new Caddy Record
|
||||||
|
|
||||||
|
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_ddns/ddns.md#ansible-caddy-records)
|
||||||
@@ -1,26 +1,32 @@
|
|||||||
# DDNS for Route53
|
# DDNS for Route53
|
||||||
|
|
||||||
- [DDNS for Route53](#ddns-for-route53)
|
- [DDNS for Route53](#ddns-for-route53)
|
||||||
- [Install](#install)
|
- [Quickly Update DDNS Records](#quickly-update-ddns-records)
|
||||||
- [As a Systemd Service](#as-a-systemd-service)
|
- [Install a New DDNS Service](#install-a-new-ddns-service)
|
||||||
- [Ansible Caddy Records](#ansible-caddy-records)
|
- [Ansible 3D Server Records](#ansible-3d-server-records)
|
||||||
- [Ansible Git Record](#ansible-git-record)
|
- [Ansible Podman Record](#ansible-podman-record)
|
||||||
- [Ansible Unifi External Records](#ansible-unifi-external-records)
|
- [Ansible Unifi External Records](#ansible-unifi-external-records)
|
||||||
- [Ansible Hostname reeselink records](#ansible-hostname-reeselink-records)
|
- [Ansible Hostname reeselink records](#ansible-hostname-reeselink-records)
|
||||||
- [Development](#development)
|
- [Development](#development)
|
||||||
- [Testing](#testing)
|
- [Testing](#testing)
|
||||||
- [Building Container Image](#building-container-image)
|
- [Building Container Image](#building-container-image)
|
||||||
|
|
||||||
This service will automatically keep ipv4 and ipv6 records updated in AWS Route53.
|
This service will automatically keep ipv4 and ipv6 records updated in AWS
|
||||||
|
Route53.
|
||||||
|
|
||||||
**NOTE**: This requires the aws cli to be installed on each node with
|
**NOTE**: This requires the aws cli to be installed on each node with
|
||||||
credentials that can modify records in route53. See
|
credentials that can modify records in route53. See
|
||||||
[aws_iam](/active/aws_iam/aws_iam.md) and
|
[aws_iam](/active/aws_iam/aws_iam.md) and [aws_cli](/active/aws_cli/aws_cli.md)
|
||||||
[aws_cli](/active/aws_cli/aws_cli.md)
|
|
||||||
|
|
||||||
## Install
|
## Quickly Update DDNS Records
|
||||||
|
|
||||||
### As a Systemd Service
|
In the event of a record change you can quickly trigger the ddns services with
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl start --all ddns*.service
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install a New DDNS Service
|
||||||
|
|
||||||
You need two files:
|
You need two files:
|
||||||
|
|
||||||
@@ -45,7 +51,12 @@ records:
|
|||||||
hosted_zone_id: ABC123456789
|
hosted_zone_id: ABC123456789
|
||||||
```
|
```
|
||||||
|
|
||||||
Then you can install the ddns service with something like
|
Then you'll need to pick a server responsible for keeping those records
|
||||||
|
updated. Whichever host you run the service on will also be the host which
|
||||||
|
provides the public IP. Choose the host accordingly if it will be updating a
|
||||||
|
public IP on behalf of another server, as the IPv6 address will not be correct.
|
||||||
|
|
||||||
|
Now you can install the DDNS service with something like:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ansible-playbook \
|
ansible-playbook \
|
||||||
@@ -60,27 +71,32 @@ active/podman_ddns/install_ddns.yaml \
|
|||||||
|
|
||||||
See ansible playbook [install_ddns.yaml](/install_ddns.yaml)
|
See ansible playbook [install_ddns.yaml](/install_ddns.yaml)
|
||||||
|
|
||||||
#### Ansible Caddy Records
|
It's recommended that you have multiple secret `foobar-records.yaml` files for
|
||||||
|
multiple servers. If you have a podman server, it'll have its own
|
||||||
|
`podman-records.yaml`. If you have a docker server, it'll have its own
|
||||||
|
`docker-records.yaml`. Etc. etc.
|
||||||
|
|
||||||
|
### Ansible 3D Server Records
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ansible-playbook \
|
ansible-playbook \
|
||||||
-i ansible/inventory.yaml \
|
-i ansible/inventory.yaml \
|
||||||
-l 3dserver \
|
-l 3dserver \
|
||||||
active/podman_ddns/install_ddns.yaml \
|
active/podman_ddns/install_ddns.yaml \
|
||||||
-e "@active/podman_ddns/secrets/caddy_records.yaml"
|
-e "@active/podman_ddns/secrets/3dserver_records.yaml"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Ansible Git Record
|
### Ansible Podman Record
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ansible-playbook \
|
ansible-playbook \
|
||||||
-i ansible/inventory.yaml \
|
-i ansible/inventory.yaml \
|
||||||
-l podman \
|
-l podman \
|
||||||
active/podman_ddns/install_ddns.yaml \
|
active/podman_ddns/install_ddns.yaml \
|
||||||
-e "@active/podman_ddns/secrets/git_record.yaml"
|
-e "@active/podman_ddns/secrets/podman_records.yaml"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Ansible Unifi External Records
|
### Ansible Unifi External Records
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
ansible-playbook \
|
ansible-playbook \
|
||||||
@@ -90,7 +106,7 @@ active/podman_ddns/install_ddns.yaml \
|
|||||||
-e "@active/podman_ddns/secrets/unifi_external_record.yaml"
|
-e "@active/podman_ddns/secrets/unifi_external_record.yaml"
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Ansible Hostname reeselink records
|
### Ansible Hostname reeselink records
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export PLAYBOOK_PATH=active/podman_ddns
|
export PLAYBOOK_PATH=active/podman_ddns
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ services:
|
|||||||
image: docker.gitea.com/gitea:1.24
|
image: docker.gitea.com/gitea:1.24
|
||||||
container_name: gitea
|
container_name: gitea
|
||||||
environment:
|
environment:
|
||||||
- USER_UID=1000
|
|
||||||
- USER_GID=1000
|
|
||||||
- GITEA__database__DB_TYPE=postgres
|
- GITEA__database__DB_TYPE=postgres
|
||||||
- GITEA__database__HOST=postgres:5432
|
- GITEA__database__HOST=postgres:5432
|
||||||
- GITEA__database__NAME=gitea
|
- GITEA__database__NAME=gitea
|
||||||
@@ -16,15 +14,13 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- gitea
|
- gitea
|
||||||
volumes:
|
volumes:
|
||||||
- /home/gitea/gitea_data:/data
|
- /home/gitea/gitea_data:/data:Z
|
||||||
- /etc/localtime:/etc/localtime:ro
|
- /etc/localtime:/etc/localtime:ro
|
||||||
ports:
|
ports:
|
||||||
- "3000:3000"
|
- "3000:3000"
|
||||||
- "2222:2222"
|
- "2222:2222"
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
security_opt:
|
|
||||||
- label=disable
|
|
||||||
labels:
|
labels:
|
||||||
- "io.containers.autoupdate=registry"
|
- "io.containers.autoupdate=registry"
|
||||||
|
|
||||||
@@ -39,9 +35,9 @@ services:
|
|||||||
networks:
|
networks:
|
||||||
- gitea
|
- gitea
|
||||||
volumes:
|
volumes:
|
||||||
- /home/gitea/gitea_postgres:/var/lib/postgresql/data
|
- /home/gitea/gitea_postgres:/var/lib/postgresql/data:Z
|
||||||
security_opt:
|
labels:
|
||||||
- label=disable
|
- "io.containers.autoupdate=registry"
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
gitea:
|
gitea:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
- [Gitea](#gitea)
|
- [Gitea](#gitea)
|
||||||
- [Gitea on Rootless Podman](#gitea-on-rootless-podman)
|
- [Gitea on Rootless Podman](#gitea-on-rootless-podman)
|
||||||
|
- [A note on directories](#a-note-on-directories)
|
||||||
- [Create the gitea user](#create-the-gitea-user)
|
- [Create the gitea user](#create-the-gitea-user)
|
||||||
- [Convert Compose to Quadlet](#convert-compose-to-quadlet)
|
- [Convert Compose to Quadlet](#convert-compose-to-quadlet)
|
||||||
- [Install Quadlets](#install-quadlets)
|
- [Install Quadlets](#install-quadlets)
|
||||||
@@ -15,6 +16,18 @@
|
|||||||
|
|
||||||
## Gitea on Rootless Podman
|
## Gitea on Rootless Podman
|
||||||
|
|
||||||
|
### A note on directories
|
||||||
|
|
||||||
|
```bash
|
||||||
|
RunMode: prod
|
||||||
|
AppPath: /usr/local/bin/gitea
|
||||||
|
WorkPath: /data/gitea
|
||||||
|
CustomPath: /data/gitea
|
||||||
|
ConfigFile: /data/gitea/conf/app.ini
|
||||||
|
|
||||||
|
Data: /data/gitea/data/
|
||||||
|
```
|
||||||
|
|
||||||
### Create the gitea user
|
### Create the gitea user
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
@@ -4,13 +4,11 @@ Requires=postgres.service
|
|||||||
[Container]
|
[Container]
|
||||||
AutoUpdate=registry
|
AutoUpdate=registry
|
||||||
ContainerName=gitea
|
ContainerName=gitea
|
||||||
Environment=USER_UID=1000 USER_GID=1000 GITEA__database__DB_TYPE=postgres GITEA__database__HOST=postgres:5432 GITEA__database__NAME=gitea GITEA__database__USER=gitea GITEA__database__PASSWD=gitea
|
|
||||||
Image=docker.gitea.com/gitea:1.24
|
Image=docker.gitea.com/gitea:1.24
|
||||||
Network=gitea.network
|
Network=gitea.network
|
||||||
PublishPort=3000:3000
|
PublishPort=3000:3000
|
||||||
PublishPort=2222:2222
|
PublishPort=2222:2222
|
||||||
SecurityLabelDisable=true
|
Volume=/home/gitea/gitea_data:/data:Z
|
||||||
Volume=/home/gitea/gitea_data:/data
|
|
||||||
Volume=/etc/localtime:/etc/localtime:ro
|
Volume=/etc/localtime:/etc/localtime:ro
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
[Container]
|
[Container]
|
||||||
|
AutoUpdate=registry
|
||||||
ContainerName=postgres
|
ContainerName=postgres
|
||||||
Environment=POSTGRES_USER=gitea POSTGRES_PASSWORD=gitea POSTGRES_DB=gitea
|
Environment=POSTGRES_USER=gitea POSTGRES_PASSWORD=gitea POSTGRES_DB=gitea
|
||||||
Image=docker.io/library/postgres:15
|
Image=docker.io/library/postgres:15
|
||||||
Network=gitea.network
|
Network=gitea.network
|
||||||
SecurityLabelDisable=true
|
Volume=/home/gitea/gitea_postgres:/var/lib/postgresql/data:Z
|
||||||
Volume=/home/gitea/gitea_postgres:/var/lib/postgresql/data
|
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Restart=always
|
Restart=always
|
||||||
|
|||||||
31
active/podman_minecraft/compose.yaml
Normal file
31
active/podman_minecraft/compose.yaml
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
services:
|
||||||
|
testcraft:
|
||||||
|
image: gitea.reeseapps.com/services/minecraft:c1ca80b09b4645888e550efb0a2700b2ec1f1645
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- /home/minecraft/testcraft:/mc_data
|
||||||
|
ports:
|
||||||
|
- 25565:25565
|
||||||
|
environment:
|
||||||
|
- MAX_RAM=4
|
||||||
|
- MIN_RAM=1
|
||||||
|
security_opt:
|
||||||
|
- "label=disable"
|
||||||
|
userns_mode: keep-id
|
||||||
|
restart: always
|
||||||
|
nimcraft:
|
||||||
|
image: gitea.reeseapps.com/services/minecraft:c1ca80b09b4645888e550efb0a2700b2ec1f1645
|
||||||
|
stdin_open: true
|
||||||
|
tty: true
|
||||||
|
volumes:
|
||||||
|
- /home/minecraft/nimcraft:/mc_data
|
||||||
|
ports:
|
||||||
|
- 25566:25565
|
||||||
|
environment:
|
||||||
|
- MAX_RAM=4
|
||||||
|
- MIN_RAM=1
|
||||||
|
security_opt:
|
||||||
|
- "label=disable"
|
||||||
|
userns_mode: keep-id
|
||||||
|
restart: always
|
||||||
108
active/podman_minecraft/minecraft.md
Normal file
108
active/podman_minecraft/minecraft.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
# Podman Template
|
||||||
|
|
||||||
|
- [Podman Template](#podman-template)
|
||||||
|
- [Install minecraft](#install-minecraft)
|
||||||
|
- [Create the minecraft user](#create-the-minecraft-user)
|
||||||
|
- [Convert Compose to Quadlet](#convert-compose-to-quadlet)
|
||||||
|
- [Install Quadlets](#install-quadlets)
|
||||||
|
- [Upgrade Quadlets](#upgrade-quadlets)
|
||||||
|
- [Expose minecraft](#expose-minecraft)
|
||||||
|
- [Backup minecraft](#backup-minecraft)
|
||||||
|
|
||||||
|
## Install minecraft
|
||||||
|
|
||||||
|
Find and replace minecraft with the name of the service.
|
||||||
|
|
||||||
|
### Create the minecraft user
|
||||||
|
|
||||||
|
```bash
|
||||||
|
useradd minecraft
|
||||||
|
|
||||||
|
su - minecraft
|
||||||
|
ssh-keygen
|
||||||
|
exit
|
||||||
|
cp ~/.ssh/authorized_keys /home/minecraft/.ssh/authorized_keys
|
||||||
|
chown minecraft:minecraft /home/minecraft/.ssh/authorized_keys
|
||||||
|
loginctl enable-linger $(id -u minecraft)
|
||||||
|
```
|
||||||
|
|
||||||
|
SSH into the server as minecraft
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl --user enable podman-restart
|
||||||
|
systemctl --user enable --now podman.socket
|
||||||
|
mkdir -p ~/.config/containers/systemd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Convert Compose to Quadlet
|
||||||
|
|
||||||
|
Create a folder called `quadlets` in your podman_minecraft project.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate the systemd service
|
||||||
|
podman run \
|
||||||
|
--security-opt label=disable \
|
||||||
|
--rm \
|
||||||
|
-v $(pwd)/active/podman_minecraft:/compose \
|
||||||
|
-v $(pwd)/active/podman_minecraft/quadlets:/quadlets \
|
||||||
|
quay.io/k9withabone/podlet \
|
||||||
|
-f /quadlets \
|
||||||
|
-i \
|
||||||
|
--overwrite \
|
||||||
|
compose /compose/compose.yaml
|
||||||
|
|
||||||
|
# Copy the files to the server
|
||||||
|
scp -r active/podman_minecraft/quadlets/. minecraft:~/.config/containers/systemd/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install Quadlets
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh minecraft
|
||||||
|
|
||||||
|
export GAME_SERVER_NAME=testcraft
|
||||||
|
mkdir $GAME_SERVER_NAME
|
||||||
|
|
||||||
|
# Download the server jar (only needed once)
|
||||||
|
podman run \
|
||||||
|
-it \
|
||||||
|
--rm \
|
||||||
|
-e SERVER_VERSION=1.21.8 \
|
||||||
|
-v $(pwd)/$GAME_SERVER_NAME:/downloads \
|
||||||
|
--security-opt label=disable \
|
||||||
|
--userns keep-id \
|
||||||
|
docker.io/ducoterra/get-minecraft:latest
|
||||||
|
|
||||||
|
systemctl --user daemon-reload
|
||||||
|
systemctl --user restart $GAME_SERVER_NAME
|
||||||
|
```
|
||||||
|
|
||||||
|
### Upgrade Quadlets
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scp -r quadlets/. minecraft:~/.config/containers/systemd/
|
||||||
|
ssh minecraft systemctl --user daemon-reload
|
||||||
|
ssh minecraft systemctl --user restart minecraft
|
||||||
|
```
|
||||||
|
|
||||||
|
## Expose minecraft
|
||||||
|
|
||||||
|
1. Create your minecraft ddns record first [following these docs](/active/podman_ddns/ddns.md#)
|
||||||
|
2. Create a SRV record in your DNS provider like the following:
|
||||||
|
|
||||||
|
| Field | Value |
|
||||||
|
| ----------- | -------------------------------------- |
|
||||||
|
| Record name | _minecraft._tcp.testcraft.reeseapps.com |
|
||||||
|
| Value | 0 5 25566 minecraft.reeseapps.com |
|
||||||
|
|
||||||
|
3. Test your record with `nslookup`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nslookup -q=srv _minecraft._tcp.testcraft.reeseapps.com
|
||||||
|
```
|
||||||
|
|
||||||
|
4. Access your server at your domain "testcraft.reeseapps.com"
|
||||||
|
|
||||||
|
## Backup minecraft
|
||||||
|
|
||||||
|
Follow the Borg [Create a Backup Service Docs](/active/systemd_borg/borg.md#create-a-backup-service)
|
||||||
14
active/podman_minecraft/quadlets/nimcraft.container
Normal file
14
active/podman_minecraft/quadlets/nimcraft.container
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[Container]
|
||||||
|
Environment=MAX_RAM=4 MIN_RAM=1
|
||||||
|
Image=gitea.reeseapps.com/services/minecraft:c1ca80b09b4645888e550efb0a2700b2ec1f1645
|
||||||
|
PodmanArgs=--interactive --tty
|
||||||
|
PublishPort=25566:25565
|
||||||
|
SecurityLabelDisable=true
|
||||||
|
UserNS=keep-id
|
||||||
|
Volume=/home/minecraft/nimcraft:/mc_data
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
14
active/podman_minecraft/quadlets/testcraft.container
Normal file
14
active/podman_minecraft/quadlets/testcraft.container
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[Container]
|
||||||
|
Environment=MAX_RAM=4 MIN_RAM=1
|
||||||
|
Image=gitea.reeseapps.com/services/minecraft:c1ca80b09b4645888e550efb0a2700b2ec1f1645
|
||||||
|
PodmanArgs=--interactive --tty
|
||||||
|
PublishPort=25565:25565
|
||||||
|
SecurityLabelDisable=true
|
||||||
|
UserNS=keep-id
|
||||||
|
Volume=/home/minecraft/testcraft:/mc_data
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Nextcloud AIO Master Container
|
||||||
|
Documentation=https://github.com/nextcloud/all-in-one/blob/main/docker-rootless.md
|
||||||
|
After=local-fs.target
|
||||||
|
Requires=podman.socket
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
ContainerName=nextcloud-aio-mastercontainer
|
||||||
|
Image=docker.io/nextcloud/all-in-one:latest
|
||||||
|
PublishPort=0.0.0.0:11001:8080
|
||||||
|
Volume=nextcloud_aio_mastercontainer:/mnt/docker-aio-config
|
||||||
|
Volume=/run/user/1001/podman/podman.sock:/var/run/docker.sock:Z
|
||||||
|
Network=bridge
|
||||||
|
SecurityLabelDisable=true
|
||||||
|
|
||||||
|
Environment=APACHE_PORT=11000
|
||||||
|
Environment=APACHE_IP_BINDING=0.0.0.0
|
||||||
|
Environment=WATCHTOWER_DOCKER_SOCKET_PATH=/run/user/1001/podman/podman.sock
|
||||||
|
Environment=NEXTCLOUD_DATADIR="/home/nextcloud/nextcloud_data"
|
||||||
|
Environment=SKIP_DOMAIN_VALIDATION=true
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=always
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target default.target
|
||||||
@@ -55,7 +55,9 @@ systemctl --user enable --now podman.socket
|
|||||||
|
|
||||||
### Create the container autostart service
|
### Create the container autostart service
|
||||||
|
|
||||||
As the nextcloud user.
|
Edit the autostart service to include "unless-stopped" containers.
|
||||||
|
|
||||||
|
As the nextcloud user:
|
||||||
|
|
||||||
`systemctl --user edit podman-restart.service`
|
`systemctl --user edit podman-restart.service`
|
||||||
|
|
||||||
@@ -63,7 +65,6 @@ As the nextcloud user.
|
|||||||
[Service]
|
[Service]
|
||||||
ExecStart=
|
ExecStart=
|
||||||
ExecStart=/usr/bin/podman $LOGGING start --all --filter restart-policy=always --filter restart-policy=unless-stopped
|
ExecStart=/usr/bin/podman $LOGGING start --all --filter restart-policy=always --filter restart-policy=unless-stopped
|
||||||
ExecStop=
|
|
||||||
ExecStop=/bin/sh -c '/usr/bin/podman $LOGGING stop $(/usr/bin/podman container ls --filter restart-policy=always --filter restart-policy=unless-stopped -q)'
|
ExecStop=/bin/sh -c '/usr/bin/podman $LOGGING stop $(/usr/bin/podman container ls --filter restart-policy=always --filter restart-policy=unless-stopped -q)'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -73,42 +74,21 @@ systemctl --user daemon-reload
|
|||||||
|
|
||||||
### Install Nextcloud
|
### Install Nextcloud
|
||||||
|
|
||||||
`mkdir -p ~/.config/containers/systemd`
|
|
||||||
|
|
||||||
`vim ~/.config/containers/systemd/nextcloud-aio-mastercontainer.container`
|
|
||||||
|
|
||||||
```conf
|
|
||||||
[Unit]
|
|
||||||
Description=Nextcloud AIO Master Container
|
|
||||||
Documentation=https://github.com/nextcloud/all-in-one/blob/main/docker-rootless.md
|
|
||||||
After=local-fs.target
|
|
||||||
Requires=podman.socket
|
|
||||||
|
|
||||||
[Container]
|
|
||||||
ContainerName=nextcloud-aio-mastercontainer
|
|
||||||
Image=docker.io/nextcloud/all-in-one:latest
|
|
||||||
PublishPort=0.0.0.0:11001:8080
|
|
||||||
Volume=nextcloud_aio_mastercontainer:/mnt/docker-aio-config
|
|
||||||
Volume=/run/user/1001/podman/podman.sock:/var/run/docker.sock:Z
|
|
||||||
Network=bridge
|
|
||||||
SecurityLabelDisable=true
|
|
||||||
|
|
||||||
Environment=APACHE_PORT=11000
|
|
||||||
Environment=APACHE_IP_BINDING=0.0.0.0
|
|
||||||
Environment=WATCHTOWER_DOCKER_SOCKET_PATH=/run/user/1001/podman/podman.sock
|
|
||||||
Environment=NEXTCLOUD_DATADIR="/home/nextcloud/nextcloud_data"
|
|
||||||
Environment=SKIP_DOMAIN_VALIDATION=true
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
Restart=always
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target default.target
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
systemctl --user daemon-reload
|
# Make the container systemd directory (if needed)
|
||||||
systemctl --user start nextcloud-aio-mastercontainer
|
ssh nextcloud mkdir -p ~/.config/containers/systemd
|
||||||
|
|
||||||
|
# Create the nextcloud network with ipv6
|
||||||
|
ssh nextcloud podman network create --ipv6 nextcloud-aio
|
||||||
|
|
||||||
|
# Copy the quadlet files
|
||||||
|
scp \
|
||||||
|
active/podman_nextcloud/nextcloud-aio-mastercontainer.container \
|
||||||
|
nextcloud:.config/containers/systemd/
|
||||||
|
|
||||||
|
# Reload and restart the service
|
||||||
|
ssh nextcloud systemctl --user daemon-reload
|
||||||
|
ssh nextcloud systemctl --user restart nextcloud-aio-mastercontainer
|
||||||
```
|
```
|
||||||
|
|
||||||
### Install Caddy
|
### Install Caddy
|
||||||
@@ -167,7 +147,6 @@ systemctl daemon-reload
|
|||||||
systemctl start caddy
|
systemctl start caddy
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Firewall
|
### Firewall
|
||||||
|
|
||||||
Allow traffic to 11000 from your reverse proxy
|
Allow traffic to 11000 from your reverse proxy
|
||||||
|
|||||||
@@ -51,4 +51,4 @@ Compile and flash.
|
|||||||
{+KC_ENT}{-KC_ENT}{1000}
|
{+KC_ENT}{-KC_ENT}{1000}
|
||||||
// full screen
|
// full screen
|
||||||
{+KC_LGUI}{+KC_PGUP}{-KC_PGUP}{-KC_LGUI}
|
{+KC_LGUI}{+KC_PGUP}{-KC_PGUP}{-KC_LGUI}
|
||||||
```
|
```
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Runs backup script for {{ repo_name }}
|
||||||
|
After=network.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=no
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/script/backup-{{ repo_name }}.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -33,6 +33,7 @@ borg create \
|
|||||||
--exclude-caches \
|
--exclude-caches \
|
||||||
--exclude 'home/*/.cache/*' \
|
--exclude 'home/*/.cache/*' \
|
||||||
--exclude 'var/tmp/*' \
|
--exclude 'var/tmp/*' \
|
||||||
|
--exclude 'home/*/.snapshots/*' \
|
||||||
{% for dir in exclude_dirs %}
|
{% for dir in exclude_dirs %}
|
||||||
--exclude '{{ dir }}' \
|
--exclude '{{ dir }}' \
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=Run Backup backup_{{ repo_name }}.service every hour
|
Description=Run Backup backup-{{ repo_name }}.service every day
|
||||||
|
|
||||||
[Timer]
|
[Timer]
|
||||||
OnCalendar=hourly
|
OnCalendar=*-*-* 2:00:00
|
||||||
AccuracySec=10min
|
AccuracySec=10min
|
||||||
Persistent=true
|
Persistent=true
|
||||||
Unit=ddns.{{ item.record }}.service
|
Unit=backup-{{ repo_name }}.service
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=timers.target
|
WantedBy=timers.target
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
# Borg Backup
|
# Borg Backup
|
||||||
|
|
||||||
- [Borg Backup](#borg-backup)
|
- [Borg Backup](#borg-backup)
|
||||||
- [Server Setup](#server-setup)
|
- [Install Borg](#install-borg)
|
||||||
- [Adding a Client](#adding-a-client)
|
- [Set up a new root client](#set-up-a-new-root-client)
|
||||||
- [Installing the Backup Service](#installing-the-backup-service)
|
- [Create a Backup Service](#create-a-backup-service)
|
||||||
- [Adding Nextcloud](#adding-nextcloud)
|
- [Check backup service logs](#check-backup-service-logs)
|
||||||
- [Manual Client Use](#manual-client-use)
|
- [Run a Manual Backup](#run-a-manual-backup)
|
||||||
|
- [Back up and Entire System](#back-up-and-entire-system)
|
||||||
|
|
||||||
## Server Setup
|
## Install Borg
|
||||||
|
|
||||||
<https://borgbackup.readthedocs.io/en/stable/deployment/central-backup-server.html#user-and-group>
|
<https://borgbackup.readthedocs.io/en/stable/deployment/central-backup-server.html#user-and-group>
|
||||||
|
|
||||||
@@ -28,14 +29,16 @@ touch /home/backup/.ssh/authorized_keys
|
|||||||
chown -R backup:backup /home/backup/.ssh
|
chown -R backup:backup /home/backup/.ssh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Adding a Client
|
## Set up a new root client
|
||||||
|
|
||||||
Note: See [adding nextcloud](#adding-nextcloud) for nextcloud instructions here.
|
Backups will be run as the root user. Generate them an SSH key to
|
||||||
|
|
||||||
|
On the server as root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export BACKUP_HOST=""
|
export BACKUP_HOST="borg.reeselink.com"
|
||||||
|
|
||||||
ssh-keygen -C ${USER}@${HOSTNAME} -f ~/.ssh/id_${BACKUP_HOST}
|
ssh-keygen -C root@${HOSTNAME} -f ~/.ssh/id_${BACKUP_HOST}
|
||||||
|
|
||||||
cat <<EOF >> ~/.ssh/config
|
cat <<EOF >> ~/.ssh/config
|
||||||
Host ${BACKUP_HOST}
|
Host ${BACKUP_HOST}
|
||||||
@@ -43,39 +46,20 @@ Host ${BACKUP_HOST}
|
|||||||
IdentityFile ~/.ssh/id_${BACKUP_HOST}
|
IdentityFile ~/.ssh/id_${BACKUP_HOST}
|
||||||
User backup
|
User backup
|
||||||
Port 22
|
Port 22
|
||||||
KeepAlive yes
|
|
||||||
EOF
|
EOF
|
||||||
```
|
```
|
||||||
|
|
||||||
Now on the server:
|
Now on borg.reeselink.com as root:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
export CLIENT_FQDN=""
|
export CLIENT_FQDN="fqdn.reeseapps.com"
|
||||||
# Should look like ssh-rsa abcd1234 backup@fqdn.something.com
|
export SSH_PUBKEY="ssh-rsa abcd1234 backup@fqdn.something.com"
|
||||||
export SSH_PUBKEY=""
|
export BORG_COMMAND="cd /home/backup/repos/${CLIENT_FQDN}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_FQDN}"
|
||||||
export AUTHKEY_ENTRY="command=\"cd /home/backup/repos/${CLIENT_FQDN}; borg serve --restrict-to-path /home/backup/repos/${CLIENT_FQDN}\",restrict ${SSH_PUBKEY}"
|
export AUTHKEY_ENTRY="command=\"${BORG_COMMAND}\",restrict ${SSH_PUBKEY}"
|
||||||
echo $AUTHKEY_ENTRY >> /home/backup/.ssh/authorized_keys
|
echo $AUTHKEY_ENTRY >> /home/backup/.ssh/authorized_keys
|
||||||
|
|
||||||
mkdir /home/backup/repos/${CLIENT_FQDN}
|
|
||||||
chown backup:backup /home/backup/repos/${CLIENT_FQDN}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then back on the client:
|
## Create a Backup Service
|
||||||
|
|
||||||
```bash
|
|
||||||
ssh borg.reeselink.com
|
|
||||||
|
|
||||||
# root
|
|
||||||
borg init --encryption none backup@${BACKUP_HOST}:root
|
|
||||||
# home
|
|
||||||
borg init --encryption none backup@${BACKUP_HOST}:home
|
|
||||||
# app
|
|
||||||
borg init --encryption none backup@${BACKUP_HOST}:gitea
|
|
||||||
# another app
|
|
||||||
borg init --encryption none backup@${BACKUP_HOST}:nextcloud
|
|
||||||
```
|
|
||||||
|
|
||||||
### Installing the Backup Service
|
|
||||||
|
|
||||||
Create your vars file in `secrets/host_vars.yaml`
|
Create your vars file in `secrets/host_vars.yaml`
|
||||||
|
|
||||||
@@ -97,30 +81,29 @@ stop_user_services:
|
|||||||
```
|
```
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
# Update all existing backup services for podman
|
||||||
|
for var_file in $(ls active/systemd_borg/secrets); do
|
||||||
ansible-playbook \
|
ansible-playbook \
|
||||||
-i active/ansible/inventory.yaml \
|
-i ansible/inventory.yaml \
|
||||||
-l podman \
|
-l podman \
|
||||||
active/systemd_borg/install_backup.yaml \
|
active/systemd_borg/install_backup.yaml \
|
||||||
-e "@active/systemd_borg/secrets/gitea_vars.yaml"
|
-e "@active/systemd_borg/secrets/$var_file"
|
||||||
|
done
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Adding Nextcloud
|
## Check backup service logs
|
||||||
|
|
||||||
Rather than creating a client, just set the borg backup location to:
|
```bash
|
||||||
|
ssh podman journalctl -u 'backup-*' -f
|
||||||
```text
|
|
||||||
backup@borg.reeselink.com:nextcloud
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Then run the backup. It will generate a pubkey. Copy this into the authorized_keys file.
|
## Run a Manual Backup
|
||||||
|
|
||||||
## Manual Client Use
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
borg list borg.reeselink.com:home
|
borg list borg.reeselink.com:home
|
||||||
|
|
||||||
# Do not include the first / in the path
|
# Do not include the first / in the path
|
||||||
export PATH_TO_BACKUP=var/home/ducoterra
|
export PATH_TO_BACKUP=home/ducoterra
|
||||||
export BORG_REPO=borg.reeselink.com:home
|
export BORG_REPO=borg.reeselink.com:home
|
||||||
|
|
||||||
# If not initialized, do that now
|
# If not initialized, do that now
|
||||||
@@ -148,6 +131,10 @@ borg create \
|
|||||||
-e "pp:/${PATH_TO_BACKUP}/.config/libvirt" \
|
-e "pp:/${PATH_TO_BACKUP}/.config/libvirt" \
|
||||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/containers" \
|
-e "pp:/${PATH_TO_BACKUP}/.local/share/containers" \
|
||||||
-e "pp:/${PATH_TO_BACKUP}/.local/share/docker" \
|
-e "pp:/${PATH_TO_BACKUP}/.local/share/docker" \
|
||||||
|
-e "pp:/${PATH_TO_BACKUP}/.npm" \
|
||||||
|
-e "pp:/${PATH_TO_BACKUP}/.ollama" \
|
||||||
|
-e "pp:/${PATH_TO_BACKUP}/Downloads" \
|
||||||
|
-e "pp:/${PATH_TO_BACKUP}/Nextcloud" \
|
||||||
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
|
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
|
||||||
/${PATH_TO_BACKUP}
|
/${PATH_TO_BACKUP}
|
||||||
|
|
||||||
@@ -156,4 +143,31 @@ borg mount $BORG_REPO::2025-05-14-00-44-05 /mnt/
|
|||||||
|
|
||||||
# Restore a borg archive to a location (dry run)
|
# Restore a borg archive to a location (dry run)
|
||||||
borg extract --dry-run --list --strip-components 1 $BORG_REPO::my-files home/USERNAME
|
borg extract --dry-run --list --strip-components 1 $BORG_REPO::my-files home/USERNAME
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Back up and Entire System
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export BORG_REPO=borg.reeselink.com:root
|
||||||
|
|
||||||
|
borg create \
|
||||||
|
--verbose \
|
||||||
|
--filter AME \
|
||||||
|
--list \
|
||||||
|
--stats \
|
||||||
|
--progress \
|
||||||
|
--show-rc \
|
||||||
|
--compression lz4 \
|
||||||
|
--exclude root/.cache \
|
||||||
|
--exclude var/lib/docker \
|
||||||
|
--exclude var/lib/containers \
|
||||||
|
--exclude usr/share/ollama \
|
||||||
|
--exclude home \
|
||||||
|
--exclude proc \
|
||||||
|
--exclude dev \
|
||||||
|
--exclude sys \
|
||||||
|
--exclude tmp \
|
||||||
|
--exclude .snapshots \
|
||||||
|
${BORG_REPO}::$(date +"%F-%H-%M-%S") \
|
||||||
|
/
|
||||||
|
```
|
||||||
|
|||||||
@@ -8,36 +8,32 @@
|
|||||||
path: /usr/local/script
|
path: /usr/local/script
|
||||||
state: directory
|
state: directory
|
||||||
mode: '0755'
|
mode: '0755'
|
||||||
- name: Copy backup.service
|
- name: Copy backup-{{ repo_name }}.service
|
||||||
template:
|
template:
|
||||||
src: backup.service
|
src: backup.service
|
||||||
dest: /etc/systemd/system/backup-{{ repo_name }}.service
|
dest: /etc/systemd/system/backup-{{ repo_name }}.service
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
- name: Copy backup.timer
|
- name: Copy backup-{{ repo_name }}.timer
|
||||||
template:
|
template:
|
||||||
src: backup.timer
|
src: backup.timer
|
||||||
dest: /etc/systemd/system/backup-{{ repo_name }}.timer
|
dest: /etc/systemd/system/backup-{{ repo_name }}.timer
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
- name: Template backup.sh
|
- name: Template backup-{{ repo_name }}.sh
|
||||||
template:
|
template:
|
||||||
src: backup.sh.j2
|
src: backup.sh.j2
|
||||||
dest: /usr/local/script/backup-{{ repo_name }}.sh
|
dest: /usr/local/script/backup-{{ repo_name }}.sh
|
||||||
owner: root
|
owner: root
|
||||||
group: root
|
group: root
|
||||||
mode: '0744'
|
mode: '0744'
|
||||||
# - name: Reload ddns timer
|
- name: Initialize Repo {{ borg_user }}@{{ borg_host }}:{{ repo_name }}
|
||||||
# ansible.builtin.systemd_service:
|
script: /usr/bin/borg init -e none {{ borg_user }}@{{ borg_host }}:{{ repo_name }}
|
||||||
# state: restarted
|
ignore_errors: yes
|
||||||
# name: ddns.{{ item.record }}.timer
|
- name: Reload backup timer backup-{{ repo_name }}.timer
|
||||||
# enabled: true
|
ansible.builtin.systemd_service:
|
||||||
# daemon_reload: true
|
name: backup-{{ repo_name }}.timer
|
||||||
# loop: "{{ records }}"
|
enabled: true
|
||||||
# - name: Run ddns service
|
daemon_reload: true
|
||||||
# ansible.builtin.systemd_service:
|
|
||||||
# state: restarted
|
|
||||||
# name: ddns.{{ item.record }}.service
|
|
||||||
# loop: "{{ records }}"
|
|
||||||
|
|||||||
8
active/systemd_wireguard/Dockerfile
Normal file
8
active/systemd_wireguard/Dockerfile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
RUN apk add -U wireguard-tools
|
||||||
|
COPY wg0.conf /etc/wireguard/wg0.conf
|
||||||
|
|
||||||
|
CMD wg-quick up wg0 && \
|
||||||
|
wg set wg0 peer 'lvghTtIHSXzOfpruVHtRnnAiZJeUi8A6lzhE21GSJjA=' allowed-ips 10.10.0.2/32 && \
|
||||||
|
watch -n 1 wg
|
||||||
35
active/systemd_wireguard/install.sh
Executable file
35
active/systemd_wireguard/install.sh
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
# TODO
|
||||||
|
# 1. Ask for listen port
|
||||||
|
# 2. Ask for name of eth interface
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
apt-get upgrade -y
|
||||||
|
apt-get install -y raspberrypi-kernel-headers
|
||||||
|
apt install -y wireguard qrencode iptables
|
||||||
|
|
||||||
|
cat > /etc/sysctl.conf <<EOF
|
||||||
|
net.ipv4.ip_forward=1
|
||||||
|
net.ipv6.conf.all.forwarding=1
|
||||||
|
EOF
|
||||||
|
|
||||||
|
reboot
|
||||||
|
|
||||||
|
cd /etc/wireguard
|
||||||
|
umask 077
|
||||||
|
export PRIVKEY=$(wg genkey)
|
||||||
|
echo $PRIVKEY | tee privatekey | wg pubkey | tee publickey
|
||||||
|
echo $PRIVKEY | tee --append /etc/wireguard/wg0.conf
|
||||||
|
cat > /etc/wireguard/wg0.conf <<EOF
|
||||||
|
[Interface]
|
||||||
|
Address = 10.10.0.1/24
|
||||||
|
Address = fd86:ea04:1111::1/64
|
||||||
|
SaveConfig = true
|
||||||
|
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
|
||||||
|
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
|
||||||
|
ListenPort = 51820
|
||||||
|
PrivateKey = $PRIVKEY
|
||||||
|
EOF
|
||||||
|
|
||||||
|
sysctl -p
|
||||||
|
wg-quick up wg0
|
||||||
|
wg
|
||||||
28
active/systemd_wireguard/install_wireguard.yaml
Normal file
28
active/systemd_wireguard/install_wireguard.yaml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
- name: Create Backup Service
|
||||||
|
hosts: all
|
||||||
|
vars_files:
|
||||||
|
- secrets/vars.yaml
|
||||||
|
tasks:
|
||||||
|
- name: Install the latest version of Wireguard Tools
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: wireguard-tools
|
||||||
|
state: latest
|
||||||
|
- name: Create wg0.conf
|
||||||
|
template:
|
||||||
|
dest: /etc/wireguard/wg0.conf
|
||||||
|
src: wg0.conf.j2
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0600'
|
||||||
|
- name: enable and persist ip forwarding
|
||||||
|
sysctl:
|
||||||
|
name: net.ipv4.ip_forward
|
||||||
|
value: "1"
|
||||||
|
state: present
|
||||||
|
sysctl_set: yes
|
||||||
|
reload: yes
|
||||||
|
- name: start wireguard and enable on boot
|
||||||
|
systemd:
|
||||||
|
name: wg-quick@wg0
|
||||||
|
enabled: yes
|
||||||
|
state: started
|
||||||
47
active/systemd_wireguard/newclient.sh
Executable file
47
active/systemd_wireguard/newclient.sh
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
# TODO
|
||||||
|
# 1. Read server pubkey from file
|
||||||
|
|
||||||
|
wg
|
||||||
|
|
||||||
|
echo -n 'Client Name: '
|
||||||
|
read name
|
||||||
|
echo -n 'Last digit of client IP \(10.10.0.?\): '
|
||||||
|
read ip
|
||||||
|
echo -n 'Server PubKey: '
|
||||||
|
read server_pubkey
|
||||||
|
|
||||||
|
mkdir $name
|
||||||
|
cd $name
|
||||||
|
export PRIVKEY=$(wg genkey)
|
||||||
|
echo $PRIVKEY | tee $name"_privkey"
|
||||||
|
export PUBKEY=$(echo $PRIVKEY | wg pubkey)
|
||||||
|
echo $PUBKEY | tee $name"_pubkey"
|
||||||
|
|
||||||
|
cat > $name".conf" <<EOF
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = $PRIVKEY
|
||||||
|
Address = 10.10.0.$ip/32, fd86:ea04:1111::$ip/128
|
||||||
|
DNS = 10.10.0.1
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $server_pubkey
|
||||||
|
Endpoint = wireguard.reeseapps.com:51820
|
||||||
|
AllowedIPs = 0.0.0.0/0, ::/0
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat >> /etc/wireguard/wg0.conf <<EOF
|
||||||
|
|
||||||
|
# $name
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $PUBKEY
|
||||||
|
AllowedIPs = 10.10.0.$ip/32
|
||||||
|
EOF
|
||||||
|
|
||||||
|
wg set wg0 peer $PUBKEY allowed-ips 10.10.0.$ip/32
|
||||||
|
|
||||||
|
qrencode -t ansiutf8 < $name".conf"
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
chmod -R 600 $name
|
||||||
|
|
||||||
|
wg
|
||||||
1
active/systemd_wireguard/qr.sh
Executable file
1
active/systemd_wireguard/qr.sh
Executable file
@@ -0,0 +1 @@
|
|||||||
|
qrencode -t ansiutf8
|
||||||
5
active/systemd_wireguard/wg0.conf.j2
Normal file
5
active/systemd_wireguard/wg0.conf.j2
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# {{ ansible_managed }}
|
||||||
|
[Interface]
|
||||||
|
Address = 10.0.1.1/24
|
||||||
|
ListenPort = 51820
|
||||||
|
PrivateKey = {{ server_privkey }}
|
||||||
39
active/systemd_wireguard/wireguard.md
Executable file
39
active/systemd_wireguard/wireguard.md
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
# Wireguard
|
||||||
|
|
||||||
|
## Install
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook \
|
||||||
|
-i ansible/inventory.yaml \
|
||||||
|
-l wireguard \
|
||||||
|
active/systemd_wireguard/install_backup.yaml \
|
||||||
|
-e "@active/systemd_wireguard/secrets/vars.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Add a client
|
||||||
|
|
||||||
|
```bash
|
||||||
|
export WG_IP_SUFFIX=$(cat IP && echo $(($(cat IP) + 1)) > IP)
|
||||||
|
export PRIVKEY=$(wg genkey)
|
||||||
|
export PUBKEY=$(echo $PRIVKEY | wg pubkey)
|
||||||
|
export SERVER_PUBKEY=$(cat publickey)
|
||||||
|
cat <<EOF > id_$WG_IP_SUFFIX
|
||||||
|
[Interface]
|
||||||
|
PrivateKey = $PRIVKEY
|
||||||
|
Address = 10.10.0.$WG_IP_SUFFIX/32
|
||||||
|
DNS = 10.10.0.1
|
||||||
|
|
||||||
|
[Peer]
|
||||||
|
PublicKey = $SERVER_PUBKEY
|
||||||
|
Endpoint = pihole.reeserelease.com:51820
|
||||||
|
AllowedIPs = 10.10.0.1/32
|
||||||
|
EOF
|
||||||
|
|
||||||
|
cat id_$WG_IP_SUFFIX | qrencode -t ansiutf8
|
||||||
|
echo "Added ID $WG_IP_SUFFIX"
|
||||||
|
echo "Press enter to continue"
|
||||||
|
read
|
||||||
|
|
||||||
|
wg set wg0 peer $PUBKEY allowed-ips 10.10.0.$WG_IP_SUFFIX/32
|
||||||
|
wg-quick down wg0 && wg-quick up wg0
|
||||||
|
```
|
||||||
@@ -259,7 +259,7 @@ vim /etc/hosts
|
|||||||
`192.168.122.195 freeipa.reese.reeselink.com`
|
`192.168.122.195 freeipa.reese.reeselink.com`
|
||||||
|
|
||||||
# This should populate /etc/krb5.conf and /etc/sssd/sssd.conf
|
# This should populate /etc/krb5.conf and /etc/sssd/sssd.conf
|
||||||
realm join freeipa.reese.reeselink.com -v
|
realm join -U someuser freeipa.reese.reeselink.com -v
|
||||||
|
|
||||||
# AD should be configured to create the user's home dir, but to be safe
|
# AD should be configured to create the user's home dir, but to be safe
|
||||||
export freeipa_user=ducoterra
|
export freeipa_user=ducoterra
|
||||||
|
|||||||
411
templates/os/foobar.md
Normal file
411
templates/os/foobar.md
Normal file
@@ -0,0 +1,411 @@
|
|||||||
|
# Foobar
|
||||||
|
|
||||||
|
These docs frequently reference an "operator" and a "client". The operator is
|
||||||
|
your laptop, computer, pipeline, or any device will be connecting to, or
|
||||||
|
configuring, the OS during/after install. The client is the device you're
|
||||||
|
installing the OS onto.
|
||||||
|
|
||||||
|
- [Foobar](#foobar)
|
||||||
|
- [Installation](#installation)
|
||||||
|
- [Network](#network)
|
||||||
|
- [Firewalld Configuration](#firewalld-configuration)
|
||||||
|
- [Setup SSH](#setup-ssh)
|
||||||
|
- [Fail2Ban](#fail2ban)
|
||||||
|
- [Set eui64 on network interface](#set-eui64-on-network-interface)
|
||||||
|
- [Set up Network Bridge](#set-up-network-bridge)
|
||||||
|
- [Storage](#storage)
|
||||||
|
- [BTRFS Parent Volumes](#btrfs-parent-volumes)
|
||||||
|
- [BTRFS Snapshots](#btrfs-snapshots)
|
||||||
|
- [BTRFS Maintenance](#btrfs-maintenance)
|
||||||
|
- [TPM2 Luks Decryption](#tpm2-luks-decryption)
|
||||||
|
- [Users](#users)
|
||||||
|
- [Change your password](#change-your-password)
|
||||||
|
- [Updates](#updates)
|
||||||
|
- [Automatic Updates](#automatic-updates)
|
||||||
|
- [Monitoring](#monitoring)
|
||||||
|
- [Disk Usage](#disk-usage)
|
||||||
|
- [Disk Wear](#disk-wear)
|
||||||
|
- [Backups](#backups)
|
||||||
|
- [Downgrading Kernel](#downgrading-kernel)
|
||||||
|
- [Apps](#apps)
|
||||||
|
- [Package Manager](#package-manager)
|
||||||
|
- [Install and Enable Cockpit](#install-and-enable-cockpit)
|
||||||
|
- [Install and Enable Virtualization](#install-and-enable-virtualization)
|
||||||
|
- [Install and Enable Containers](#install-and-enable-containers)
|
||||||
|
- [Troubleshooting](#troubleshooting)
|
||||||
|
- [Disable Swap](#disable-swap)
|
||||||
|
- [Disable Selinux](#disable-selinux)
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Configure network first
|
||||||
|
1. Set a hostname
|
||||||
|
2. Disable ipv6 privacy extensions
|
||||||
|
2. Software Selection
|
||||||
|
1. Headless Management
|
||||||
|
3. User Creation
|
||||||
|
1. Set a simple password, we'll change it later
|
||||||
|
4. Disk partitioning
|
||||||
|
1. Select manual (blivet) partitioning
|
||||||
|
2. Create a 1GB EFI system partition and mount it at `/boot/efi`
|
||||||
|
3. Create a 1GB ext4 partition and mount it at `/boot`
|
||||||
|
4. Create a btrfs volume with the remaining data and name it something unqiue, do not mount it
|
||||||
|
5. Create a btrfs subvolume called "root" and mount it at `/`
|
||||||
|
6. Create any other btrfs subvolumes you might need
|
||||||
|
5. Take note of the ipv4 and ipv6 address. Update any DNS records at this time.
|
||||||
|
6. Install and reboot
|
||||||
|
|
||||||
|
## Network
|
||||||
|
|
||||||
|
### Firewalld Configuration
|
||||||
|
|
||||||
|
Set the default firewalld zone to `public`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Note, you probably don't have to do this. Check Cockpit Network -> Firewall
|
||||||
|
# firewall-cmd --set-default-zone=public
|
||||||
|
```
|
||||||
|
|
||||||
|
Firewalld will be on and blocking by default. You can check the zone and allowed ports with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
firewall-cmd --zone=public --list-ports
|
||||||
|
firewall-cmd --zone=public --list-services
|
||||||
|
```
|
||||||
|
|
||||||
|
Allow Cockpit with
|
||||||
|
|
||||||
|
```bash
|
||||||
|
firewall-cmd --permanent --zone=public --add-port=9090/tcp
|
||||||
|
firewall-cmd --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
### Setup SSH
|
||||||
|
|
||||||
|
See [README](/README.md#ssh-key-generation)
|
||||||
|
|
||||||
|
### Fail2Ban
|
||||||
|
|
||||||
|
On the server:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run tmux session
|
||||||
|
tmux
|
||||||
|
|
||||||
|
dnf install -y fail2ban
|
||||||
|
|
||||||
|
# Setup initial rules
|
||||||
|
cat <<EOF > /etc/fail2ban/jail.local
|
||||||
|
# Jail configuration additions for local installation
|
||||||
|
|
||||||
|
# Adjust the default configuration's default values
|
||||||
|
[DEFAULT]
|
||||||
|
# Optional enter an trusted IP never to ban
|
||||||
|
# ignoreip = 2600:1700:1e6c:a81f::0/64
|
||||||
|
bantime = 6600
|
||||||
|
backend = auto
|
||||||
|
|
||||||
|
# The main configuration file defines all services but
|
||||||
|
# deactivates them by default. We have to activate those neeeded
|
||||||
|
[sshd]
|
||||||
|
enabled = true
|
||||||
|
EOF
|
||||||
|
|
||||||
|
systemctl enable fail2ban --now
|
||||||
|
|
||||||
|
# OPTIONAL: follow logs
|
||||||
|
tail -f /var/log/fail2ban.log
|
||||||
|
```
|
||||||
|
|
||||||
|
Checking, banning, unbanning
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# See banned clients
|
||||||
|
fail2ban-client banned
|
||||||
|
# See jails (sshd should be one of them)
|
||||||
|
fail2ban-client status
|
||||||
|
# Unban a client from the sshd jail
|
||||||
|
fail2ban-client set sshd unbanip <IP address>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set eui64 on network interface
|
||||||
|
|
||||||
|
Ensures consistent mac-based IPv6 address.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli connection modify Wired\ connection\ 1 ipv6.addr-gen-mode eui64
|
||||||
|
```
|
||||||
|
|
||||||
|
### Set up Network Bridge
|
||||||
|
|
||||||
|
Networking -> Add bridge -> add network interface and save
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nmcli connection modify bridge0 ipv6.addr-gen-mode eui64
|
||||||
|
```
|
||||||
|
|
||||||
|
## Storage
|
||||||
|
|
||||||
|
### BTRFS Parent Volumes
|
||||||
|
|
||||||
|
In `/etc/fstab`, add the parent volumes for your disks mounted with subvolid=5 at `/btrfs` so you can see
|
||||||
|
all subvolumes.
|
||||||
|
|
||||||
|
```conf
|
||||||
|
UUID=64beedac-c0c9-48bf-a3ae-7707df6ebc97 /btrfs/3dserver-root btrfs subvolid=5,compress=zstd:1,x-systemd.device-timeout=0 0 0
|
||||||
|
UUID=3c76b83f-7547-4c18-b08f-9e7902022b8d /btrfs/3dserver-data btrfs subvolid=5,compress=zstd:1,x-systemd.device-timeout=0 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl daemon-reload
|
||||||
|
mount -a --mkdir
|
||||||
|
```
|
||||||
|
|
||||||
|
### BTRFS Snapshots
|
||||||
|
|
||||||
|
<https://en.opensuse.org/openSUSE:Snapper_Tutorial>
|
||||||
|
|
||||||
|
<http://snapper.io/manpages/snapper-configs.html>
|
||||||
|
|
||||||
|
We'll be using snapper, a tool for automating and controlling snapshot behavior.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dnf install snapper dnf-plugin-snapper
|
||||||
|
|
||||||
|
# Allow selinux management
|
||||||
|
semanage permissive -a snapperd_t
|
||||||
|
|
||||||
|
# Note, if you mess something up you can run snapper -c root delete-config to delete
|
||||||
|
# System configs are stored in /etc/sysconfig/snapper as well as /etc/snapper
|
||||||
|
snapper -c root create-config /
|
||||||
|
snapper -c data create-config /path/to/other/data
|
||||||
|
|
||||||
|
# Enable automatic snapshots
|
||||||
|
systemctl enable --now snapper-timeline.timer
|
||||||
|
# Enable automatic cleanup
|
||||||
|
systemctl enable --now snapper-cleanup.timer
|
||||||
|
# Enable snapshots on boot
|
||||||
|
systemctl enable --now snapper-boot.timer
|
||||||
|
|
||||||
|
# List snapshots
|
||||||
|
snapper -c root list
|
||||||
|
# Create snapshot manually
|
||||||
|
snapper -c root create --description "test snapshot"
|
||||||
|
# Delete first snapshot
|
||||||
|
snapper -c root delete 1
|
||||||
|
```
|
||||||
|
|
||||||
|
Note - you probably don't want to keep yearly snapshots.
|
||||||
|
Edit `/etc/snapper/configs/root` and change `TIMELINE_LIMIT_YEARLY=` to `0`.
|
||||||
|
|
||||||
|
### BTRFS Maintenance
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start a scrub in the foreground (-B) at /
|
||||||
|
btrfs scrub start -B /
|
||||||
|
```
|
||||||
|
|
||||||
|
### TPM2 Luks Decryption
|
||||||
|
|
||||||
|
Mostly taken from here:
|
||||||
|
<https://gist.github.com/jdoss/777e8b52c8d88eb87467935769c98a95>
|
||||||
|
|
||||||
|
PCR reference for `--tpm2-pcrs` args
|
||||||
|
|
||||||
|
```text
|
||||||
|
0: System firmware executable
|
||||||
|
2: Kernel
|
||||||
|
4: Bootloader
|
||||||
|
7: Secure boot state
|
||||||
|
8: Cmdline
|
||||||
|
9: Initrd
|
||||||
|
```
|
||||||
|
|
||||||
|
Note, if your threat vector is people trying to get data off your old disks after throwing them
|
||||||
|
away, you can set `--tpm2-pcrs=""`. Someone could gain access to your encrypted partition if they
|
||||||
|
can access your machine physically by manipulating the boot parameters but you're guaranteed to
|
||||||
|
unlock despite updates and upgrades.
|
||||||
|
|
||||||
|
Basic commands:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run tmux session
|
||||||
|
tmux
|
||||||
|
|
||||||
|
# Show tpm2 devices
|
||||||
|
systemd-cryptenroll --tpm2-device=list
|
||||||
|
# Show crypto luks block devices
|
||||||
|
blkid -t TYPE=crypto_LUKS
|
||||||
|
|
||||||
|
# Enroll the tpm2 device with systemd-cryptenroll
|
||||||
|
systemd-cryptenroll /dev/nvme0n1p3 --tpm2-device=auto --tpm2-pcrs=""
|
||||||
|
|
||||||
|
####################
|
||||||
|
##### OPTIONAL #####
|
||||||
|
####################
|
||||||
|
# If you have lots of devices to decrypt (like a btrfs raid array), use these commands.
|
||||||
|
# Get all crypto luks partitions
|
||||||
|
blkid | grep crypto_LUKS
|
||||||
|
# List them all space-separated and drop the '/dev'
|
||||||
|
LUKS_DEVS="nvme0n1p4 nvme1n1p1 nvme2n1p1 nvme3n1p1 nvme5n1p1 nvme4n1p1 nvme6n1p1"
|
||||||
|
|
||||||
|
# Check that your list is good
|
||||||
|
for dev in $LUKS_DEVS; do echo will enroll /dev/$dev; done
|
||||||
|
|
||||||
|
# Enroll
|
||||||
|
for dev in $LUKS_DEVS; do \
|
||||||
|
echo "Enrolling /dev/$dev"; \
|
||||||
|
systemd-cryptenroll /dev/$dev --tpm2-device=auto --tpm2-pcrs=""; \
|
||||||
|
done
|
||||||
|
########################
|
||||||
|
##### END OPTIONAL #####
|
||||||
|
########################
|
||||||
|
|
||||||
|
# Append to command line args
|
||||||
|
echo "add_dracutmodules+=\" tpm2-tss \"" | tee /etc/dracut.conf.d/tpm2.conf
|
||||||
|
dracut -f
|
||||||
|
```
|
||||||
|
|
||||||
|
Finally, `vim /etc/default/grub` and add `rd.luks.options=tpm2-device=auto` to GRUB_CMDLINE_LINUX
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Update Grub
|
||||||
|
grub2-mkconfig -o /boot/grub2/grub.cfg
|
||||||
|
reboot
|
||||||
|
# Cross your fingers that you don't have to go type in the password manually.
|
||||||
|
# Yes, 60 full seconds is too long. Go type your password in.
|
||||||
|
```
|
||||||
|
|
||||||
|
If you need to reenroll for some reason:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Reenroll
|
||||||
|
systemd-cryptenroll /dev/nvme0n1p3 --wipe-slot=tpm2 --tpm2-device=auto --tpm2-pcrs=""
|
||||||
|
```
|
||||||
|
|
||||||
|
## Users
|
||||||
|
|
||||||
|
### Change your password
|
||||||
|
|
||||||
|
In Cockpit navigate to Accounts -> user -> Set password
|
||||||
|
|
||||||
|
## Updates
|
||||||
|
|
||||||
|
### Automatic Updates
|
||||||
|
|
||||||
|
In Cockpit navigate to software updates -> automatic updates -> install -> security updates only
|
||||||
|
|
||||||
|
## Monitoring
|
||||||
|
|
||||||
|
In Cockpit: Overview -> View metrics and history -> Install PCP Support -> Metrics settings -> Turn on Collect Metrics
|
||||||
|
|
||||||
|
### Disk Usage
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
### Disk Wear
|
||||||
|
|
||||||
|
TODO
|
||||||
|
|
||||||
|
## Backups
|
||||||
|
|
||||||
|
See [borg.md](/active/systemd_borg/borg.md)
|
||||||
|
|
||||||
|
### Downgrading Kernel
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dnf install koji
|
||||||
|
|
||||||
|
# Note: format is kernel-version.fedora-version
|
||||||
|
cd $(mktemp -d) && koji download-build --arch=x86_64 --arch=noarch kernel-6.11.3-300.fc41 && dnf install ./*
|
||||||
|
|
||||||
|
reboot
|
||||||
|
```
|
||||||
|
|
||||||
|
## Apps
|
||||||
|
|
||||||
|
### Package Manager
|
||||||
|
|
||||||
|
Configure dnf to use the fastest mirror:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
echo 'fastestmirror=1' >> /etc/dnf/dnf.conf
|
||||||
|
dnf clean all
|
||||||
|
dnf update --refresh -y
|
||||||
|
# libdnf5 is required for ansible to work
|
||||||
|
dnf install -y glances tmux vim python3-libdnf5
|
||||||
|
```
|
||||||
|
|
||||||
|
### Install and Enable Cockpit
|
||||||
|
|
||||||
|
<https://cockpit-project.org/running>
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dnf install cockpit
|
||||||
|
systemctl enable --now cockpit.socket
|
||||||
|
firewall-cmd --add-service=cockpit
|
||||||
|
firewall-cmd --add-service=cockpit --permanent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Install and Enable Virtualization
|
||||||
|
|
||||||
|
Don't forget to add a btrfs subvolume for `/var/lib/libvirt`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Since we already created our /btrfs mountpoint, this volume will show up automatically
|
||||||
|
# at /btrfs/libvirt
|
||||||
|
btrfs sub create /btrfs/libvirt
|
||||||
|
```
|
||||||
|
|
||||||
|
Now create an fstab entry that mounts the volume at /var/lib/libvirt
|
||||||
|
|
||||||
|
```bash
|
||||||
|
UUID=... /var/lib/libvirt btrfs subvol=libvirt,compress=zstd:1,x-systemd.device-timeout=0 0 0
|
||||||
|
```
|
||||||
|
|
||||||
|
Mount the libvirt volume:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl daemon-reload
|
||||||
|
mount -a --mkdir
|
||||||
|
# Check that the mount was successful. This will print something if our mount worked.
|
||||||
|
mount | grep -i /var/lib/libvirt
|
||||||
|
```
|
||||||
|
|
||||||
|
Create a snapshot schedule for libvirt.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
snapper -c libvirt create-config /var/lib/libvirt
|
||||||
|
# Don't forget to edit "YEARLY" at /etc/snapper/configs/libvirt
|
||||||
|
```
|
||||||
|
|
||||||
|
Install and enable the virtualization service.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dnf group install --with-optional virtualization
|
||||||
|
systemctl enable --now libvirtd
|
||||||
|
```
|
||||||
|
|
||||||
|
Install the cockpit machines application.
|
||||||
|
|
||||||
|
## Install and Enable Containers
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Disable Swap
|
||||||
|
|
||||||
|
```bash
|
||||||
|
swapoff -a
|
||||||
|
zramctl --reset /dev/zram0
|
||||||
|
dnf -y remove zram-generator-defaults
|
||||||
|
```
|
||||||
|
|
||||||
|
### Disable Selinux
|
||||||
|
|
||||||
|
By default selinux will be enforcing. You can set it to permissive with
|
||||||
|
|
||||||
|
```bash
|
||||||
|
setenforce 0
|
||||||
|
```
|
||||||
|
|
||||||
|
And then make it permanent by editing `/etc/selinux/config` and inserting `SELINUX=permissive`.
|
||||||
3
templates/podman/compose/README.md
Normal file
3
templates/podman/compose/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Compose
|
||||||
|
|
||||||
|
Put your compose.yaml here.
|
||||||
12
templates/podman/compose/compose.yaml
Normal file
12
templates/podman/compose/compose.yaml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
services:
|
||||||
|
foobar:
|
||||||
|
container_name: foobar
|
||||||
|
restart: always
|
||||||
|
image: localhost/foobar:latest
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
volumes:
|
||||||
|
- /home/foobar/data:/var/app/data
|
||||||
|
security_opt:
|
||||||
|
- label=disable
|
||||||
|
userns_mode: keep-id
|
||||||
131
templates/podman/foobar.md
Normal file
131
templates/podman/foobar.md
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# Podman foobar
|
||||||
|
|
||||||
|
- [Podman foobar](#podman-foobar)
|
||||||
|
- [Setup foobar Project](#setup-foobar-project)
|
||||||
|
- [Install foobar](#install-foobar)
|
||||||
|
- [Create the foobar user](#create-the-foobar-user)
|
||||||
|
- [Write the foobar compose spec](#write-the-foobar-compose-spec)
|
||||||
|
- [Convert foobar compose spec to quadlets](#convert-foobar-compose-spec-to-quadlets)
|
||||||
|
- [Expose foobar](#expose-foobar)
|
||||||
|
- [firewalld](#firewalld)
|
||||||
|
- [Backup foobar](#backup-foobar)
|
||||||
|
- [Upgrade foobar](#upgrade-foobar)
|
||||||
|
- [Upgrade Quadlets](#upgrade-quadlets)
|
||||||
|
- [Notes](#notes)
|
||||||
|
- [SELinux](#selinux)
|
||||||
|
|
||||||
|
## Setup foobar Project
|
||||||
|
|
||||||
|
1. Copy and rename this folder to active/podman_foobar
|
||||||
|
2. Find and replace foobar with the name of the service.
|
||||||
|
3. Create the rootless user to run the podman containers
|
||||||
|
4. Write the compose.yaml spec for your service
|
||||||
|
5. Convert the compose.yaml spec to a quadlet
|
||||||
|
6. Install the quadlet on the podman server
|
||||||
|
7. Expose the quadlet service
|
||||||
|
8. Install a backup service and timer
|
||||||
|
|
||||||
|
## Install foobar
|
||||||
|
|
||||||
|
### Create the foobar user
|
||||||
|
|
||||||
|
```bash
|
||||||
|
useradd foobar
|
||||||
|
|
||||||
|
su - foobar
|
||||||
|
ssh-keygen
|
||||||
|
exit
|
||||||
|
cp ~/.ssh/authorized_keys /home/foobar/.ssh/authorized_keys
|
||||||
|
chown foobar:foobar /home/foobar/.ssh/authorized_keys
|
||||||
|
loginctl enable-linger $(id -u foobar)
|
||||||
|
```
|
||||||
|
|
||||||
|
SSH into the server as foobar
|
||||||
|
|
||||||
|
```bash
|
||||||
|
systemctl --user enable podman-restart
|
||||||
|
systemctl --user enable --now podman.socket
|
||||||
|
mkdir -p ~/.config/containers/systemd
|
||||||
|
```
|
||||||
|
|
||||||
|
### Write the foobar compose spec
|
||||||
|
|
||||||
|
Edit the compose.yaml at active/foobar/compose/compose.yaml
|
||||||
|
|
||||||
|
### Convert foobar compose spec to quadlets
|
||||||
|
|
||||||
|
On your local machine:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Generate the systemd service
|
||||||
|
podman run \
|
||||||
|
--security-opt label=disable \
|
||||||
|
--rm \
|
||||||
|
-v $(pwd)/active/foobar/:/compose \
|
||||||
|
-v $(pwd)/active/foobar/quadlets:/quadlets \
|
||||||
|
quay.io/k9withabone/podlet \
|
||||||
|
-f /quadlets \
|
||||||
|
-i \
|
||||||
|
--overwrite \
|
||||||
|
compose /compose/compose.yaml
|
||||||
|
|
||||||
|
# Copy the files to the server
|
||||||
|
scp -r active/foobar/quadlets/. foobar:~/.config/containers/systemd/
|
||||||
|
```
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ssh foobar systemctl --user daemon-reload
|
||||||
|
ssh foobar systemctl --user restart foobar
|
||||||
|
# Enables auto-update service which will pull new container images automatically every day
|
||||||
|
ssh foobar systemctl --user enable --now podman-auto-update.timer
|
||||||
|
```
|
||||||
|
|
||||||
|
### Expose foobar
|
||||||
|
|
||||||
|
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)
|
||||||
|
3. Finally, follow your OS's guide for opening ports via its firewall service.
|
||||||
|
|
||||||
|
#### firewalld
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# command to get current active zone and default zone
|
||||||
|
firewall-cmd --get-active-zones
|
||||||
|
firewall-cmd --get-default-zone
|
||||||
|
|
||||||
|
# command to open 443 on tcp
|
||||||
|
firewall-cmd --permanent --zone=<zone> --add-port=443/tcp
|
||||||
|
|
||||||
|
# command to open 80 and 443 on tcp and udp
|
||||||
|
firewall-cmd --permanent --zone=<zone> --add-port={80,443}/{tcp,udp}
|
||||||
|
|
||||||
|
# command to list available services and then open http and https
|
||||||
|
firewall-cmd --get-services
|
||||||
|
firewall-cmd --permanent --zone=<zone> --add-service={http,https}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backup foobar
|
||||||
|
|
||||||
|
Follow the [Borg Backup instructions](/active/systemd_borg/borg.md#set-up-a-client-for-backup)
|
||||||
|
|
||||||
|
## Upgrade foobar
|
||||||
|
|
||||||
|
### Upgrade Quadlets
|
||||||
|
|
||||||
|
Upgrades should be a repeat of [writing the compose spec](#convert-compose-to-quadlet) and [installing the quadlets](#convert-compose-to-quadlet)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
scp -r quadlets/. foobar:~/.config/containers/systemd/
|
||||||
|
ssh foobar systemctl --user daemon-reload
|
||||||
|
ssh foobar systemctl --user restart foobar
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
### SELinux
|
||||||
|
|
||||||
|
<https://blog.christophersmart.com/2021/01/31/podman-volumes-and-selinux/>
|
||||||
|
|
||||||
|
:z allows a container to share a mounted volume with all other containers.
|
||||||
|
|
||||||
|
:Z allows a container to reserve a mounted volume and prevents any other container from accessing.
|
||||||
3
templates/podman/quadlets/README.md
Normal file
3
templates/podman/quadlets/README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# Quadlets
|
||||||
|
|
||||||
|
Put your quadlets here.
|
||||||
49
templates/systemd/foobar.md
Normal file
49
templates/systemd/foobar.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# foobar
|
||||||
|
|
||||||
|
- [foobar](#foobar)
|
||||||
|
- [Setup foobar Project](#setup-foobar-project)
|
||||||
|
- [Service Variables](#service-variables)
|
||||||
|
- [Install foobar](#install-foobar)
|
||||||
|
- [Upgrade foobar](#upgrade-foobar)
|
||||||
|
- [Backup foobar](#backup-foobar)
|
||||||
|
- [Restore foobar](#restore-foobar)
|
||||||
|
- [Uninstall foobar](#uninstall-foobar)
|
||||||
|
|
||||||
|
## Setup foobar Project
|
||||||
|
|
||||||
|
1. Copy and rename this folder to active/systemd_foobar
|
||||||
|
2. Find and replace foobar with the name of the service
|
||||||
|
3. Write the foobar.service spec
|
||||||
|
4. (OPTIONAL) Write the foobar.timer spec
|
||||||
|
5. (OPTIONAL) Write the foobar.sh.j2 template
|
||||||
|
6. Write the install_foobar.yaml ansible template
|
||||||
|
7. Install the service via ansible
|
||||||
|
8. Expose the service
|
||||||
|
9. Install a backup service and timer
|
||||||
|
|
||||||
|
## Service Variables
|
||||||
|
|
||||||
|
1. For most vars,populate `vars.yaml`
|
||||||
|
2. For secret vars, create a new folder called `secrets/` and put a `vars.yaml` there.
|
||||||
|
|
||||||
|
## Install foobar
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run the playbook
|
||||||
|
ansible-playbook \
|
||||||
|
-i ansible/inventory.yaml \
|
||||||
|
-l podman \
|
||||||
|
active/systemd_foobar/install_foobar.yaml \
|
||||||
|
-e "@active/systemd_foobar/vars.yaml" \
|
||||||
|
-e "@active/systemd_foobar/secrets/vars.yaml"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Upgrade foobar
|
||||||
|
|
||||||
|
## Backup foobar
|
||||||
|
|
||||||
|
Follow the [Borg Backup instructions](/active/systemd_borg/borg.md#set-up-a-client-for-backup)
|
||||||
|
|
||||||
|
## Restore foobar
|
||||||
|
|
||||||
|
## Uninstall foobar
|
||||||
12
templates/systemd/foobar.service
Normal file
12
templates/systemd/foobar.service
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Runs foobar
|
||||||
|
After=network.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=no
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/local/script/foobar.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
3
templates/systemd/foobar.sh.j2
Normal file
3
templates/systemd/foobar.sh.j2
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
echo "hello foobar!"
|
||||||
11
templates/systemd/foobar.timer
Normal file
11
templates/systemd/foobar.timer
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Run Foobar every day
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=*-*-* 2:00:00
|
||||||
|
AccuracySec=10min
|
||||||
|
Persistent=true
|
||||||
|
Unit=foobar.service
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
39
templates/systemd/install_foobar.yaml
Normal file
39
templates/systemd/install_foobar.yaml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
- name: Create Backup Service
|
||||||
|
hosts: all
|
||||||
|
vars_files:
|
||||||
|
- secrets/vars.yaml
|
||||||
|
tasks:
|
||||||
|
- name: Create /usr/local/script dir
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /usr/local/script
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
- name: Copy foobar.service
|
||||||
|
template:
|
||||||
|
src: backup.service
|
||||||
|
dest: /etc/systemd/system/foobar.service
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
- name: Copy foobar.timer
|
||||||
|
template:
|
||||||
|
src: backup.timer
|
||||||
|
dest: /etc/systemd/system/foobar.timer
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
- name: Template foobar.sh
|
||||||
|
template:
|
||||||
|
src: backup.sh.j2
|
||||||
|
dest: /usr/local/script/foobar.sh
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0744'
|
||||||
|
- name: Something foobar related that might fail
|
||||||
|
script: echo 'hello foobar!'
|
||||||
|
ignore_errors: yes
|
||||||
|
- name: Reload foobar.timer
|
||||||
|
ansible.builtin.systemd_service:
|
||||||
|
name: foobar.timer
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
1
templates/systemd/vars.yaml
Normal file
1
templates/systemd/vars.yaml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
name: foobar
|
||||||
Reference in New Issue
Block a user