initial commit

This commit is contained in:
admin 2025-01-26 01:18:19 +00:00
commit 01c1db8ed6
9 changed files with 784 additions and 0 deletions

2
ansible.cfg Executable file
View File

@ -0,0 +1,2 @@
[defaults]
inventory = inventory

5
inventory Executable file
View File

@ -0,0 +1,5 @@
servers:
hosts:
debian-pods:
ansible_host: 192.168.0.30
ansible_user: admin

23
main.yml Executable file
View File

@ -0,0 +1,23 @@
---
- name: configure host
hosts: all
vars_files:
- vars
- vault.yml
tasks:
- import_tasks: tasks/setup.yml
tags: ['setup']
- import_tasks: tasks/nvidia.yml
tags: ['nvidia']
- import_tasks: tasks/pre-podman.yml
tags: ['podman']
- import_tasks: tasks/podman.yml
tags: ['podman']
- import_tasks: tasks/post-podman.yml
tags: ['podman']

21
tasks/nvidia.yml Executable file
View File

@ -0,0 +1,21 @@
- name: install nvidia-container-toolkit repo
become: true
ansible.builtin.shell:
cmd: "curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --yes --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg && curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | tee /etc/apt/sources.list.d/nvidia-container-toolkit.list"
- name: install Nvidia driver
become: true
ansible.builtin.apt:
pkg:
- nvidia-container-toolkit
- nvidia-driver
- firmware-misc-nonfree
state: present
- name: configure nvidia for rootless podman
become: true
ansible.builtin.shell:
cmd: nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml
register: nvidia_ctk_result
ignore_errors: true
failed_when: nvidia_ctk+result.rc != 1

582
tasks/podman.yml Executable file
View File

@ -0,0 +1,582 @@
---
- name: mealie
containers.podman.podman_container:
state: quadlet
name: podman_mealie
image: ghcr.io/mealie-recipes/mealie:latest
network: bridge
volumes:
- /home/admin/podman/mealie:/app/data/
ports:
- 9091:9000
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: ollama
containers.podman.podman_container:
state: quadlet
name: podman_ollama
image: docker.io/ollama/ollama:latest
network: bridge
volumes:
- "/home/admin/podman/ollama:/root/.ollama"
ports:
- "11434:11434"
env:
OLLAMA_KEEP_ALIVE: "-1"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: open-webui
containers.podman.podman_container:
state: quadlet
name: podman_open-webui
image: ghcr.io/open-webui/open-webui:latest
network: bridge
volumes:
- "/home/admin/podman/open-webui:/app/backend/data"
ports:
- "3000:8080"
env:
ENABLE_RAG_WEB_SEARCH: "True"
RAG_WEB_SEARCH_ENGINE: "searxng"
RAG_WEB_SEARCH_RESULT_COUNT: 3
RAG_WEB_SEARCH_CONCURRENT_REQUESTS: 10
SEARXNG_QUERY_URL: "http://192.168.0.30:8880/search?q=<query>"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: searxng
containers.podman.podman_container:
state: quadlet
name: podman_searxng
image: docker.io/searxng/searxng:latest
network: bridge
ports:
- "8880:8080"
volumes:
- "/home/admin/podman/searxng:/etc/searxng"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: jellyfin
containers.podman.podman_container:
state: quadlet
name: podman_jellyfin
image: docker.io/jellyfin/jellyfin
network: bridge
volumes:
- "/home/admin/podman/jellyfin:/config"
- "/mnt/media/video/movies:/movies:ro"
- "/mnt/media/video/tv:/tv:ro"
- "/mnt/media/audio/music/flac:/music:ro"
- "/mnt/media/video/Family:/family:ro"
ports:
- "8096:8096"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: freshrss
containers.podman.podman_container:
state: quadlet
name: podman_freshrss
image: lscr.io/linuxserver/freshrss:latest
network: bridge
volumes:
- "/home/admin/podman/freshrss:/config"
ports:
- "8555:80"
env:
TZ: "Europe/London"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: eclipse-mosquitto
containers.podman.podman_container:
state: quadlet
name: podman_eclipse-mosquitto
image: docker.io/eclipse-mosquitto
network: bridge
volumes:
- "/home/admin/podman/eclipse-mosquitto:/mosquitto"
ports:
- "1883:1883"
- "9001:9001"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: frigate
containers.podman.podman_container:
state: quadlet
name: podman_frigate
image: "ghcr.io/blakeblackshear/frigate:{{ frigate_version }}"
network: bridge
volumes:
- /etc/localtime:/etc/localtime:ro
- /home/admin/podman/frigate:/config
- /mnt/share/services/cctv:/media/frigate
ports:
- "5005:5000"
- "5001:8971"
- "1935:1935"
- "8554:8554"
env:
FRIGATE_RTSP_PASSWORD: "{{ rtsp_password }}"
quadlet_options:
- "Tmpfs=/tmp/cache"
- "ShmSize=128mb"
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: nginx-proxy-manager
containers.podman.podman_container:
state: quadlet
name: podman_nginx-proxy-manager
image: docker.io/jc21/nginx-proxy-manager:2.10.4
network: bridge
privileged: true
volumes:
- "/home/admin/podman/nginx-proxy-manager:/data"
- "/home/admin/podman/letsencrypt:/etc/letsencrypt"
ports:
- "5080:80"
- "5443:443"
- "5081:81"
env:
TZ: "Europe/London"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: ddclient
containers.podman.podman_container:
state: quadlet
name: podman_ddclient
image: lscr.io/linuxserver/ddclient:latest
network: bridge
env:
TZ: "Europe/London"
volumes:
- "/home/admin/podman/ddclient:/config"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: gitea
containers.podman.podman_container:
state: quadlet
name: podman_gitea
image: docker.io/gitea/gitea:latest
network: bridge
env:
TZ: "Europe/London"
DISABLE_REGISTRATION: "true"
volumes:
- "/home/admin/podman/gitea:/data"
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
ports:
- "3001:3000"
- "222:22"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: nginx_mektem_com
containers.podman.podman_container:
state: quadlet
name: podman_nginx_mektem_com
image: docker.io/nginx:latest
network: bridge
volumes:
- "/home/admin/podman/nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
- "/home/admin/podman/nginx/html:/usr/share/nginx/html"
ports:
"888:80"
env:
NGINX_HOST: "mektem.com"
NGINX_PORT: "80"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: joplin
containers.podman.podman_container:
state: quadlet
name: podman_joplin
image: docker.io/joplin/server:latest
network: bridge
ports:
"22300:22300"
env:
APP_PORT: "22300"
APP_BASE_URL: "https://notes.mektem.com"
DB_CLIENT: "pg"
POSTGRES_PASSWORD: "{{ joplin_password }}"
POSTGRES_DATABASE: "joplin-db"
POSTGRES_USER: "joplin"
POSTGRES_PORT: "5432"
POSTGRES_HOST: "{{ ansible_ssh_host }}"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: joplin-db
containers.podman.podman_container:
state: quadlet
name: podman_joplin-db
image: docker.io/postgres:15
network: bridge
volumes:
- "/home/admin/podman/joplin-db:/var/lib/postgresql/data"
ports:
"5432:5432"
env:
TZ: "Europe/London"
POSTGRES_PASSWORD: "{{ joplin_password }}"
POSTGRES_USER: "joplin"
POSTGRES_DB: "joplin-db"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: wireguard
containers.podman.podman_container:
state: quadlet
name: podman_wireguard
image: lscr.io/linuxserver/wireguard:latest
network: bridge
privileged: true
cap_add:
- NET_RAW
- NET_ADMIN
- SYS_MODULE
volumes:
- "/home/admin/podman/wireguard:/config"
- "/lib/modules:/lib/modules" #optional
ports:
- "51820:51820/udp"
env:
TZ: "Europe/London"
SERVERURL: "81.99.39.74"
SERVERPORT: "51820"
PEERS: "FarisIOS,FarisMacbook,SafaPhone"
ALLOWEDIPS: "0.0.0.0/0"
LOG_CONFS: "true"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: vaultwarden
containers.podman.podman_container:
state: quadlet
name: podman_vaultwarden
image: docker.io/vaultwarden/server:latest
network: bridge
volumes:
- "/home/admin/podman/vaultwarden/:/data/"
ports:
- "8000:80"
- "3012:3012"
env:
TZ: "Europe/London"
DOMAIN: "https://vault.mektem.com"
SIGNUPS_ALLOWED: "false"
EXPERIMENTAL_CLIENT_FEATURE_FLAGS: "ssh-key-vault-item,ssh-agent"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: homeassistant
containers.podman.podman_container:
state: quadlet
name: podman_homeassistant
image: ghcr.io/home-assistant/home-assistant:stable
network: bridge
volumes:
- "/home/admin/podman/homeassistant:/config"
- "/etc/localtime:/etc/localtime:ro"
ports:
- "8123:8123"
env:
TZ: "Europe/London"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: rutorrent
containers.podman.podman_container:
state: quadlet
name: podman_rutorrent
image: docker.io/crazymax/rtorrent-rutorrent:latest
network: bridge
volumes:
- "/home/admin/podman/rutorrent/passwd:/passwd"
- "/home/admin/podman/rutorrent/data:/data"
- "/mnt/media/torrents:/downloads"
ports:
- "8888:8080"
- "5000:8000"
- "50000:50000"
env:
TZ: "Europe/London"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: prowlarr
containers.podman.podman_container:
state: quadlet
name: podman_prowlarr
image: lscr.io/linuxserver/prowlarr:latest
network: bridge
volumes:
- "/home/admin/podman/prowlarr:/config"
ports:
- "9696:9696"
env:
TZ: "Europe/London"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: sonarr
containers.podman.podman_container:
state: quadlet
name: podman_sonarr
image: lscr.io/linuxserver/sonarr:latest
network: bridge
volumes:
- "/home/admin/podman/sonarr:/config"
- "/mnt/media/video/tv:/tv"
- "/mnt/media/torrents:/downloads"
ports:
- "8989:8989"
env:
TZ: "Europe/London"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: radarr
containers.podman.podman_container:
state: quadlet
name: podman_radarr
image: lscr.io/linuxserver/radarr:latest
network: bridge
volumes:
- "/home/admin/podman/radarr:/config"
- "/mnt/media/video/movies:/movies"
- "/mnt/media/torrents:/downloads"
ports:
- "7878:7878"
env:
TZ: "Europe/London"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: lidarr
containers.podman.podman_container:
state: quadlet
name: podman_lidarr
image: lscr.io/linuxserver/lidarr:latest
network: bridge
volumes:
- "/home/admin/podman/lidarr:/config"
- "/mnt/media/audio/music/flac:/music"
- "/mnt/media/torrents:/downloads"
ports:
- "8686:8686"
env:
TZ: "Europe/London"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: kiwix
containers.podman.podman_container:
state: quadlet
name: podman_kiwix
image: ghcr.io/kiwix/kiwix-serve:latest
network: bridge
command: "*.zim"
volumes:
- "/mnt/share/shared/Faris/1 documents/zim:/data"
ports:
- "8088:8080"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: immich-server
containers.podman.podman_container:
state: quadlet
name: podman_immich-server
image: "ghcr.io/immich-app/immich-server:{{ immich_version }}"
network: bridge
volumes:
- "/mnt/share/services/immich:/usr/src/app/upload"
- "/etc/localtime:/etc/localtime:ro"
ports:
- "2283:2283"
env_file:
- "/home/admin/podman/.env"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: immich-machine-learning
containers.podman.podman_container:
state: quadlet
name: podman_immich-machine-learning
image: "ghcr.io/immich-app/immich-machine-learning:{{ immich_version }}"
network: bridge
volumes:
- "/home/admin/podman/immich/cache:/cache"
env_file:
- "/home/admin/podman/.env"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: immich-redis
containers.podman.podman_container:
state: quadlet
name: podman_immich-redis
image: registry.hub.docker.com/library/redis:6.2-alpine
network: bridge
ports:
- "6379:6379"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: immich-db
containers.podman.podman_container:
state: quadlet
name: podman_immich-db
image: registry.hub.docker.com/tensorchord/pgvecto-rs:pg14-v0.2.0
network: bridge
env:
POSTGRES_PASSWORD: "{{ immich_db_password }}"
POSTGRES_USER: postgres
POSTGRES_DB: immich
volumes:
- "/home/admin/podman/immich/db:/var/lib/postgresql/data"
ports:
- "5433:5432"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target
- name: metube
containers.podman.podman_container:
state: quadlet
name: podman_metube
image: ghcr.io/alexta69/metube:latest
volumes:
- "/mnt/media/youtube-dl:/downloads"
- "/mnt/media/audio/music/flac:/music"
ports:
- "8081:8081"
env:
AUDIO_DOWNLOAD_DIR: "/music"
quadlet_options:
- "AutoUpdate=registry"
- "Pull=newer"
- |
[Install]
WantedBy=default.target

17
tasks/post-podman.yml Executable file
View File

@ -0,0 +1,17 @@
- name: reload systemd daemon
ansible.builtin.systemd_service:
scope: user
daemon_reload: true
- name: get list of all container services
ansible.builtin.shell:
cmd: "systemctl --user list-units --type=service --state=inactive --no-pager --quiet | grep 'podman_' | awk '{print $1}'"
register: inactive_containers
changed_when: false
- name: reload containers
ansible.builtin.systemd_service:
scope: user
state: started
name: "{{ item }}"
with_items: "{{ inactive_containers.stdout_lines }}"
when: inactive_containers.stdout_lines is defined

6
tasks/pre-podman.yml Executable file
View File

@ -0,0 +1,6 @@
---
- name: cleanup unused containers
ansible.builtin.file:
state: absent
path: /home/admin/.config/containers/systemd/

126
tasks/setup.yml Executable file
View File

@ -0,0 +1,126 @@
---
- name: set localtime (only needed for gitea and frigate)
become: true
ansible.builtin.file:
path: /usr/share/zoneinfo/Europe/London
dest: /etc/localtime
state: link
- name: set timezone (only neede for gitea)
become: true
ansible.builtin.shell:
cmd: echo "Europe/London" | tee /etc/timezone && dpkg-reconfigure -f noninteractive tzdata
changed_when: false
- name: Update apt and install required programs
become: true
ansible.builtin.apt:
pkg:
- gpg
- ansible
- cron
- curl
- git
- tmux
- podman
- neovim
- nfs-common
- fzf
- rsync
state: present
update_cache: true
- name: create mount directories
become: true
block:
- name: create /mnt/share
ansible.builtin.file:
path: /mnt/share
state: directory
- name: create /mnt/media
ansible.builtin.file:
path: /mnt/media
state: directory
- name: mount shares
become: true
block:
- name: mount data
ansible.posix.mount:
path: /mnt/share
src: "{{ truenas_ip }}:/mnt/pool/data"
fstype: nfs4
opts: defaults,auto,rw
state: mounted
- name: mount media
ansible.posix.mount:
path: /mnt/media
src: "{{ truenas_ip }}:/mnt/pool/media"
fstype: nfs4
opts: defaults,auto,rw
state: mounted
- name: setup backup
become: true
ansible.builtin.cron:
minute: "0"
hour: "4"
name: "backup"
user: "root"
job: "/bin/bash '/mnt/share/services/scripts/backup.sh'"
cron_file: backup
- name: check for podman folder
ansible.builtin.file:
path: /home/admin/podman
state: directory
# - name: initialize podman-compose
# become: true
# ignore_errors: true
# ansible.posix.synchronize:
# src: /mnt/share/DUNNO
# dest: /home/admin
# checksum: true
- name: change podman to overlayfs (system might need to be reset after this)
block:
- name: create directory if doesn't exist
ansible.builtin.file:
state: directory
path: /home/admin/.config/containers/
- name: create file if doesn't exist
ansible.builtin.file:
state: touch
path: /home/admin/.config/containers/storage.conf
- name: storage
ansible.builtin.lineinfile:
path: /home/admin/.config/containers/storage.conf
search_string: [storage]
line: [storage]
- name: overlay
ansible.builtin.lineinfile:
path: /home/admin/.config/containers/storage.conf
search_string: driver
line: driver = 'overlay'
- name: allow rootless podman to access ports below 1000
become: true
ansible.posix.sysctl:
name: net.ipv4.ip_unprivileged_port_start
value: 80
sysctl_file: /etc/sysctl.d/99-ports.conf
# this might not be needed, haven't tested
- name: allow rootless podmad (wireguard) to access net src
become: true
ansible.posix.sysctl:
name: net.ipv4.conf.all.src_valid_mark
value: 1
sysctl_file: /etc/sysctl.d/99-ports.conf
- name: enable linger (so user services start without login required)
ansible.builtin.shell:
cmd: loginctl enable-linger

2
vars Executable file
View File

@ -0,0 +1,2 @@
immich_version: v1.124.2
frigate_version: 0.14.1