Pelican
Panel
https://github.com/trentnbauer/HomelabPublic/blob/main/docker-compose/pelican.yml
Wings
https://github.com/trentnbauer/HomelabPublic/blob/main/docker-compose/pelican-wings.yml
Last updated
Last updated
services:
panel:
image: ghcr.io/pelican-dev/panel:v1.0.0-beta33
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: ${PANEL_CPULIMIT:-2}
#memory: 50M
depends_on:
database:
condition: service_started
restart: true
cache:
condition: service_started
restart: true
restart: unless-stopped
healthcheck:
test: wget --no-verbose --tries=1 --spider http://127.0.0.1/up || exit 1
interval: 30s
timeout: 25s
retries: 3
start_period: 30s
networks:
Management:
aliases:
- panel
volumes:
- panel-data:/pelican-data
- panel-logs:/var/www/html/storage/logs
environment:
TZ: ${TZ:-UTC}
APP_URL: https://${PANEL_SUBDOMAIN:-panel}.${DOMAIN}
APP_NAME: ${APP_NAME:-Pelican}
APP_KEY: ${APP_KEY}
APP_DEBUG: ${DEBUG:-false}
APP_ENV: production
APP_LOCALE: ${LOCALE:-en}
BEHIND_PROXY: true
TRUSTED_PROXIES: '192.168.253.0/24,0.0.0.0/0'
DB_CONNECTION: mariadb
DB_HOST: database
DB_PORT: 3306
DB_DATABASE: pelican
MYSQL_DATABASE: pelican
DB_USERNAME: pelican
DB_PASSWORD: ${MYSQL_PASS}
CACHE_STORE: redis
SESSION_DRIVER: redis
QUEUE_CONNECTION: redis
REDIS_HOST: cache
MAIL_DRIVER: ${MAIL_DRIVER:-smtp}
MAIL_MAILER: ${MAIL_DRIVER:-smtp}
MAIL_HOST: ${MAIL_SERVER:-smtp.gmail.com}
MAIL_PORT: ${MAIL_PORT:-465}
MAIL_FROM: ${MAIL_FROM}
MAIL_FROM_ADDRESS: ${MAIL_FROM}
MAIL_FROM_NAME: ${MAIL_FROM_NAME:-Pelican}
MAIL_USERNAME: ${MAIL_USERNAME}
MAIL_PASSWORD: ${MAIL_PASSWORD}
MAIL_SCHEME: ${MAIL_SCHEME:-smtps}
SKIP_CADDY: ${SKIP_CADDY:-false} # enable when not using caddy.
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
labels:
- dfpelican.enable=true
- dfpelican.0.hostname=${PANEL_SUBDOMAIN:-panel}.${DOMAIN}
- dfpelican.0.service=http://panel:80
- dfpelican.0.access.policy=bypass
- dfpelican.0.zonename=${DOMAIN}
- AutohealPelican=true
database:
image: mariadb:12.1
restart: unless-stopped
command: --default-authentication-plugin=mysql_native_password
deploy:
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 5
window: 120s
volumes:
- database:/var/lib/mysql
networks:
Management:
aliases:
- database
healthcheck:
test: ["CMD", "healthcheck.sh", "--su-mysql", "--connect", "--innodb_initialized"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASS}
MYSQL_PASSWORD: ${MYSQL_PASS}
MYSQL_DATABASE: "pelican"
MYSQL_USER: "pelican"
MARIADB_AUTO_UPGRADE: true
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
labels:
- AutohealPelican=true
cache:
image: redis:alpine
restart: unless-stopped
deploy:
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 5
window: 120s
networks:
Management:
aliases:
- cache
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
start_period: 15s
labels:
- AutohealPelican=true
dockflare:
image: alplat/dockflare:v2.0.4
restart: unless-stopped
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: ${DOCKFLARE_CPULIMIT:-2}
networks:
Management:
aliases:
- dockflare
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:5000 -O /dev/null || exit 1
interval: 30s
retries: 3
start_period: 30s
timeout: 20s
environment:
- TUNNEL_NAME=pelican
- LABEL_PREFIX=dfpelican
- CLOUDFLARED_NETWORK_NAME=pelican-mgmt
- CLOUDFLARED_IMAGE=cloudflare/cloudflared:latest
- TZ=${TZ:-Australia/Melbourne}
- CF_API_TOKEN=${CF_APITOKEN}
- CF_ACCOUNT_ID=${CF_ACCOUNTID}
- AGENT_STATUS_UPDATE_INTERVAL_SECONDS=5
- SYNC_ALL_CLOUDFLARE_POLICIES=true
- TZ=${TZ:-UTC}
- GRACE_PERIOD_SECONDS=28800
- CLEANUP_INTERVAL_SECONDS=900
- SCAN_ALL_NETWORKS=false
- MAX_CONCURRENT_DNS_OPS=${DOCKFLARE_DNSOPS:-2}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- dockflare:/app/data
labels:
- AutohealPelican=true
crowdsec-engine:
image: crowdsecurity/crowdsec:v1.7.6@sha256:63b595fef92de1778573b375897a45dd226637ee9a3d3db9f57ac7355c369493
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: ${CROWDSEC_CPULIMIT:-2}
restart: unless-stopped
depends_on:
init-crowdsec:
condition: service_completed_successfully
environment:
- COLLECTIONS=crowdsecurity/linux
- BOUNCER_KEY_CLOUDFLARE=Heroics9HeadrestQuenchHullPatriot
- ENROLL_INSTANCE_NAME=PelicanPanel
- DISABLE_LOCAL_API=false
- DISABLE_ONLINE_API=false
- ENROLL_KEY=${CROWDSEC_ENROLL_KEY}
- BLOCKLISTPASSWORD=${BLOCKLISTPASSWORD:-OccupantCorporalVividness9DiabetesCrumb}
volumes:
- crowdsec-data:/var/lib/crowdsec/data
- crowdsec-config:/etc/crowdsec
- bouncer-config:/etc/bouncer-shared
- panel-logs:/var/www/html/storage/logs
healthcheck:
test: ["CMD", "cscli", "version"]
labels:
- PelicanAutoheal=true
networks:
Management:
aliases:
- crowdsec
#entrypoint: >
# /bin/bash -c "
# cscli machines add blocklist --password $$BLOCKLISTPASSWORD -f /etc/crowdsec/blocklist_credentials.yaml --force &&
# /bin/bash /docker_start.sh"
crowdsecbouncer-cloudflare:
image: ghcr.io/crowdsecurity/cloudflare-bouncer:v0.3.0@sha256:39719a070c154866ebc81335e70fdfa1c61eac45025fee7d9bbf8da689fbb2c6
deploy:
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 6
window: 60s
resources:
limits:
cpus: ${CROWDSEC_CPULIMIT:-2}
restart: unless-stopped
depends_on:
crowdsec-engine:
condition: service_healthy
environment:
API_URL: http://crowdsec:8080
API_KEY: Heroics9HeadrestQuenchHullPatriot
CF_APITOKEN: ${CF_APITOKEN}
CF_ACCOUNTID: ${CF_ACCOUNTID}
CF_ZONE_ID: ${CF_ZONE_ID}
labels:
- PelicanAutoheal=true
volumes:
- bouncer-config:/etc/crowdsec/bouncers/:rw
- /etc/localtime:/etc/localtime:ro
networks:
- Management
crowdsec-blocklist:
image: ghcr.io/wolffcatskyy/crowdsec-blocklist-import:3.3.2@sha256:dc562b89ec4642f5e587641408059b0e880cc4b460546527cc3831470e809538
depends_on:
crowdsec-engine:
condition: service_healthy
restart: unless-stopped
labels:
- PelicanAutoheal=true
environment:
- CROWDSEC_LAPI_URL=http://crowdsec:8080
- CROWDSEC_MACHINE_ID=blocklist
- CROWDSEC_MACHINE_PASSWORD=${BLOCKLISTPASSWORD:-OccupantCorporalVividness9DiabetesCrumb}
- MODE=lapi
- DECISION_DURATION=24h
- TZ=${TZ:-UTC}
#- MAX_DECISIONS=${MAX_DECISIONS:-8000} # USG3P=8000, UDR=15000, UDM Pro=50000
entrypoint: /bin/sh -c "while true; do /usr/local/bin/import.sh; echo 'Sleeping for 6 hours...'; sleep 21600; done"
# This container is designed to be re-ran manually by the user or manually via a CRON job. I've altered the entrypoint command to sleep the container for 6 hours instead.
networks:
Management:
aliases:
- blocklist
autoheal:
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 5
window: 120s
network_mode: "none"
environment:
AUTOHEAL_CONTAINER_LABEL: AutohealPelican
AUTOHEAL_INTERVAL: 60
AUTOHEAL_START_PERIOD: 240
AUTOHEAL_DEFAULT_STOP_TIMEOUT: 60
WEBHOOK_URL: ${AUTOHEAL_WEBHOOK:-}
image: willfarrell/autoheal@sha256:76d1f7341bee169cf08ed56f19d0194ff40ad970d8dfa096316499a3ebf148b0
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
init-crowdsec:
image: alpine:latest
volumes:
- crowdsec-config:/etc/crowdsec
- bouncer-config:/etc/crowdsec/bouncers
command: >
sh -c "apk add --no-cache wget ca-certificates &&
mkdir -p /etc/crowdsec/acquisitions.d /etc/crowdsec/bouncers &&
wget -qO /etc/crowdsec/acquis.yaml https://raw.githubusercontent.com/trentnbauer/HomelabPublic/main/crowdsec/pterodactyl.yaml &&
wget -qO /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml https://raw.githubusercontent.com/trentnbauer/HomelabPublic/main/crowdsec/crowdsec-cloudflare-bouncer.yaml &&
wget -qO /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml https://raw.githubusercontent.com/trentnbauer/HomelabPublic/main/crowdsec/crowdsec-firewall-bouncer.yaml"
volumes:
panel-data:
panel-logs:
database:
dockflare:
crowdsec-data:
crowdsec-config:
bouncer-config:
networks:
Management:
name: pelican-mgmt
ipam:
config:
- subnet: 192.168.253.0/24
gateway: 192.168.253.1
services:
wings:
image: ghcr.io/pelican-dev/wings:v1.0.0-beta24
deploy:
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 999
window: 30s
resources:
limits:
cpus: ${WINGS_CPULIMIT:-2}
#memory: 50M
restart: unless-stopped
networks:
Management:
aliases:
- wings
ports:
- ${SFTP_PORT:-2022}:${SFTP_PORT:-2022}
tty: true
environment:
TZ: ${TZ:-UTC}
WINGS_UID: 988
WINGS_GID: 988
WINGS_USERNAME: pelican
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/containers/:/var/lib/docker/containers/
- /etc/pelican/:/etc/pelican/
- /var/lib/pelican/:/var/lib/pelican/
- logs:/var/log/pelican/
- /tmp/pelican/:/tmp/pelican/
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
labels:
- dfwings${NODE_SUBDOMAIN}.enable=true
- dfwings${NODE_SUBDOMAIN}.0.hostname=${NODE_SUBDOMAIN}.${DOMAIN}
- dfwings${NODE_SUBDOMAIN}.0.service=http://wings:8080
- dfwings${NODE_SUBDOMAIN}.0.access.policy=bypass
- dfwings${NODE_SUBDOMAIN}.0.zonename=${DOMAIN}
- ah-wings=true
dockflare:
image: alplat/dockflare:v2.0.4
restart: unless-stopped
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: ${DOCKFLARE_CPULIMIT:-2}
networks:
Management:
aliases:
- dockflare
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:5000 -O /dev/null || exit 1
interval: 30s
retries: 3
start_period: 30s
timeout: 20s
environment:
- TUNNEL_NAME=wings-${NODE_SUBDOMAIN}
- LABEL_PREFIX=dfwings${NODE_SUBDOMAIN}
- CLOUDFLARED_NETWORK_NAME=wings-mgmt
- CLOUDFLARED_IMAGE=cloudflare/cloudflared:latest
- TZ=${TZ:-Australia/Melbourne}
- CF_API_TOKEN=${CF_APITOKEN}
- CF_ACCOUNT_ID=${CF_ACCOUNTID}
- AGENT_STATUS_UPDATE_INTERVAL_SECONDS=5
- SYNC_ALL_CLOUDFLARE_POLICIES=true
- TZ=${TZ:-UTC}
- GRACE_PERIOD_SECONDS=28800
- CLEANUP_INTERVAL_SECONDS=900
- SCAN_ALL_NETWORKS=false
- MAX_CONCURRENT_DNS_OPS=${DOCKFLARE_DNSOPS:-2}
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- dockflare:/app/data
labels:
- ah-wings=true
ddns:
image: favonia/cloudflare-ddns:1.15.1
deploy:
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 5
window: 120s
resources:
limits:
cpus: 0.25
networks:
- Management
restart: always
user: "1000:1000"
read_only: true
cap_drop: [all]
security_opt: [no-new-privileges:true]
environment:
- CLOUDFLARE_API_TOKEN=${CF_APITOKEN}
- DOMAINS=${JOIN_SUBDOMAIN:-join}.${DOMAIN}
- PROXIED=${PROXIED-false}
- DETECTION_TIMEOUT=15s
- UPDATE_CRON=@every ${UPDATE_CRON:-5m}
- DELETE_ON_STOP=${DELETE_ON_STOP:-false}
- UPDATE_ON_START=${UPDATE_ON_START:-true}
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
crowdsec-engine:
image: crowdsecurity/crowdsec:v1.7.6@sha256:63b595fef92de1778573b375897a45dd226637ee9a3d3db9f57ac7355c369493
deploy:
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
resources:
limits:
cpus: ${CROWDSEC_CPULIMIT:-2}
restart: unless-stopped
ports:
- ${CROWDSEC_PORT:-8080}:8080
depends_on:
init-crowdsec:
condition: service_completed_successfully
environment:
- COLLECTIONS=lourys/pterodactyl
- ENROLL_INSTANCE_NAME=WingsSFTP-${NODE_SUBDOMAIN}
- BOUNCER_KEY_FIREWALL=${CROWDSEC_KEY}
- DISABLE_LOCAL_API=false
- DISABLE_ONLINE_API=false
- ENROLL_KEY=${CROWDSEC_ENROLL_KEY}
volumes:
- crowdsec-data:/var/lib/crowdsec/data
- crowdsec-config:/etc/crowdsec
- bouncer:/etc/bouncer-shared
- logs:/var/log/pelican:ro
healthcheck:
test: ["CMD", "cscli", "version"]
labels:
- PelicanAutoheal=true
networks:
Management:
aliases:
- crowdsec
crowdsec-bouncer-fw:
image: ghcr.io/shgew/cs-firewall-bouncer-docker:v0.0.34@sha256:ff1b5b0972ea0cfe39a4f10728effc38f6185a88b742fc4ad5a53d5dca80aca1
deploy:
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 6
window: 60s
resources:
limits:
cpus: ${CROWDSEC_CPULIMIT:-2}
restart: unless-stopped
network_mode: host
depends_on:
crowdsec-engine:
condition: service_healthy
cap_add:
- NET_ADMIN
- NET_RAW
security_opt:
- no-new-privileges:true
environment:
- API_URL=http://localhost:${CROWDSEC_PORT:-8080}/
- API_KEY=${CROWDSEC_KEY}
volumes:
- bouncer:/config:rw
- /etc/localtime:/etc/localtime:ro
autoheal:
deploy:
replicas: 1
restart_policy:
condition: on-failure
delay: 30s
max_attempts: 5
window: 120s
environment:
AUTOHEAL_CONTAINER_LABEL: ah-wings
AUTOHEAL_INTERVAL: 60
AUTOHEAL_START_PERIOD: 240
AUTOHEAL_DEFAULT_STOP_TIMEOUT: 60
WEBHOOK_URL: ${AUTOHEAL_WEBHOOK:-}
image: willfarrell/autoheal@sha256:76d1f7341bee169cf08ed56f19d0194ff40ad970d8dfa096316499a3ebf148b0
network_mode: none
restart: always
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock
init-wings:
image: ghcr.io/pelican-dev/wings:v1.0.0-beta22
command: /usr/bin/wings configure --panel-url https://${PANEL_SUBDOMAIN:-panel}.${DOMAIN} --token ${PANEL_TOKEN} --node ${NODE_ID} --override
networks:
Management:
tty: true
environment:
TZ: ${TZ:-UTC}
WINGS_UID: 988
WINGS_GID: 988
WINGS_USERNAME: pelican
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/containers/:/var/lib/docker/containers/
- /etc/pelican/:/etc/pelican/
- /var/lib/pelican/:/var/lib/pelican/
- logs:/var/log/pelican/
- /tmp/pelican/:/tmp/pelican/
logging:
driver: "json-file"
options:
max-size: "5m"
max-file: "3"
labels:
- ah-wings=true
init-crowdsec:
image: alpine:latest
volumes:
- crowdsec-config:/etc/crowdsec
- bouncer:/etc/crowdsec/bouncers
command: >
sh -c "apk add --no-cache wget ca-certificates &&
mkdir -p /etc/crowdsec/acquisitions.d /etc/crowdsec/bouncers &&
wget -qO /etc/crowdsec/acquis.yaml https://raw.githubusercontent.com/trentnbauer/HomelabPublic/main/crowdsec/pterodactyl.yaml &&
wget -qO /etc/crowdsec/bouncers/crowdsec-cloudflare-bouncer.yaml https://raw.githubusercontent.com/trentnbauer/HomelabPublic/main/crowdsec/crowdsec-cloudflare-bouncer.yaml &&
wget -qO /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml https://raw.githubusercontent.com/trentnbauer/HomelabPublic/main/crowdsec/crowdsec-firewall-bouncer.yaml"
volumes:
config:
logs:
temp:
dockflare:
crowdsec-data:
crowdsec-config:
bouncer:
networks:
Management:
name: wings-mgmt
wings:
name: pelican_nw
games:
name: pelican0