diff --git a/ansible/assets/01-netcfg.yaml.j2 b/ansible/assets/basementpi/01-netcfg.yaml.j2 similarity index 100% rename from ansible/assets/01-netcfg.yaml.j2 rename to ansible/assets/basementpi/01-netcfg.yaml.j2 diff --git a/ansible/assets/docker-compose.yml.j2 b/ansible/assets/basementpi/compose.yml.j2 similarity index 97% rename from ansible/assets/docker-compose.yml.j2 rename to ansible/assets/basementpi/compose.yml.j2 index 3c0afea..364af87 100644 --- a/ansible/assets/docker-compose.yml.j2 +++ b/ansible/assets/basementpi/compose.yml.j2 @@ -81,6 +81,9 @@ services: - 'test.mycomputer.party:10.11.1.15' - 'matrix matrix.mycomputer.party:10.11.1.16' - 'wiki wiki.injust.us:10.11.1.13' + - 'git git.mycomputer.party:10.11.1.17' + - 'gitea gitea.injust.us:10.11.1.18' + - 'gitea.mycomputer.party:10.11.1.15' restart: always diff --git a/ansible/assets/ddclient.conf.j2 b/ansible/assets/basementpi/ddclient.conf.j2 similarity index 100% rename from ansible/assets/ddclient.conf.j2 rename to ansible/assets/basementpi/ddclient.conf.j2 diff --git a/ansible/assets/unbound.conf.j2 b/ansible/assets/basementpi/unbound.conf.j2 similarity index 100% rename from ansible/assets/unbound.conf.j2 rename to ansible/assets/basementpi/unbound.conf.j2 diff --git a/ansible/assets/bastion/wg0.conf b/ansible/assets/bastion/wg0.conf new file mode 100644 index 0000000..6a6a298 --- /dev/null +++ b/ansible/assets/bastion/wg0.conf @@ -0,0 +1,23 @@ +[Interface] +Address = 10.11.20.1/24 +#SaveConfig = true +ListenPort = 51820 +PrivateKey = uBjwOBqEeH/2V7qo5GLGQaX159I1YBztzxvYE9pXOnI= +#https://serverfault.com/questions/1162475/iptables-exclude-a-specific-port-from-being-forwarded-to-the-destination +PostUp = iptables -t nat -N Inbound +PostUp = iptables -t nat -A PREROUTING -d 51.222.155.202 -j Inbound +PostUp = iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE +PostUp = iptables -t nat -A Inbound -p tcp --dport 22 -j RETURN +PostUp = iptables -t nat -A Inbound -p tcp --dport 51820 -j RETURN +PostUp = iptables -t nat -A Inbound -p udp --dport 51820 -j RETURN +PostUp = iptables -t nat -A Inbound -s 10.11.1.15 -j RETURN +PostUp = iptables -t nat -A Inbound -j DNAT --to-destination 10.11.1.15 -p tcp --dport 80 +PostUp = iptables -t nat -A Inbound -j DNAT --to-destination 10.11.1.15 -p tcp --dport 443 +PostDown = iptables -D PREROUTING -d 51.222.155.202 -j Inbound -t nat +PostDown = iptables -D POSTROUTING -o ens3 -j MASQUERADE -t nat +PostDown = iptables -F Inbound -t nat +PostDown = iptables -X Inbound -t nat + +[Peer] +PublicKey = 84ITOv/sB0f/h7fIY+uLQeTmMDgTCjvVzIQmEsLAZmo= +AllowedIPs = 10.11.20.2/32,10.11.1.15/32 diff --git a/ansible/assets/bastion/wg0.conf.j2 b/ansible/assets/bastion/wg0.conf.j2 new file mode 100644 index 0000000..0b87907 --- /dev/null +++ b/ansible/assets/bastion/wg0.conf.j2 @@ -0,0 +1,22 @@ +[Interface] +Address = {{ wg_interface_ip }} +ListenPort = 51820 +PrivateKey = {{ wg_private_key}} +#https://serverfault.com/questions/1162475/iptables-exclude-a-specific-port-from-being-forwarded-to-the-destination +PostUp = iptables -t nat -N Inbound +PostUp = iptables -t nat -A PREROUTING -d {{ public_ip }} -j Inbound +PostUp = iptables -t nat -A POSTROUTING -o {{ wan_interface }} -j MASQUERADE +PostUp = iptables -t nat -A Inbound -p tcp --dport 22 -j RETURN +PostUp = iptables -t nat -A Inbound -p tcp --dport 51820 -j RETURN +PostUp = iptables -t nat -A Inbound -p udp --dport 51820 -j RETURN +PostUp = iptables -t nat -A Inbound -s {{ homeserver_private_ip }} -j RETURN +PostUp = iptables -t nat -A Inbound -j DNAT --to-destination {{ homeserver_private_ip }} -p tcp --dport 80 +PostUp = iptables -t nat -A Inbound -j DNAT --to-destination {{ homeserver_private_ip }} -p tcp --dport 443 +PostDown = iptables -D PREROUTING -d {{ public_ip }} -j Inbound -t nat +PostDown = iptables -D POSTROUTING -o {{ wan_interface }} -j MASQUERADE -t nat +PostDown = iptables -F Inbound -t nat +PostDown = iptables -X Inbound -t nat + +[Peer] +PublicKey = {{ homeserver_wg_public_key }} +AllowedIPs = {{ homeserver_wg_ip }}/32,{{ homeserver_private_ip }}/32 diff --git a/ansible/assets/docker-ext/compose.yml.j2 b/ansible/assets/docker-ext/compose.yml.j2 new file mode 100644 index 0000000..2adeebb --- /dev/null +++ b/ansible/assets/docker-ext/compose.yml.j2 @@ -0,0 +1,647 @@ +version: "3.5" +services: + traefik: + container_name: traefik + # The official v2 Traefik docker image + image: traefik:v3.1 + restart: unless-stopped + depends_on: + - crowdsec + # Enables the web UI and tells Traefik to listen to docker + command: + - "--api.insecure=true" + - "--providers.docker=true" + - "--providers.file=true" + - "--accesslog.filepath=/var/log/traefik/access.log" + - "--providers.file.filename=/etc/traefik/rules.yaml" + - "--entrypoints.web.address=:80" + - "--entrypoints.websecure.address=:443" + - "--certificatesresolvers.myresolver.acme.email=jg@justus.ws" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + - "--certificatesresolvers.myresolver.acme.httpchallenge.entrypoint=web" + - "--entrypoints.web.http.redirections.entrypoint.to=websecure" + - "--entrypoints.web.http.redirections.entrypoint.scheme=https" + - --experimental.plugins.crowdsec-bouncer.modulename=github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin + - --experimental.plugins.crowdsec-bouncer.version=v1.2.1 + #- "--certificatesresolvers.myresolver.acme.tlschallenge=true" + ports: + # The HTTP port + - "80:80" + - "443:443" + # The Web UI (enabled by --api.insecure=true) + - "8080:8080" + volumes: + # So that Traefik can listen to the Docker events + - /var/run/docker.sock:/var/run/docker.sock + #- ./traefik/traefik.yml:/etc/traefik/traefik.yml + - ./traefik:/etc/traefik + - ./letsencrypt:/letsencrypt + - "./logsTraefik:/var/log/traefik" + networks: + - proxy + - backend + - docker_default + labels: + - "traefik.http.middlewares.authtest.basicauth.users=user:$$apr1$$VKJibd3x$$SwY/BRH.QTeVEaRDnLKvv0" + - "traefik.http.middlewares.crowdsec.plugin.crowdsec-bouncer.enabled=true" + - "traefik.http.middlewares.crowdsec.plugin.crowdsec-bouncer.crowdseclapikey=dTkMpqDs/ryjvw1tQaV3k0VtCFQUlh+hrdZMEWnxfXc" + - "traefik.http.middlewares.authchain.chain.middlewares=crowdsec@docker,authentik@docker" + - "traefik.http.middlewares.internalOnly.ipallowlist.sourcerange=192.168.0.0/16, 10.0.0.0/8, 172.16.0.0/12" + - "traefik.http.middlewares.internalOnlyWithAuth.chain.middlewares=internalOnly@docker,crowdsec@docker,authentik@docker" + + #ddclient: + # image: lscr.io/linuxserver/ddclient:latest + # container_name: ddclient + # environment: + # - PUID=1000 + # - PGID=1000 + # - TZ=America/Thunder_Bay + # volumes: + # - ./ddclient/:/config + # restart: unless-stopped + #porkbunddns: + # image: pavlinchen/porkbun-ddns + # container_name: porkbun-ddns + # restart: unless-stopped + # pull_policy: always + # environment: + # APIKey: pk1_6896ac0da1af81d9b7ae1ef0ee65b7f8bc655fc0099588e1db9bb9708da2d2ec + # SecretAPIKey: k1_8c0d61edd906856c4f4f979b6207049ea0b0b50aec5759dacb86c24cb0bf001d + # Domain: mycomputer.party wiki + # Schedule: "*/5 * * * *" #optional + # TZ: Canada/Eastern #optional + dokuwiki: + image: bitnami/dokuwiki:20240206 + restart: unless-stopped + container_name: dokuwiki + ports: + - "8007:8080" + environment: + PHP_TIMEZONE: America/Toronto + DOKUWIKI_USERNAME: admin + volumes: + - ./dokuwiki:/bitnami/dokuwiki + networks: + - backend + labels: + - "traefik.enable=true" + - "traefik.http.routers.dokuwiki.rule=Host(`wiki.mycomputer.party`)" + - "traefik.http.routers.dokuwiki.entrypoints=websecure" + - "traefik.http.routers.dokuwiki.tls.certresolver=myresolver" + - traefik.http.routers.dokuwiki.tls=true + - "traefik.http.routers.dokuwiki.middlewares=crowdsec@docker" + mail-server: + tty: true + stdin_open: true + restart: unless-stopped + ports: + - 8443:443 + - 8008:8080 + - 25:25 + - 587:587 + - 465:465 + - 143:143 + - 993:993 + - 4190:4190 + volumes: + - ./stalwart-mail:/opt/stalwart-mail + container_name: stalwart-mail + image: stalwartlabs/mail-server:latest + labels: + - "traefik.enable=true" + - "traefik.http.routers.stalwart.rule=Host(`stalwart.mycomputer.party`)" + - "traefik.http.routers.stalwart.entrypoints=websecure" + - "traefik.http.routers.stalwart.tls.certresolver=myresolver" + - "traefik.http.routers.stalwart.tls=true" + - "traefik.http.services.stalwart-http.loadbalancer.server.port=8080" + # --- MariaDB + #linkace-db: + # image: mariadb:11.2 + # container_name: linkace-db + # restart: unless-stopped + # command: mariadbd --character-set-server=utf8mb4 --collation-server=utf8mb4_bin + # environment: + # - MYSQL_ROOT_PASSWORD=LRd5^AwDF76CvE6fMb + # - MYSQL_USER=linkace + # - MYSQL_PASSWORD=linkace + # - MYSQL_DATABASE=linkace + # volumes: + # - db:/var/lib/mysql + + ## --- LinkAce Image with PHP and nginx + #linkace-app: + # image: linkace/linkace:simple + # container_name: linkace-app + # restart: unless-stopped + # depends_on: + # - linkace-db + # ports: + # - "8009:80" + # #- "0.0.0.0:443:443" + # volumes: + # - ./linkace/.env:/app/.env + # - ./linkace/backups:/app/storage/app/backups + # - linkace_logs:/app/storage/logs + # # Remove the hash of the following line if you want to use HTTPS for this container + # #- ./nginx-ssl.conf:/etc/nginx/conf.d/default.conf:ro + # #- /path/to/your/ssl/certificates:/certs:ro + # labels: + # - "traefik.enable=true" + # - "traefik.http.routers.linkace.rule=Host(`linkace.mycomputer.party`)" + # - "traefik.http.routers.linkace.entrypoints=websecure" + # - "traefik.http.routers.linkace.tls.certresolver=myresolver" + # - "traefik.http.routers.linkace.tls=true" + # - "traefik.http.services.linkace-http.loadbalancer.server.port=80" + + linkding: + container_name: "${LD_CONTAINER_NAME:-linkding}" + image: sissbruecker/linkding:latest-plus + ports: + - "${LD_HOST_PORT:-9090}:9090" + volumes: + - "${LD_HOST_DATA_DIR:-./data}:/etc/linkding/data" + env_file: + - .env-linkding + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.http.routers.linkding.rule=Host(`linkding.mycomputer.party`)" + - "traefik.http.routers.linkding.entrypoints=websecure" + - "traefik.http.routers.linkding.tls.certresolver=myresolver" + - "traefik.http.routers.linkding.tls=true" + - "traefik.http.services.linkding-http.loadbalancer.server.port=9090" + - "traefik.http.routers.linkding.middlewares=authchain@docker" + wallabag: + container_name: wallabag + restart: unless-stopped + image: wallabag/wallabag + environment: + #- MYSQL_ROOT_PASSWORD=wallaroot + - POSTGRES_USER=wallabag + - POSTGRES_PASSWORD=Mo8ntF92q5oWNV6TbS7t + - SYMFONY__ENV__DATABASE_DRIVER=pdo_pgsql + - SYMFONY__ENV__DATABASE_HOST=postgres.injust.us + - SYMFONY__ENV__DATABASE_PORT=5432 + - SYMFONY__ENV__DATABASE_NAME=wallabag + - SYMFONY__ENV__DATABASE_USER=wallabag + - SYMFONY__ENV__DATABASE_PASSWORD=Mo8ntF92q5oWNV6TbS7t + - SYMFONY__ENV__DATABASE_TABLE_PREFIX="wallabag_" + - SYMFONY__ENV__MAILER_DSN=smtp://127.0.0.1 + - SYMFONY__ENV__FROM_EMAIL=wallabag@example.com + - SYMFONY__ENV__DOMAIN_NAME=https://wallabag.mycomputer.party + - SYMFONY__ENV__SERVER_NAME="My Computer Party Wallabag" + ports: + - "8010:80" + volumes: + - ./wallabag/images:/var/www/wallabag/web/assets/images + healthcheck: + test: ["CMD", "wget" ,"--no-verbose", "--tries=1", "--spider", "http://localhost"] + interval: 1m + timeout: 3s + depends_on: + - redis + labels: + - "traefik.enable=true" + - "traefik.http.routers.wallabag.rule=Host(`wallabag.mycomputer.party`)" + - "traefik.http.routers.wallabag.entrypoints=websecure" + - "traefik.http.routers.wallabag.tls.certresolver=myresolver" + - "traefik.http.routers.wallabag.tls=true" + - "traefik.http.services.wallabag-http.loadbalancer.server.port=80" + - "traefik.http.routers.wallabag.middlewares=crowdsec@docker" + redis: + container_name: redis + image: redis:alpine + restart: unless-stopped + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 20s + timeout: 3s + authentik-server: + container_name: authentik-server + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.8.2} + restart: unless-stopped + command: server + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_HOST: https://authentik.mycomputer.party + AUTHENTIK_POSTGRESQL__HOST: postgres.injust.us + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_PG_PASS} + volumes: + - ./authentik/media:/media + - ./authentik/custom-templates:/templates + env_file: + - .authentik-env + ports: + - "${COMPOSE_PORT_HTTP:-9000}:9000" + - "${COMPOSE_PORT_HTTPS:-9443}:9443" + depends_on: + - redis + labels: + - "traefik.enable=true" + #- "traefik.http.routers.authentik.rule=Host(`authentik.mycomputer.party`)" + - "traefik.http.routers.authentik.rule=Host(`authentik.mycomputer.party`) || PathPrefix(`/outpost.goauthentik.io/`)" + - "traefik.http.routers.authentik.entrypoints=websecure" + - "traefik.http.routers.authentik.tls.certresolver=myresolver" + - "traefik.http.routers.authentik.tls=true" + - "traefik.http.services.authentik-http.loadbalancer.server.port=9000" + - "traefik.http.middlewares.authentik.forwardauth.address=http://authentik-server:9000/outpost.goauthentik.io/auth/traefik" + - "traefik.http.middlewares.authentik.forwardauth.trustForwardHeader=true" + - "traefik.http.middlewares.authentik.forwardauth.authResponseHeaders=X-authentik-username,X-authentik-groups,X-authentik-email,X-authentik-name,X-authentik-uid,X-authentik-jwt,X-authentik-meta-jwks,X-authentik-meta-outpost,X-authentik-meta-provider,X-authentik-meta-app,X-authentik-meta-version" + - "traefik.http.routers.authentik.middlewares=crowdsec@docker" + authentik-worker: + container_name: authentik-worker + image: ${AUTHENTIK_IMAGE:-ghcr.io/goauthentik/server}:${AUTHENTIK_TAG:-2024.8.2} + restart: unless-stopped + command: worker + environment: + AUTHENTIK_REDIS__HOST: redis + AUTHENTIK_POSTGRESQL__HOST: postgres.injust.us + AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} + AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} + AUTHENTIK_POSTGRESQL__PASSWORD: ${AUTHENTIK_PG_PASS} + # `user: root` and the docker socket volume are optional. + # See more for the docker socket integration here: + # https://goauthentik.io/docs/outposts/integrations/docker + # Removing `user: root` also prevents the worker from fixing the permissions + # on the mounted folders, so when removing this make sure the folders have the correct UID/GID + # (1000:1000 by default) + user: root + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./authentik/media:/media + - ./authentik/certs:/certs + - ./authentik/custom-templates:/templates + env_file: + - .authentik-env + depends_on: + - redis + changedetection: + image: ghcr.io/dgtlmoon/changedetection.io + container_name: changedetection + hostname: changedetection + volumes: + - changedetection-data:/datastore +# Configurable proxy list support, see https://github.com/dgtlmoon/changedetection.io/wiki/Proxy-configuration#proxy-list-support +# - ./proxies.json:/datastore/proxies.json + + environment: + # Default listening port, can also be changed with the -p option + # - PORT=5000 + + # - PUID=1000 + # - PGID=1000 + # + # Log levels are in descending order. (TRACE is the most detailed one) + # Log output levels: TRACE, DEBUG(default), INFO, SUCCESS, WARNING, ERROR, CRITICAL + # - LOGGER_LEVEL=DEBUG + # + # Alternative WebDriver/selenium URL, do not use "'s or 's! + # - WEBDRIVER_URL=http://browser-chrome:4444/wd/hub + # + # WebDriver proxy settings webdriver_proxyType, webdriver_ftpProxy, webdriver_noProxy, + # webdriver_proxyAutoconfigUrl, webdriver_autodetect, + # webdriver_socksProxy, webdriver_socksUsername, webdriver_socksVersion, webdriver_socksPassword + # + # https://selenium-python.readthedocs.io/api.html#module-selenium.webdriver.common.proxy + # + # Alternative Playwright URL, do not use "'s or 's! + # - PLAYWRIGHT_DRIVER_URL=ws://playwright-chrome:3000 + # + # Playwright proxy settings playwright_proxy_server, playwright_proxy_bypass, playwright_proxy_username, playwright_proxy_password + # + # https://playwright.dev/python/docs/api/class-browsertype#browser-type-launch-option-proxy + # + # Plain requests - proxy support example. + # - HTTP_PROXY=socks5h://10.10.1.10:1080 + # - HTTPS_PROXY=socks5h://10.10.1.10:1080 + # + # An exclude list (useful for notification URLs above) can be specified by with + # - NO_PROXY="localhost,192.168.0.0/24" + # + # Base URL of your changedetection.io install (Added to the notification alert) + - BASE_URL=https://changedetection.mycomputer.party + # Respect proxy_pass type settings, `proxy_set_header Host "localhost";` and `proxy_set_header X-Forwarded-Prefix /app;` + # More here https://github.com/dgtlmoon/changedetection.io/wiki/Running-changedetection.io-behind-a-reverse-proxy-sub-directory + - USE_X_SETTINGS=1 + # + # Hides the `Referer` header so that monitored websites can't see the changedetection.io hostname. + #- HIDE_REFERER=true + # + # Default number of parallel/concurrent fetchers + # - FETCH_WORKERS=10 + + # Comment out ports: when using behind a reverse proxy , enable networks: etc. + ports: + - 5000:5000 + restart: unless-stopped + labels: + - "traefik.enable=true" + - "traefik.http.routers.changedetection.rule=Host(`changedetection.mycomputer.party`)" + - "traefik.http.routers.changedetection.entrypoints=websecure" + - "traefik.http.routers.changedetection.tls.certresolver=myresolver" + - "traefik.http.routers.changedetection.tls=true" + - "traefik.http.services.changedetection-http.loadbalancer.server.port=5000" + - "traefik.http.routers.changedetection.middlewares=authchain@docker" + + # Used for fetching pages via WebDriver+Chrome where you need Javascript support. + # Now working on arm64 (needs testing on rPi - tested on Oracle ARM instance) + # replace image with seleniarm/standalone-chromium:4.0.0-20211213 + + # If WEBDRIVER or PLAYWRIGHT are enabled, changedetection container depends on that + # and must wait before starting (substitute "browser-chrome" with "playwright-chrome" if last one is used) +# depends_on: +# browser-chrome: +# condition: service_started + + # Used for fetching pages via Playwright+Chrome where you need Javascript support. + # RECOMMENDED FOR FETCHING PAGES WITH CHROME +# playwright-chrome: +# hostname: playwright-chrome +# image: dgtlmoon/sockpuppetbrowser:latest +# cap_add: +# - SYS_ADMIN +## SYS_ADMIN might be too much, but it can be needed on your platform https://github.com/puppeteer/puppeteer/blob/main/docs/troubleshooting.md#running-puppeteer-on-gitlabci +# restart: unless-stopped +# environment: +# - SCREEN_WIDTH=1920 +# - SCREEN_HEIGHT=1024 +# - SCREEN_DEPTH=16 +# - MAX_CONCURRENT_CHROME_PROCESSES=10 + + # Used for fetching pages via Playwright+Chrome where you need Javascript support. + # Note: Works well but is deprecated, does not fetch full page screenshots (doesnt work with Visual Selector) + # Does not report status codes (200, 404, 403) and other issues +# browser-chrome: +# hostname: browser-chrome +# image: selenium/standalone-chrome:4 +# environment: +# - VNC_NO_PASSWORD=1 +# - SCREEN_WIDTH=1920 +# - SCREEN_HEIGHT=1080 +# - SCREEN_DEPTH=24 +# volumes: +# # Workaround to avoid the browser crashing inside a docker container +# # See https://github.com/SeleniumHQ/docker-selenium#quick-start +# - /dev/shm:/dev/shm +# restart: unless-stopped + + healthchecks: + container_name: healthchecks + restart: unless-stopped + # To use a pre-built image, remove the above "build" section + # and uncomment the following line: + image: healthchecks/healthchecks:latest + env_file: + - .healthchecks-env + ports: + - "8011:8000" + # To enable SMTP on port 2525, set SMTPD_PORT=2525 in .env + # and uncomment the following line: + # - "2525:2525" + command: bash -c 'uwsgi /opt/healthchecks/docker/uwsgi.ini' + labels: + - "traefik.enable=true" + - "traefik.http.routers.healthchecks.rule=Host(`healthchecks.mycomputer.party`)" + - "traefik.http.routers.healthchecks.entrypoints=websecure" + - "traefik.http.routers.healthchecks.tls.certresolver=myresolver" + - "traefik.http.routers.healthchecks.tls=true" + - "traefik.http.services.healthchecks-http.loadbalancer.server.port=8000" + - "traefik.http.routers.healthchecks.middlewares=authchain@docker" + apache: + image: php:7.2-apache + volumes: + - ./apache:/var/www/html + ports: + - 8012:80 + container_name: apache + labels: + - "traefik.enable=true" + - "traefik.http.routers.apache.rule=Host(`apache.mycomputer.party`)" + - "traefik.http.routers.apache.entrypoints=websecure" + - "traefik.http.routers.apache.tls.certresolver=myresolver" + - "traefik.http.routers.apache.tls=true" + - "traefik.http.services.apache-http.loadbalancer.server.port=80" + - "traefik.http.routers.apache.middlewares=internalOnlyWithAuth@docker" + networks: + - backend + apache2: + image: php:7.2-apache + volumes: + - ./apache:/var/www/html + ports: + - 8013:80 + container_name: apache2 + labels: + - "traefik.enable=true" + - "traefik.http.routers.apache2.rule=Host(`apache2.mycomputer.party`)" + - "traefik.http.routers.apache2.entrypoints=websecure" + - "traefik.http.routers.apache2.tls.certresolver=myresolver" + - "traefik.http.routers.apache2.tls=true" + - "traefik.http.services.apache2-http.loadbalancer.server.port=80" + #- traefik.http.routers.apache2.middlewares=authchain@docker + networks: + - backend + + #wireguard: + # image: lscr.io/linuxserver/wireguard + # container_name: wireguard + # cap_add: + # - NET_ADMIN + # - SYS_MODULE + # environment: + # - PUID=1001 + # - PGID=1001 + # - TZ=America/Thunder_Bay + # - PEERS=thelma + # - INTERNAL_SUBNET=10.11.20.0/24 + # - ALLOWEDIPS=10.11.0.0/16 + # volumes: + # - ./wireguard:/config + # - /lib/modules:/lib/modules + # networks: + # wireguard: + # ipv4_address: 172.20.0.50 + # sysctls: + # - net.ipv4.conf.all.src_valid_mark=1 + # restart: unless-stopped + crowdsec: + image: crowdsecurity/crowdsec + container_name: crowdsec + environment: + PGID: "1001" + COLLECTIONS: "crowdsecurity/sshd crowdsecurity/linux crowdsecurity/traefik crowdsecurity/http-cve firix/authentik" + ports: + - 8081:8080 + expose: + - "8080" + volumes: + #- ./crowdsec/logs:/var/log/crowdsec:ro + - ./crowdsec/db:/var/lib/crowdsec/data + - /var/log:/var/log:ro + - ./crowdsec/opt:/etc/crowdsec + - ./logsTraefik:/logs/traefik:ro + - /var/run/docker.sock:/var/run/docker.sock #To read container logs, can use socket-proxy instead + restart: unless-stopped + labels: + - "traefik.enable=false" + #- "traefik.http.routers.crowdsec.rule=Host(`crowdsec.mycomputer.party`)" + #- "traefik.http.routers.crowdsec.entrypoints=websecure" + #- "traefik.http.routers.crowdsec.tls.certresolver=myresolver" + #- "traefik.http.routers.crowdsec.tls=true" + networks: + - proxy + - backend + ddns-updater: + image: docker.io/qmcgaw/ddns-updater + container_name: ddns-updater + ports: + - 8014:8000 + volumes: + - ./ddns-updater:/updater/data + bookstack: + image: lscr.io/linuxserver/bookstack + container_name: bookstack + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Thunder_Bay + - APP_URL=https://bookstack.mycomputer.party + - DB_HOST=bookstack_db + - DB_PORT=3306 + - DB_USER=bookstack + - DB_PASS=Chn8i#ExmX@J1C + - DB_DATABASE=bookstackapp + env_file: + - .env-bookstack + volumes: + - /path/to/bookstack_app_data:/config + ports: + - 6875:80 + restart: unless-stopped + depends_on: + - bookstack_db + labels: + - "traefik.enable=true" + - "traefik.http.routers.bookstack.rule=Host(`bookstack.mycomputer.party`)" + - "traefik.http.routers.bookstack.entrypoints=websecure" + - "traefik.http.routers.bookstack.tls.certresolver=myresolver" + - "traefik.http.routers.bookstack.tls=true" + bookstack_db: + image: lscr.io/linuxserver/mariadb + container_name: bookstack_db + environment: + - PUID=1000 + - PGID=1000 + - TZ=America/Thunder_Bay + - MYSQL_ROOT_PASSWORD=cSoO1dcaS5sI&t + - MYSQL_DATABASE=bookstackapp + - MYSQL_USER=bookstack + - MYSQL_PASSWORD=Chn8i#ExmX@J1C + volumes: + - ./bookstack_db_data:/config + restart: unless-stopped + wikijs: + image: ghcr.io/requarks/wiki:2 + container_name: wikijs + environment: + DB_TYPE: postgres + DB_HOST: postgres.injust.us + DB_PORT: 5432 + DB_USER: wikijs + DB_PASS: 3Jfr7nmY4KBauR3nuHno + DB_NAME: wikijs + restart: unless-stopped + labels: + - "traefik.http.routers.wiki.rule=Host(`wikijs.mycomputer.party`)" + - traefik.http.routers.wiki.tls=true + - "traefik.http.routers.wiki.entrypoints=websecure" + - "traefik.http.routers.wiki.tls.certresolver=myresolver" + + # immich-server: + # container_name: immich_server + # image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} + # # extends: + # # file: hwaccel.transcoding.yml + # # service: cpu # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding + # volumes: + # # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file + # - ${UPLOAD_LOCATION}:/usr/src/app/upload + # - /etc/localtime:/etc/localtime:ro + # env_file: + # - .env-immich + # ports: + # - 2283:3001 + # depends_on: + # - redis + # #- database + # restart: always + # healthcheck: + # disable: false + # database: + # container_name: immich_postgres + # image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 + # environment: + # POSTGRES_PASSWORD: ${DB_PASSWORD} + # POSTGRES_USER: ${DB_USERNAME} + # POSTGRES_DB: ${DB_DATABASE_NAME} + # POSTGRES_INITDB_ARGS: '--data-checksums' + # volumes: + # # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file + # - ${DB_DATA_LOCATION}:/var/lib/postgresql/data + # healthcheck: + # test: pg_isready --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' || exit 1; Chksum="$$(psql --dbname='${DB_DATABASE_NAME}' --username='${DB_USERNAME}' --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1 + # interval: 5m + # start_interval: 30s + # start_period: 5m + # command: ["postgres", "-c", "shared_preload_libraries=vectors.so", "-c", 'search_path="$$user", public, vectors', "-c", "logging_collector=on", "-c", "max_wal_size=2GB", "-c", "shared_buffers=512MB", "-c", "wal_compression=on"] + # restart: always + # + # immich-machine-learning: + # container_name: immich_machine_learning + # # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag. + # # Example tag: ${IMMICH_VERSION:-release}-cuda + # image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} + # # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration + # # file: hwaccel.ml.yml + # # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable + # volumes: + # - model-cache:/cache + # env_file: + # - .env-immich + # restart: always + # healthcheck: + # disable: false + # + # # redis: + # # container_name: immich_redis + # # image: docker.io/redis:6.2-alpine@sha256:2d1463258f2764328496376f5d965f20c6a67f66ea2b06dc42af351f75248792 + # # healthcheck: + # # test: redis-cli ping || exit 1 + # # restart: always + + + + +volumes: + linkace_logs: + db: + driver: local + changedetection-data: + model-cache: + +networks: + wireguard: + name: wireguard + ipam: + driver: default + config: + - subnet: "172.20.0.0/24" + backend: + proxy: + docker_default: + external: True + + + diff --git a/ansible/assets/docker-ext/rules.yaml.j2 b/ansible/assets/docker-ext/rules.yaml.j2 new file mode 100644 index 0000000..8ec983d --- /dev/null +++ b/ansible/assets/docker-ext/rules.yaml.j2 @@ -0,0 +1,22 @@ +http: + routers: + router-gitea: + entryPoints: + - websecure + rule: Host(`gitea.mycomputer.party`) + service: service-gitea + tls: + certResolver: myresolver + + services: + service-gitea: + loadBalancer: + servers: + - url: "http://gitea.injust.us:3000" + + #certificatesResolvers: + # myresolver: + # email: jg@justus.ws + # storage: /letsencrypt/acme_fileprovider.json + # httpChallenge: + # entryPoint: web diff --git a/ansible/assets/docker-ext/wg0.conf.j2 b/ansible/assets/docker-ext/wg0.conf.j2 new file mode 100644 index 0000000..07f0840 --- /dev/null +++ b/ansible/assets/docker-ext/wg0.conf.j2 @@ -0,0 +1,9 @@ +[Interface] +PrivateKey = {{ docker-ext_wg_private_key }} +Address = 10.11.20.2/24 + +[Peer] +PublicKey = s3Ch/zcv5IeSpIbHBT5pdzpHWwV2qh4Z9W/0DSZg/CQ= +AllowedIPs = 0.0.0.0/0 +Endpoint = vps.mycomputer.party:51820 +PersistentKeepalive = 25 diff --git a/ansible/assets/docker-int/compose.yml.j2 b/ansible/assets/docker-int/compose.yml.j2 new file mode 100644 index 0000000..b83d528 --- /dev/null +++ b/ansible/assets/docker-int/compose.yml.j2 @@ -0,0 +1,171 @@ +version: '3.3' +services: + traefik: + container_name: traefik + # The official v2 Traefik docker image + image: traefik:v2.11 + # Enables the web UI and tells Traefik to listen to docker + command: + - --api.insecure=true + - --providers.docker + - "--log.filePath=/var/log/traefik/traefik.log" + - "--entryPoints.web.address=:80" + - "--entryPoints.websecure.address=:443" + - "--certificatesresolvers.myresolver.acme.dnschallenge=true" + - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=cloudflare" + #- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory" + - "--certificatesresolvers.myresolver.acme.email=jg@justus.ws" + - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" + ports: + # The HTTP port + - "80:80" + - "443:443" + # The Web UI (enabled by --api.insecure=true) + - "8080:8080" + volumes: + # So that Traefik can listen to the Docker events + - /var/run/docker.sock:/var/run/docker.sock + - "./letsencrypt:/letsencrypt" + - "./logsTraefik:/var/log/traefik" + environment: + - "CF_API_KEY=4fa4711ae24bd19c1c17a06ce2ec6b3fa7629" + - "CF_API_EMAIL=jg@justus.ws" + #squid: + # container_name: squid + # volumes: + # #- '/root/docker/squid/logs:/var/log/squid' + # # - '/root/docker/squid/data:/var/spool/squid' + # - '/root/docker/squid/squid.conf:/etc/squid/squid.conf' + # # - '/rood/docker/squid/config-snippet:/etc/squid/conf.d/snippet.conf' + # environment: + # - TZ=America/Thunder_Bay + # ports: + # - '3128:3128' + # image: 'ubuntu/squid:5.2-22.04_beta' + # #yacy_search_server: + # # container_name: yacy + # # ports: + # # - '8090:8090' + # # - '8443:8443' + # # logging: + # # options: + # # max-size: 200 + # # max-file: 2 + # # image: 'yacy/yacy_search_server:latest' + paperless-broker: + image: docker.io/library/redis:7 + container_name: paperless-broker + restart: unless-stopped + volumes: + - redisdata:/data + + # db: + # image: docker.io/library/postgres:15 + # restart: unless-stopped + # volumes: + # - pgdata:/var/lib/postgresql/data + # environment: + # POSTGRES_DB: paperless + # POSTGRES_USER: paperless + # POSTGRES_PASSWORD: paperless + + paperless-webserver: + image: ghcr.io/paperless-ngx/paperless-ngx:latest + container_name: paperless-webserver + restart: unless-stopped + depends_on: + # - db + - paperless-broker + ports: + - "8000:8000" + volumes: + - data:/usr/src/paperless/data + - media:/usr/src/paperless/media + - export:/usr/src/paperless/export + - consume:/usr/src/paperless/consume + env_file: docker-compose.env + #environment: + labels: + - "traefik.http.routers.paperless.rule=Host(`paperless.injust.us`)" + - "traefik.http.routers.paperless.entrypoints=websecure" + - traefik.http.routers.paperless.tls=true + - "traefik.http.routers.paperless.tls.certresolver=myresolver" + webdav: + container_name: webdav + image: ionelmc/webdav + restart: unless-stopped + ports: + - "8081:8080" + environment: + WEBDAV_USERNAME: alice + WEBDAV_PASSWORD: secret1234 + UID: 1001 + volumes: + - ./consume:/media + #webdav: + # container_name: webdav + # image: bytemark/webdav + # restart: unless-stopped + # ports: + # - "8081:80" + # environment: + # AUTH_TYPE: Digest + # USERNAME: alice + # PASSWORD: secret1234 + # volumes: + # - consume:/var/lib/dav/data/ScannerPro + labels: + - "traefik.http.routers.webdav.rule=Host(`webdav.injust.us`)" + testweb: + image: httpd:2.4 + ports: + - "8008:80" + volumes: + - ./htdocs:/usr/local/apache2/htdocs/ + labels: + - "traefik.http.routers.testweb.rule=Host(`testweb.injust.us`)" + - traefik.http.routers.testweb.tls=true + - "traefik.http.routers.testweb.entrypoints=websecure" + - "traefik.http.routers.testweb.tls.certresolver=myresolver" + actual_server: + image: docker.io/actualbudget/actual-server:latest + ports: + # This line makes Actual available at port 5006 of the device you run the server on, + # i.e. http://localhost:5006. You can change the first number to change the port, if you want. + - '5006:5006' + #environment: + # Uncomment any of the lines below to set configuration options. + # - ACTUAL_HTTPS_KEY=/data/selfhost.key + # - ACTUAL_HTTPS_CERT=/data/selfhost.crt + # - ACTUAL_PORT=5006 + # - ACTUAL_UPLOAD_FILE_SYNC_SIZE_LIMIT_MB=20 + # - ACTUAL_UPLOAD_SYNC_ENCRYPTED_FILE_SYNC_SIZE_LIMIT_MB=50 + # - ACTUAL_UPLOAD_FILE_SIZE_LIMIT_MB=20 + # See all options and more details at https://actualbudget.github.io/docs/Installing/Configuration + # !! If you are not using any of these options, remove the 'environment:' tag entirely. + volumes: + # Change './actual-data' below to the path to the folder you want Actual to store its data in on your server. + # '/data' is the path Actual will look for its files in by default, so leave that as-is. + - ./actual-data:/data + labels: + - "traefik.http.routers.actual.rule=Host(`actual.injust.us`)" + - traefik.http.routers.actual.tls=true + - "traefik.http.routers.actual.entrypoints=websecure" + - "traefik.http.routers.actual.tls.certresolver=myresolver" + restart: unless-stopped + +volumes: + data: + media: + pgdata: + redisdata: + consume: + driver_opts: + type: "nfs" + o: "addr=omv.injust.us,nolock,soft,rw" + device: ":/export/Paperless" + export: + driver_opts: + type: "nfs" + o: "addr=omv.injust.us,nolock,soft,rw" + device: ":/export/Paperless_Export" diff --git a/ansible/assets/git/compose.yml.j2 b/ansible/assets/git/compose.yml.j2 new file mode 100644 index 0000000..1723562 --- /dev/null +++ b/ansible/assets/git/compose.yml.j2 @@ -0,0 +1,30 @@ +version: "3" + +networks: + gitea: + external: false + +volumes: + gitea: + driver: local + +services: + server: + image: gitea/gitea:1.22.3 + container_name: gitea + restart: unless-stopped + environment: + - GITEA__database__DB_TYPE=postgres + - GITEA__database__HOST=postgres:5432 + - GITEA__database__NAME={{ gitea_db_name }} + - GITEA__database__USER={{ gitea_db_user }} + - GITEA__database__PASSWD={{ vault_gitea_db_password }} + networks: + - gitea + volumes: + - gitea:/data + - /etc/timezone:/etc/timezone:ro + - /etc/localtime:/etc/localtime:ro + ports: + - "3000:3000" + - "222:22" diff --git a/ansible/assets/gitea/compose.yml.j2 b/ansible/assets/gitea/compose.yml.j2 new file mode 100644 index 0000000..70fff78 --- /dev/null +++ b/ansible/assets/gitea/compose.yml.j2 @@ -0,0 +1,13 @@ +version: '3.3' +services: + runner: + image: gitea/act_runner:nightly + environment: + CONFIG_FILE: /config.yaml + GITEA_INSTANCE_URL: "{{ gitea_instance_url }}" + GITEA_RUNNER_REGISTRATION_TOKEN: "{{ gitea_runner_token }}" + GITEA_RUNNER_NAME: "{{ gitea_runner_name }}" + volumes: + - ./config.yaml:/config.yaml + - ./data:/data + - /var/run/docker.sock:/var/run/docker.sock diff --git a/ansible/setup.yaml b/ansible/buildHomelab.yaml similarity index 50% rename from ansible/setup.yaml rename to ansible/buildHomelab.yaml index 1477dd6..409a4a3 100644 --- a/ansible/setup.yaml +++ b/ansible/buildHomelab.yaml @@ -1,6 +1,6 @@ --- -- name: Setup - hosts: all +- name: Setup pi + hosts: basementpi remote_user: root vars: @@ -13,37 +13,19 @@ - name: Copy netplan ansible.builtin.template: - src: assets/01-netcfg.yaml.j2 + src: assets/{{ inventory_hostname }}/01-netcfg.yaml.j2 dest: /etc/netplan + backup: true - name: Copy unbound config ansible.builtin.template: - src: assets/unbound.conf.j2 + src: assets/{{ inventory_hostname }}/unbound.conf.j2 dest: ./unbound/ + backup: true - name: Apply Netplan ansible.builtin.command: netplan apply - - name: Docker Prereqs - ansible.builtin.apt: - update_cache: true - name: - - ca-certificates - - curl - - gnupg - - lsb-release - - name: Create keyring directory - ansible.builtin.file: - path: /etc/apt/keyrings - state: directory - - name: Create Docker directory - ansible.builtin.file: - path: /root/docker - state: directory - - name: Download Docker GPG keys - ansible.builtin.shell: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg --batch --yes - - name: Add Docker repo - ansible.builtin.shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null - name: Disable Ubunut stub DNS resolver ansible.builtin.shell: sed -r -i.orig 's/#?DNSStubListener=yes/DNSStubListener=no/g' /etc/systemd/resolved.conf @@ -58,31 +40,61 @@ update_cache: true name: - restic - - - name: Install Docker - ansible.builtin.apt: - update_cache: true - name: - - docker-ce - - docker-ce-cli - - containerd.io - - docker-compose-plugin - - name: Copy Docker Compose file - ansible.builtin.template: - src: assets/docker-compose.yml.j2 - dest: /root/docker/docker-compose.yml - tags: wireguard,docker - name: Copy ddclient config ansible.builtin.template: - src: assets/ddclient.conf.j2 + src: assets/{{ inventory_hostname }}/ddclient.conf.j2 dest: /root/docker/ddclient/ddclient.conf - tags: docker + backup: true + +- name: Setup bastion + hosts: bastion + vars: + tags: + - bastion + roles: + - bastion +- name: Configure Docker hosts + hosts: + - docker + vars: + tags: + - docker + - docker_hosts + tasks: + - name: Copy Docker Compose file + ansible.builtin.template: + src: assets/{{ inventory_hostname }}/compose.yml.j2 + dest: /root/docker/compose.yml + backup: true - name: Run Docker ansible.builtin.shell: docker compose up -d --remove-orphans args: chdir: /root/docker - tags: wireguard,docker + +- name: Local server Wireguard + hosts: + - docker-ext + tags: + - bastion + tasks: + - name: "Local server Wireguard" + ansible.builtin.template: + src: assets/{{ inventory_hostname }}/wg0.conf.j2 + dest: /etc/wireguard/wg0.conf + backup: true + +- name: Traefik config + hosts: + - docker-ext + tags: + - traefik + tasks: + - name: "Traefik rules" + ansible.builtin.template: + src: assets/{{ inventory_hostname }}/rules.yaml.j2 + dest: /root/docker/traefik/rules.yaml + backup: true diff --git a/ansible/install_docker.yaml b/ansible/install_docker.yaml new file mode 100644 index 0000000..7e4a3e4 --- /dev/null +++ b/ansible/install_docker.yaml @@ -0,0 +1,43 @@ +- name: Setup Docker hosts + hosts: + - docker + - gitea + vars: + tasks: + - name: Docker Prereqs + ansible.builtin.apt: + update_cache: true + name: + - ca-certificates + - curl + - gnupg + - lsb-release + - name: Create keyring directory + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + - name: Create Docker directory + ansible.builtin.file: + path: /root/docker + state: directory +## TODO: Detect OS + # - name: Download Docker GPG keys + # ansible.builtin.shell: curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg --batch --yes + # - name: Add Docker repo + # ansible.builtin.shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null + - name: Install Docker keyring + ansible.builtin.shell: install -m 0755 -d /etc/apt/keyrings + - name: Download Docker GPG keys + ansible.builtin.shell: curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc + - name: chmod keyring + ansible.builtin.shell: chmod a+r /etc/apt/keyrings/docker.asc + - name: Add Docker repo + ansible.builtin.shell: echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null + - name: Install Docker + ansible.builtin.apt: + update_cache: true + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-compose-plugin diff --git a/ansible/install_gitea.yaml b/ansible/install_gitea.yaml new file mode 100644 index 0000000..64c6f5d --- /dev/null +++ b/ansible/install_gitea.yaml @@ -0,0 +1,7 @@ +--- +- name: Install Gitea + hosts: + - gitea + roles: + - install_gitea + diff --git a/ansible/inventory/host_vars/all/vars b/ansible/inventory/host_vars/all/vars new file mode 100644 index 0000000..ae0a96d --- /dev/null +++ b/ansible/inventory/host_vars/all/vars @@ -0,0 +1,2 @@ +docker-ext_wg_public_key: 84ITOv/sB0f/h7fIY+uLQeTmMDgTCjvVzIQmEsLAZmo= +docker-ext_wg_private_key: GFNTkhkNuQe63+SgCrPVGgAtU98WKHdtUPSmsqjiDVs= diff --git a/ansible/inventory/host_vars/basementpi.local/vars b/ansible/inventory/host_vars/basementpi/vars similarity index 100% rename from ansible/inventory/host_vars/basementpi.local/vars rename to ansible/inventory/host_vars/basementpi/vars diff --git a/ansible/inventory/host_vars/basementpi.local/vault b/ansible/inventory/host_vars/basementpi/vault similarity index 100% rename from ansible/inventory/host_vars/basementpi.local/vault rename to ansible/inventory/host_vars/basementpi/vault diff --git a/ansible/inventory/host_vars/bastion/vars b/ansible/inventory/host_vars/bastion/vars new file mode 100644 index 0000000..a6ae81d --- /dev/null +++ b/ansible/inventory/host_vars/bastion/vars @@ -0,0 +1,9 @@ +--- +wg_private_key: "{{ vault_wg_private_key }}" +wg_interface_ip: 10.11.20.1/24 + +public_ip: 51.222.155.202 +wan_interface: ens3 +homeserver_private_ip: 10.11.1.15 +homeserver_wg_ip: 10.11.20.2 +homeserver_wg_public_key: 84ITOv/sB0f/h7fIY+uLQeTmMDgTCjvVzIQmEsLAZmo= diff --git a/ansible/inventory/host_vars/bastion/vault b/ansible/inventory/host_vars/bastion/vault new file mode 100644 index 0000000..68a415e --- /dev/null +++ b/ansible/inventory/host_vars/bastion/vault @@ -0,0 +1,9 @@ +$ANSIBLE_VAULT;1.1;AES256 +33623432633737383766613431346364373766336334613365653731373962316330636635356363 +6438326536313065356662336363383438396338393039660a336466316632316262323763633233 +31643766313437366234656334326464363562356231386139333161373031363961333061356138 +3964393366633632640a333563313963356135323761383734373832323333353031343836613938 +65336334613835653564396639343537396463383432356334333538313131616436333664666433 +33666237333837323962646265363963386133646463343234383566313131346330353938396233 +35383434643534306135633161353031356139373137383335633561303539363465633565356462 +35623062316131316435 diff --git a/ansible/inventory/host_vars/git/vars b/ansible/inventory/host_vars/git/vars new file mode 100644 index 0000000..192551e --- /dev/null +++ b/ansible/inventory/host_vars/git/vars @@ -0,0 +1,4 @@ +--- +gitea_db_name: gitea +gitea_db_user: gitea +gitea_db_password: "{{ vault_db_password }}" diff --git a/ansible/inventory/host_vars/git/vault b/ansible/inventory/host_vars/git/vault new file mode 100644 index 0000000..34558ff --- /dev/null +++ b/ansible/inventory/host_vars/git/vault @@ -0,0 +1,7 @@ +$ANSIBLE_VAULT;1.1;AES256 +38343062386631643835333736313032396433363666393663343161363264393833646231333038 +6234663931623536666535343762336233383065616432610a343062353463303761373039306661 +65663964313565316661323664323632653363396434323537356331636364363639333130346461 +3038653465663339300a636132303165343461373838376633626638616266633164643465396662 +31363736376366376461353165613838666537666561323164316662613435643861643536306561 +3232386238653430383038343162643066653164306439353231 diff --git a/ansible/inventory/host_vars/gitea/vars b/ansible/inventory/host_vars/gitea/vars new file mode 100644 index 0000000..ffed1d3 --- /dev/null +++ b/ansible/inventory/host_vars/gitea/vars @@ -0,0 +1,3 @@ +gitea_instance_url: https://gitea.mycomputer.party +gitea_runner_token: "{{ vault_runner_token }}" +gitea_runner_name: runner1 diff --git a/ansible/inventory/host_vars/gitea/vault b/ansible/inventory/host_vars/gitea/vault new file mode 100644 index 0000000..9d06c92 --- /dev/null +++ b/ansible/inventory/host_vars/gitea/vault @@ -0,0 +1,8 @@ +$ANSIBLE_VAULT;1.1;AES256 +33326335326536306338373536323931313161363731353734366231616238396237363438346365 +3131616263646364623264356537636462363533636439320a346162313663626230306266643030 +34393961393564363162323031346133386337383338316136623738366236376131633339363364 +3262393335646163340a633831393434366262346262626532376265303336616532663933383463 +30666533303966326166353565363263313964386435306465633532643162636535366262396535 +62343339643264643039333838383534383662303637326563386261643061313264353234636337 +353063336363326466343538666235303833 diff --git a/ansible/inventory/hosts b/ansible/inventory/hosts index 966bdc0..ba95275 100644 --- a/ansible/inventory/hosts +++ b/ansible/inventory/hosts @@ -1,2 +1,9 @@ -[rasperrypi] -basementpi.local ansible_host=10.11.1.10 ansible_ssh_user=root +basementpi ansible_host=10.11.1.10 ansible_ssh_user=root + +bastion ansible_host=51.222.155.202 ansible_ssh_user=root + +[docker] +docker-ext ansible_ssh_user=root +docker-int ansible_ssh_user=root +git ansible_ssh_user=root +basementpi ansible_host=10.11.1.10 ansible_ssh_user=root diff --git a/ansible/inventory/hosts.yaml b/ansible/inventory/hosts.yaml new file mode 100644 index 0000000..7bf5bb0 --- /dev/null +++ b/ansible/inventory/hosts.yaml @@ -0,0 +1,19 @@ +ungrouped: + hosts: + bastion: + ansible_host: 51.222.155.202 + ansible_ssh_user: root + +docker: + hosts: + docker-ext: + ansible_ssh_user: root + docker-int: + ansible_ssh_user: root + git: + ansible_ssh_user: root + basementpi: + ansible_host: 10.11.1.10 + ansible_ssh_user: root + gitea: + ansible_ssh_user: root diff --git a/ansible/renovate.json b/ansible/renovate.json new file mode 100644 index 0000000..eca8842 --- /dev/null +++ b/ansible/renovate.json @@ -0,0 +1,11 @@ +{ + "extends": [ + "config:base" + ], + "packageRules": [ + { + "updateTypes": ["minor", "patch", "pin", "digest"], + "automerge": false + } + ] +} diff --git a/ansible/roles/bastion/tasks/main.yml b/ansible/roles/bastion/tasks/main.yml new file mode 100644 index 0000000..1b0254d --- /dev/null +++ b/ansible/roles/bastion/tasks/main.yml @@ -0,0 +1,19 @@ +- name: Enable IP forwarding + ansible.builtin.lineinfile: + path: /etc/sysctl.conf + regexp: '^#?.*net\.ipv4\.ip_forward=' + line: 'net.ipv4.ip_forward=1' +- name: Install Wireguard + ansible.builtin.package: + name: wireguard + state: present +- name: Shutdown Wireguard (remove iptables rules) + ansible.builtin.shell: wg-quick down wg0 + ignore_errors: true +- name: Copy Wireguard config + ansible.builtin.template: + src: assets/{{ inventory_hostname }}/wg0.conf.j2 + dest: /etc/wireguard/wg0.conf + backup: true +- name: Enable Wireguard int + ansible.builtin.shell: wg-quick up wg0 diff --git a/ansible/roles/install_gitea/defaults/main.yml b/ansible/roles/install_gitea/defaults/main.yml new file mode 100644 index 0000000..78566d9 --- /dev/null +++ b/ansible/roles/install_gitea/defaults/main.yml @@ -0,0 +1,2 @@ +gitea_version: 1.22.3 +gitea_minor_version: 1.22 diff --git a/ansible/roles/install_gitea/tasks/main.yaml b/ansible/roles/install_gitea/tasks/main.yaml new file mode 100644 index 0000000..9bec049 --- /dev/null +++ b/ansible/roles/install_gitea/tasks/main.yaml @@ -0,0 +1,63 @@ +- name: Install Git + ansible.builtin.package: + name: git + state: present +- name: Download Gitea binary + ansible.builtin.get_url: + url: https://dl.gitea.com/gitea/{{ gitea_version }}/gitea-{{ gitea_version }}-linux-amd64 + dest: /usr/local/bin/gitea + mode: +x +- name: Create git user + ansible.builtin.user: + name: git + state: present + system: true + shell: /bin/bash + comment: Git Version Control + password: ! + create_home: true +- name: Create /var/lib/gitea + ansible.builtin.file: + state: directory + path: /var/lib/gitea + owner: git + group: git + mode: '750' +- name: Create /var/lib/gitea subdirs + ansible.builtin.file: + state: directory + path: "{{ item.path }}" + owner: git + group: git + mode: '750' + loop: + - { path: /var/lib/gitea/custom} + - { path: /var/lib/gitea/data} + - { path: /var/lib/gitea/log} +- name: Create /etc/gitea + ansible.builtin.file: + path: /etc/gitea + state: directory + owner: root + group: git + mode: '770' +- name: Get systemd unit file + ansible.builtin.get_url: + url: https://raw.githubusercontent.com/go-gitea/gitea/refs/heads/release/v{{ gitea_minor_version }}/contrib/systemd/gitea.service + dest: /etc/systemd/system/gitea.service +- name: Start service + ansible.builtin.systemd_service: + name: gitea + enabled: true + state: started + #- name: Set permissions after install + # ansible.builtin.file: + # state: "{{ item.state }}" + # path: "{{ item.path }}" + # mode: "{{ item.mode }}" + # loop: + # - { state: directory, path: /etc/gitea, mode: '750' } + # - { state: file, path: /etc/gitea/app.ini, mode: '640' } + + + diff --git a/requirements.txt b/requirements.txt index 0d48dfc..0618547 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ -ansible==7.1.0 -ansible-core==2.14.1 +ansible==8.7.0 +ansible-core==2.15.11 cffi==1.15.1 cryptography==39.0.0 Jinja2==3.1.2