From 108f58e52777007ecd574b7df051dc9d7378e6d0 Mon Sep 17 00:00:00 2001 From: Adam French Date: Tue, 7 Apr 2026 12:14:56 +0100 Subject: [PATCH] Add UptimeKuma, Searxng, Wallabag services - Add uptime-kuma, searxng, and wallabag Docker services with Postgres integration for wallabag - Add nginx reverse proxy location blocks for /uptime-kuma/, /searxng/, /wallabag/ in both prod and dev templates - Update entrypoint.sh envsubst to include new HOST/PORT vars - Add Vite dev proxy entries for all three services - Update gitea-runner config: add self-hosted label and allow all volumes - Add Gitea CI/CD workflow Co-Authored-By: Claude Sonnet 4.6 --- .gitea/workflows/ci-cd.yml | 57 +++++++++++++++++++++++++ docker-compose.yml | 47 ++++++++++++++++++++- gitea-runner/config.yaml | 4 +- nginx/entrypoint.sh | 4 +- nginx/nginx.conf.template | 39 ++++++++++++++++++ nginx/nginx_dev.conf.template | 78 +++++++++++++++++++++++++++++++++++ vue/vite.config.js | 3 ++ 7 files changed, 227 insertions(+), 5 deletions(-) create mode 100644 .gitea/workflows/ci-cd.yml diff --git a/.gitea/workflows/ci-cd.yml b/.gitea/workflows/ci-cd.yml new file mode 100644 index 0000000..01a96d2 --- /dev/null +++ b/.gitea/workflows/ci-cd.yml @@ -0,0 +1,57 @@ +name: CI/CD + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + build-backend: + name: Build & Test Backend + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: backend/go.mod + cache-dependency-path: backend/go.sum + + - name: Build + run: cd backend && go build ./... + + - name: Test + run: cd backend && go test ./... + + build-frontend: + name: Build Frontend + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: npm + cache-dependency-path: vue/package-lock.json + + - name: Install dependencies + run: cd vue && npm ci + + - name: Build + run: cd vue && npm run build + + deploy: + name: Deploy + runs-on: self-hosted + needs: [build-backend, build-frontend] + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + steps: + - name: Pull latest & redeploy + run: | + cd /home/adamf/Coding/web_server + git pull origin main + docker compose up --build -d diff --git a/docker-compose.yml b/docker-compose.yml index 79da695..f9129fc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -6,6 +6,8 @@ volumes: dbdata: uploads: vue_dist: + uptime_kuma_data: + searxng_data: services: vue: @@ -32,6 +34,9 @@ services: - gitea - hasura - quartz + - uptime-kuma + - searxng + - wallabag networks: - app-network ports: @@ -129,11 +134,49 @@ services: volumes: - ${OBSIDIAN_DIR}:/quartz/content:ro + uptime-kuma: + image: louislam/uptime-kuma:1 + container_name: "${UPTIMEKUMA_HOST}" + restart: unless-stopped + networks: + - app-network + environment: + - UPTIME_KUMA_BASE_PATH=/uptime-kuma + volumes: + - uptime_kuma_data:/app/data + + searxng: + image: searxng/searxng:latest + container_name: "${SEARXNG_HOST}" + restart: unless-stopped + networks: + - app-network + environment: + - BASE_URL=https://www.${DOMAIN}/searxng/ + - INSTANCE_NAME=searxng + volumes: + - searxng_data:/etc/searxng + + wallabag: + image: wallabag/wallabag:latest + container_name: "${WALLABAG_HOST}" + restart: unless-stopped + networks: + - app-network + depends_on: + - db + environment: + - SYMFONY__ENV__DOMAIN_NAME=https://www.${DOMAIN}/wallabag + - SYMFONY__ENV__DATABASE_DRIVER=pdo_pgsql + - SYMFONY__ENV__DATABASE_HOST=${POSTGRES_HOST} + - SYMFONY__ENV__DATABASE_PORT=${POSTGRES_PORT} + - SYMFONY__ENV__DATABASE_NAME=wallabag + - SYMFONY__ENV__DATABASE_USER=${POSTGRES_USER} + - SYMFONY__ENV__DATABASE_PASSWORD=${POSTGRES_PASSWORD} + gitea-runner: image: gitea/act_runner:latest container_name: "${GITEA_RUNNER_HOST}" - profiles: - - disabled environment: GITEA_RUNNER_NAME: ${GITEA_RUNNER_NAME} CONFIG_FILE: /config.yaml diff --git a/gitea-runner/config.yaml b/gitea-runner/config.yaml index e3ee4f9..69bc111 100644 --- a/gitea-runner/config.yaml +++ b/gitea-runner/config.yaml @@ -43,6 +43,7 @@ runner: # If it's empty when registering, it will ask for inputting labels. # If it's empty when execute `daemon`, will use labels in `.runner` file. labels: + - "self-hosted:host" - "ubuntu-latest:docker://docker.gitea.com/runner-images:ubuntu-latest" - "ubuntu-22.04:docker://docker.gitea.com/runner-images:ubuntu-22.04" - "ubuntu-20.04:docker://docker.gitea.com/runner-images:ubuntu-20.04" @@ -89,7 +90,8 @@ container: # If you want to allow any volume, please use the following configuration: # valid_volumes: # - '**' - valid_volumes: [] + valid_volumes: + - '**' # overrides the docker client host with the specified one. # If it's empty, act_runner will find an available docker host automatically. # If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers. diff --git a/nginx/entrypoint.sh b/nginx/entrypoint.sh index a54c3b6..fb1aeca 100755 --- a/nginx/entrypoint.sh +++ b/nginx/entrypoint.sh @@ -12,12 +12,12 @@ if [ "$DEV_MODE" = "true" ]; then -out "$CERT_DIR/fullchain.pem" \ -subj "/CN=localhost" 2>/dev/null fi - envsubst '${DOMAIN} ${BACKEND_HOST} ${BACKEND_PORT} ${BACKEND_ENDPOINT} ${ICECAST_HOST} ${ICECAST_PORT} ${GITEA_HOST} ${GITEA_PORT} ${HASURA_HOST} ${HASURA_PORT} ${QUARTZ_HOST} ${QUARTZ_PORT}' \ + envsubst '${DOMAIN} ${BACKEND_HOST} ${BACKEND_PORT} ${BACKEND_ENDPOINT} ${ICECAST_HOST} ${ICECAST_PORT} ${GITEA_HOST} ${GITEA_PORT} ${HASURA_HOST} ${HASURA_PORT} ${QUARTZ_HOST} ${QUARTZ_PORT} ${UPTIMEKUMA_HOST} ${UPTIMEKUMA_PORT} ${SEARXNG_HOST} ${SEARXNG_PORT} ${WALLABAG_HOST} ${WALLABAG_PORT}' \ /etc/nginx/nginx.conf elif [ -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ] && [ -f "/etc/letsencrypt/live/$DOMAIN/privkey.pem" ]; then echo "Certificates found. Using production nginx config." - envsubst '${DOMAIN} ${BACKEND_HOST} ${BACKEND_PORT} ${BACKEND_ENDPOINT} ${ICECAST_HOST} ${ICECAST_PORT} ${GITEA_HOST} ${GITEA_PORT} ${HASURA_HOST} ${HASURA_PORT} ${QUARTZ_HOST} ${QUARTZ_PORT}' \ + envsubst '${DOMAIN} ${BACKEND_HOST} ${BACKEND_PORT} ${BACKEND_ENDPOINT} ${ICECAST_HOST} ${ICECAST_PORT} ${GITEA_HOST} ${GITEA_PORT} ${HASURA_HOST} ${HASURA_PORT} ${QUARTZ_HOST} ${QUARTZ_PORT} ${UPTIMEKUMA_HOST} ${UPTIMEKUMA_PORT} ${SEARXNG_HOST} ${SEARXNG_PORT} ${WALLABAG_HOST} ${WALLABAG_PORT}' \ /etc/nginx/nginx.conf else diff --git a/nginx/nginx.conf.template b/nginx/nginx.conf.template index 1a3eabd..84257f9 100644 --- a/nginx/nginx.conf.template +++ b/nginx/nginx.conf.template @@ -232,6 +232,45 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location /uptime-kuma { + return 301 /uptime-kuma/; + } + + location /uptime-kuma/ { + proxy_pass http://$UPTIMEKUMA_HOST:$UPTIMEKUMA_PORT/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /searxng { + return 301 /searxng/; + } + + location /searxng/ { + proxy_pass http://$SEARXNG_HOST:$SEARXNG_PORT/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /wallabag { + return 301 /wallabag/; + } + + location /wallabag/ { + proxy_pass http://$WALLABAG_HOST:$WALLABAG_PORT/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } } diff --git a/nginx/nginx_dev.conf.template b/nginx/nginx_dev.conf.template index f275e6e..9303d34 100644 --- a/nginx/nginx_dev.conf.template +++ b/nginx/nginx_dev.conf.template @@ -159,6 +159,45 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location /uptime-kuma { + return 301 /uptime-kuma/; + } + + location /uptime-kuma/ { + proxy_pass http://$UPTIMEKUMA_HOST:$UPTIMEKUMA_PORT/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /searxng { + return 301 /searxng/; + } + + location /searxng/ { + proxy_pass http://$SEARXNG_HOST:$SEARXNG_PORT/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /wallabag { + return 301 /wallabag/; + } + + location /wallabag/ { + proxy_pass http://$WALLABAG_HOST:$WALLABAG_PORT/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } server { @@ -283,6 +322,45 @@ http { proxy_set_header X-Forwarded-Proto $scheme; } + location /uptime-kuma { + return 301 /uptime-kuma/; + } + + location /uptime-kuma/ { + proxy_pass http://$UPTIMEKUMA_HOST:$UPTIMEKUMA_PORT/; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /searxng { + return 301 /searxng/; + } + + location /searxng/ { + proxy_pass http://$SEARXNG_HOST:$SEARXNG_PORT/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /wallabag { + return 301 /wallabag/; + } + + location /wallabag/ { + proxy_pass http://$WALLABAG_HOST:$WALLABAG_PORT/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + } } diff --git a/vue/vite.config.js b/vue/vite.config.js index b1fcd5f..69d894a 100644 --- a/vue/vite.config.js +++ b/vue/vite.config.js @@ -23,6 +23,9 @@ export default defineConfig({ "/api": "http://localhost:8080", "/gitea": "http://localhost:3000", "/radio": "http://localhost:8000", + "/uptime-kuma": "http://localhost:3001", + "/searxng": "http://localhost:8080", + "/wallabag": "http://localhost:80", }, }, });