9 Commits

14 changed files with 311 additions and 15 deletions

19
.gitignore vendored
View File

@@ -1,4 +1,8 @@
# ignore environment files
.env
# whatever the hell this file is
core
cloudflare/tailscale/
@@ -23,13 +27,20 @@ pdf/stirling/latest/logs/
pdf/stirling/latest/config/db/backup/
pdf/stirling/latest/config/*.db
# beszel
beszel/beszel_data/*
beszel/beszel_data/auxiliary.db
# pangolin
pangolin/config/db/db.sqlite
pangolin/config/db/backups/db*.sqlite
pangolin/config/letsencrypt/acme.json
pangolin/config/key
pangolin/config/config.yml.bak
pangolin/installer
# ignore environment files
.env
pangolin/config/traefik-dashboard/positions/.position
pangolin/config/traefik-dashboard/geoip/*.mmdb
pangolin/config/traefik-dashboard/dashboard/*.db-wal
pangolin/config/traefik/logs/access.log
pangolin/config/traefik-dashboard/dashboard/*.db
pangolin/config/traefik-dashboard/dashboard/*.db-shm

View File

@@ -3,16 +3,26 @@
## Useful aliases
These are defined in <https://github.com/acedanger/shell>
`dcdn`=`docker compose down`
`dcupd`=`docker compose up -d`
`dcpull`=`docker compose pull`
`dsta`=`docker stop $(docker ps -q)`
`dclf`=`docker compose logs -f`
`dxcit`=`docker container exec -it`
`lzd`=`lazydocker`
## Putting it all together
Shut it down, pull the latest images, and start it up again:
Shut it down, pull the latest images, start it up in the background, and follow the logs:
`dcdn; dcpull; dcupd`
```bash
dcdn && dcpull && dcupd && dclf
```

View File

@@ -22,6 +22,19 @@ services:
- ${GITEA_SSH_PORT:-2229}:22
depends_on:
- db
labels:
- diun.enable=true
healthcheck:
test:
- CMD
- curl
- -f
- http://localhost
interval: 10s
retries: 3
start_period: 30s
timeout: 10s
db:
image: docker.io/library/postgres:14
restart: always
@@ -33,11 +46,39 @@ services:
- gitea
volumes:
- postgres:/var/lib/postgresql/data
runner:
image: gitea/act_runner:latest
container_name: gitea-runner
restart: always
networks:
- gitea
volumes:
- runner:/data
- /var/run/docker.sock:/var/run/docker.sock
- ./runner-config.yaml:/data/config.yaml:ro
environment:
- GITEA_INSTANCE_URL=http://server:3000
- GITEA_RUNNER_REGISTRATION_TOKEN=${GITEA_RUNNER_REGISTRATION_TOKEN}
- GITEA_RUNNER_NAME=docker-runner
- CONFIG_FILE=/data/config.yaml
command: >
sh -c "
if [ ! -f /data/.runner ]; then
act_runner register --no-interactive --instance http://server:3000 --token $${GITEA_RUNNER_REGISTRATION_TOKEN} --name docker-runner;
fi;
act_runner --config /data/config.yaml daemon
"
depends_on:
- server
labels:
- diun.enable=true
networks:
gitea:
external: false
volumes:
gitea:
driver: local
postgres:
driver: local
runner:

15
gitea/runner-config.yaml Normal file
View File

@@ -0,0 +1,15 @@
log:
level: info
runner:
capacity: 1
timeout: 3h
container:
# Use the gitea network so job containers can resolve the 'server' hostname
network_mode: gitea_gitea
privileged: false
options: ""
workdir_parent: ""
valid_volumes: []
docker_host: ""

View File

@@ -21,7 +21,7 @@ services:
labels:
- diun.enable=true
chrome:
image: gcr.io/zenika-hub/alpine-chrome:123
image: gcr.io/zenika-hub/alpine-chrome:124
restart: unless-stopped
labels:
- diun.enable=true
@@ -33,7 +33,7 @@ services:
- --remote-debugging-port=9222
- --hide-scrollbars
meilisearch:
image: getmeili/meilisearch:v1.11.1
image: getmeili/meilisearch:v1.13.3
restart: unless-stopped
environment:
MEILI_NO_ANALYTICS: true

View File

@@ -21,6 +21,7 @@ services:
- WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY}
- WIREGUARD_PRESHARED_KEY=${WIREGUARD_PRESHARED_KEY}
- WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES}
- UPDATER_PERIOD:24h
- TZ=America/New_York # Timezone for accurate log times
- SERVER_COUNTRIES=United States
restart: always
@@ -151,9 +152,53 @@ services:
- TZ=America/New_York
labels:
- diun.enable=true
jellystat-db:
image: postgres:15.2
shm_size: 1gb
container_name: jellystat-db
restart: unless-stopped
logging:
driver: json-file
options:
max-file: "5"
max-size: 10m
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${JELLYSTAT_POSTGRES_PASSWORD}
labels:
- diun.enable=true
volumes:
- postgres_data:/var/lib/postgresql/data
jellystat:
image: cyfershepard/jellystat:latest
container_name: jellystat
restart: unless-stopped
logging:
driver: json-file
options:
max-file: "5"
max-size: 10m
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ${JELLYSTAT_POSTGRES_PASSWORD}
POSTGRES_IP: jellystat-db
POSTGRES_PORT: 5432
JWT_SECRET: ${JELLYSTAT_JWT_SECRET}
TZ: America/New_York
labels:
- diun.enable=true
volumes:
- jellystat-backup-data:/app/backend/backup-data
ports:
- 3200:3000
depends_on:
- jellystat-db
networks:
default: null
volumes:
gluetun_data: null
sabnzbd_data: null
tautulli: null
huntarr_data: null
postgres_data: null
jellystat-backup-data: null

View File

@@ -0,0 +1,76 @@
app:
dashboard_url: https://pangolin.acedanger.com
log_level: info
save_logs: false
domains:
domain1:
base_domain: acedanger.com
cert_resolver: letsencrypt
domain2:
base_domain: peterwood.rocks
cert_resolver: letsencrypt
domain3:
base_domain: peterwood.dad
cert_resolver: letsencrypt
domain4:
base_domain: ptrwd.com
cert_resolver: letsencrypt
domain5:
base_domain: margotwood.xyz
cert_resolver: letsencrypt
server:
external_port: 3000
internal_port: 3001
next_port: 3002
internal_hostname: pangolin
session_cookie_name: p_session_token
resource_access_token_param: p_token
resource_access_token_headers:
id: P-Access-Token-Id
token: P-Access-Token
resource_session_request_param: p_session_request
secret: EkiOH3KRHNzde3euT1yTaYIKXchPmHqz
cors:
origins:
- https://pangolin.acedanger.com
methods:
- GET
- POST
- PUT
- DELETE
- PATCH
headers:
- X-CSRF-Token
- Content-Type
credentials: false
traefik:
cert_resolver: letsencrypt
http_entrypoint: web
https_entrypoint: websecure
gerbil:
start_port: 51820
base_endpoint: pangolin.acedanger.com
use_subdomain: false
block_size: 24
site_block_size: 30
subnet_group: 100.89.137.0/20
rate_limits:
global:
window_minutes: 1
max_requests: 500
email:
smtp_host: smtp.fastmail.com
smtp_port: 465
smtp_user: peter@peterwood.dev
smtp_pass: 7v5x943m4g58384q
no_reply: no-reply@peterwood.dev
users:
server_admin:
email: peter@peterwood.dev
password: 23!hA1F^RCjT28
flags:
require_email_verification: true
disable_signup_without_invite: true
disable_user_create_org: false
allow_raw_resources: true
allow_base_domain_resources: true

View File

@@ -0,0 +1 @@
Database and Contents Copyright (c) 2025 MaxMind, Inc.

View File

@@ -0,0 +1,3 @@
Use of this MaxMind product is governed by MaxMind's GeoLite2 End User License Agreement, which can be viewed at https://www.maxmind.com/en/geolite2/eula.
This database incorporates GeoNames [https://www.geonames.org] geographical data, which is made available under the Creative Commons Attribution 4.0 License. To view a copy of this license, visit https://creativecommons.org/licenses/by/4.0/.

View File

@@ -0,0 +1 @@
Latitude and longitude are not precise and should not be used to identify a particular street address or household.

View File

@@ -41,6 +41,23 @@ http:
tls:
certResolver: letsencrypt
# Traefik Log Dashboard router
traefik-dashboard-redirect:
rule: "Host(`traefik-logs.acedanger.com`)"
service: traefik-dashboard-service
entryPoints:
- web
middlewares:
- redirect-to-https
traefik-dashboard-router:
rule: "Host(`traefik-logs.acedanger.com`)"
service: traefik-dashboard-service
entryPoints:
- websecure
tls:
certResolver: letsencrypt
services:
next-service:
loadBalancer:
@@ -51,3 +68,17 @@ http:
loadBalancer:
servers:
- url: "http://pangolin:3000" # API/WebSocket server
traefik-dashboard-service:
loadBalancer:
servers:
- url: "http://traefik-dashboard:3000"
tcp:
serversTransports:
pp-transport-v1:
proxyProtocol:
version: 1
pp-transport-v2:
proxyProtocol:
version: 2

View File

@@ -19,6 +19,20 @@ log:
level: "INFO"
format: "common"
accessLog:
filePath: "/var/log/traefik/access.log"
format: "json"
bufferingSize: 100
fields:
defaultMode: "keep"
names:
ClientUsername: "drop"
headers:
defaultMode: "keep"
names:
Authorization: "drop"
Cookie: "drop"
certificatesResolvers:
letsencrypt:
acme:

View File

@@ -1,7 +1,7 @@
name: pangolin
services:
pangolin:
image: fosrl/pangolin:1.10.3
image: fosrl/pangolin:1.12.1
container_name: pangolin
restart: unless-stopped
labels:
@@ -18,7 +18,7 @@ services:
timeout: 10s
retries: 15
gerbil:
image: fosrl/gerbil:1.2.1
image: fosrl/gerbil:latest
container_name: gerbil
restart: unless-stopped
labels:
@@ -59,6 +59,53 @@ services:
- ./config/traefik:/etc/traefik:ro # Volume to store the Traefik configuration
- ./config/letsencrypt:/letsencrypt # Volume to store the Let's Encrypt certificates
- ./config/traefik/logs:/var/log/traefik # Volume to store Traefik logs
traefik-agent:
image: hhftechnology/traefik-log-dashboard-agent:dev-dashboard
container_name: traefik-log-dashboard-agent
restart: unless-stopped
labels:
- diun.enable=true
ports:
- "5000:5000"
volumes:
- ./config/traefik/logs:/logs:ro
- ./config/traefik-dashboard/geoip:/geoip:ro
- ./config/traefik-dashboard/positions:/data
environment:
- TRAEFIK_LOG_DASHBOARD_ACCESS_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_ERROR_PATH=/logs/access.log
- TRAEFIK_LOG_DASHBOARD_AUTH_TOKEN=${TRAEFIK_DASHBOARD_AUTH_TOKEN}
- TRAEFIK_LOG_DASHBOARD_SYSTEM_MONITORING=true
- TRAEFIK_LOG_DASHBOARD_GEOIP_ENABLED=true
- TRAEFIK_LOG_DASHBOARD_GEOIP_CITY_DB=/geoip/GeoLite2-City.mmdb
- TRAEFIK_LOG_DASHBOARD_GEOIP_COUNTRY_DB=/geoip/GeoLite2-Country.mmdb
- TRAEFIK_LOG_DASHBOARD_LOG_FORMAT=json
- PORT=5000
healthcheck:
test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:5000/api/logs/status" ]
interval: 30s
timeout: 10s
retries: 3
start_period: 10s
traefik-dashboard:
image: hhftechnology/traefik-log-dashboard:dev-dashboard
container_name: traefik-log-dashboard
restart: unless-stopped
labels:
- diun.enable=true
ports:
- "3005:3000"
volumes:
- ./config/traefik-dashboard/dashboard:/app/data
environment:
- AGENT_API_URL=http://traefik-agent:5000
- AGENT_API_TOKEN=${TRAEFIK_DASHBOARD_AUTH_TOKEN}
- AGENT_NAME=Pangolin Traefik Agent
- NODE_ENV=production
- PORT=3000
depends_on:
traefik-agent:
condition: service_healthy
networks:
default:
driver: bridge

View File

@@ -7,6 +7,7 @@ services:
environment:
- DATA_DIR=/data
- TS_AUTHKEY=${TS_AUTHKEY}
- TSNET_FORCE_LOGIN=1
restart: always
labels:
- diun.enable=true