version: "3.3"
|
|
services:
|
|
caddy:
|
|
image: caddy:2.3.0
|
|
networks:
|
|
- blog
|
|
- internet-access
|
|
- sequentialread
|
|
- gitea
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
command: ["/bin/sh", "-c", "rm -f /caddysocket/caddy.sock && caddy run -config /config/config.json"]
|
|
volumes:
|
|
- type: bind
|
|
source: ./caddy/config
|
|
target: /config
|
|
read_only: true
|
|
- type: bind
|
|
source: ./caddy/data
|
|
target: /data
|
|
- type: bind
|
|
source: ./caddy/log
|
|
target: /var/log
|
|
- type: volume
|
|
source: caddy-socket-volume
|
|
target: /caddysocket
|
|
|
|
caddy-config:
|
|
image: sequentialread/caddy-config:0.0.11
|
|
networks:
|
|
- sequentialread
|
|
volumes:
|
|
- type: bind
|
|
source: ./security-gateway/docker.sock
|
|
target: /var/run/docker.sock
|
|
- type: volume
|
|
source: caddy-socket-volume
|
|
target: /caddysocket
|
|
environment:
|
|
- CADDY_ACME_DOMAINS_CSV=*.sequentialread.com
|
|
- CADDY_ACME_ISSUER_URL=https://acme-v02.api.letsencrypt.org/directory
|
|
- CADDY_ACME_CLIENT_EMAIL_ADDRESS=forest.n.johnson@gmail.com
|
|
|
|
docker-api-security-gateway:
|
|
image: sequentialread/docker-api-security-gateway:0.0.16
|
|
userns_mode: "host"
|
|
volumes:
|
|
- type: bind
|
|
source: /var/run/docker.sock
|
|
target: /var/run/docker.sock
|
|
read_only: true
|
|
- type: bind
|
|
source: ./security-gateway/
|
|
target: /var/run/docker-api-security-gateway/
|
|
environment:
|
|
DOCKER_API_PROXY_DEBUG: "false"
|
|
DOCKER_API_PROXY_ALLOW_0_METHODREGEX: ^GET$$
|
|
DOCKER_API_PROXY_ALLOW_0_URIREGEX: ^/info(\?)?$$
|
|
DOCKER_API_PROXY_ALLOW_1_METHODREGEX: ^GET$$
|
|
DOCKER_API_PROXY_ALLOW_1_URIREGEX: ^/containers/json(\?)?((filters=%7B%22status%22%3A%5B%22running%22%5D%7D&)?limit=0)?$$
|
|
DOCKER_API_PROXY_ALLOW_2_METHODREGEX: ^GET$$
|
|
DOCKER_API_PROXY_ALLOW_2_URIREGEX: ^/containers/[a-f0-9]+/stats(\?)?(stream=0)?$$
|
|
DOCKER_API_PROXY_ALLOW_3_METHODREGEX: ^GET$$
|
|
DOCKER_API_PROXY_ALLOW_3_URIREGEX: ^/containers/[a-f0-9]+/json(\?)?$$
|
|
DOCKER_API_PROXY_RESULTFILTERS_0_METHODREGEX: .*
|
|
DOCKER_API_PROXY_RESULTFILTERS_0_URIREGEX: ^/containers/[a-f0-9]+/json(\?)?$$
|
|
DOCKER_API_PROXY_RESULTFILTERS_0_BLACKLIST_0_PATH: .Config.Env
|
|
DOCKER_API_PROXY_HTTP_LISTENUNIXSOCKET: /var/run/docker-api-security-gateway/docker.sock
|
|
DOCKER_API_PROXY_HTTP_LISTENUNIXSOCKETUID: 165536
|
|
DOCKER_API_PROXY_HTTP_LISTENUNIXSOCKETGID: 165536
|
|
DOCKER_HOST: unix:///var/run/docker.sock
|
|
DOCKER_API_VERSION: '1.40'
|
|
|
|
goatcounter:
|
|
image: sequentialread/goatcounter:1.4.2-9
|
|
restart: always
|
|
entrypoint: ["/bin/sh"]
|
|
command: ["-c", "/app/goatcounter migrate -createdb all && /app/goatcounter serve -tls none -listen '*:8080'"]
|
|
networks:
|
|
sequentialread:
|
|
ipv4_address: ${SEQUENTIALREAD_NETWORK_GOATCOUNTER_IPV4}
|
|
volumes:
|
|
- type: bind
|
|
source: ./goatcounter/db
|
|
target: /app/db
|
|
labels:
|
|
sequentialread-8080-public-port: 443
|
|
sequentialread-8080-public-protocol: https
|
|
sequentialread-8080-public-hostnames: "goatcounter.sequentialread.com,goatcounter.beta.sequentialread.com"
|
|
sequentialread-8080-container-protocol: http
|
|
|
|
goatcounter-log-publisher:
|
|
image: sequentialread/goatcounter:1.4.2-28
|
|
restart: always
|
|
entrypoint: ["/bin/sh"]
|
|
command: ["-c", "tail -f /caddylog/caddy-goatcounter.log | ./goatcounter-caddy-log-adapter | ./goatcounter import -site http://goatcounter.sequentialread.com -format combined-vhost -- -"]
|
|
extra_hosts:
|
|
- "goatcounter.beta.sequentialread.com:${SEQUENTIALREAD_NETWORK_GOATCOUNTER_IPV4}"
|
|
- "goatcounter.sequentialread.com:${SEQUENTIALREAD_NETWORK_GOATCOUNTER_IPV4}"
|
|
volumes:
|
|
- type: bind
|
|
source: ./goatcounter/db
|
|
target: /app/db
|
|
- type: bind
|
|
source: ./caddy/log
|
|
target: /caddylog
|
|
networks:
|
|
- sequentialread
|
|
environment:
|
|
- GOATCOUNTER_API_KEY=${GOATCOUNTER_API_KEY}
|
|
- LOGADAPTER_INCLUDESUCCESSORFAILUREINKEY=false
|
|
- LOGADAPTER_DEBUG=false
|
|
- LOGADAPTER_DOMAINS_0_MATCHHOSTNAMEREGEX=^(www\.)?((git|stream|pwm|captcha|comments)\.)?(beta\.)?sequentialread.com
|
|
- LOGADAPTER_DOMAINS_0_CONTENTTYPEWHITELISTREGEX=[^/]+/html
|
|
- LOGADAPTER_DOMAINS_1_MATCHHOSTNAMEREGEX=goatcounter
|
|
- LOGADAPTER_DOMAINS_1_CONTENTTYPEWHITELISTREGEX=DROP_ALL
|
|
|
|
influxdb:
|
|
image: influxdb:1.8.4
|
|
restart: always
|
|
networks:
|
|
- sequentialread
|
|
volumes:
|
|
- type: bind
|
|
source: ./influxdb/data/
|
|
target: /var/lib/influxdb
|
|
environment:
|
|
- INFLUXDB_REPORTING_DISABLED=true
|
|
- INFLUXDB_HTTP_AUTH_ENABLED=true
|
|
- INFLUXDB_HTTP_PPROF_AUTH_ENABLED=true
|
|
- INFLUXDB_HTTP_DEBUG_PPROF_ENABLED=true
|
|
labels:
|
|
sequentialread-8086-public-port: 443
|
|
sequentialread-8086-public-protocol: https
|
|
sequentialread-8086-public-hostnames: "influxdb.sequentialread.com,influxdb.beta.sequentialread.com"
|
|
sequentialread-8086-container-protocol: http
|
|
|
|
telegraf:
|
|
image: telegraf:1.17.3
|
|
restart: always
|
|
# in order to get telegraf to report the host's network io correctly,
|
|
# it has to run on the host network... and the only way to do that
|
|
# would be to disable the user namespace remap. so we manually set it to the
|
|
# remapped UID and GID
|
|
userns_mode: "host"
|
|
network_mode: "host"
|
|
user: 165536:165536
|
|
# now that we are on the hosts network, in order to talk to influx we have to go in through the
|
|
# front door: Caddy, which is listening on 80 and 443 on localhost.
|
|
extra_hosts:
|
|
- "influxdb.beta.sequentialread.com:127.0.0.1"
|
|
- "influxdb.sequentialread.com:127.0.0.1"
|
|
command: ["--config", "/telegrafconfig/telegraf.conf"]
|
|
volumes:
|
|
- type: bind
|
|
source: ./security-gateway/docker.sock
|
|
target: /var/run/docker.sock
|
|
- type: bind
|
|
source: /
|
|
target: /hostfs
|
|
read_only: true
|
|
- type: bind
|
|
source: ./telegraf
|
|
target: /telegrafconfig
|
|
read_only: true
|
|
depends_on:
|
|
- docker-api-security-gateway
|
|
environment:
|
|
- HOST_MOUNT_PREFIX=/hostfs
|
|
- HOST_PROC=/hostfs/proc
|
|
- TELEGRAF_INFLUX_PASSWORD=${TELEGRAF_INFLUX_PASSWORD}
|
|
- TELEGRAF_INFLUX_URL=https://influxdb.sequentialread.com
|
|
|
|
grafana:
|
|
image: grafana/grafana:7.4.3
|
|
# The Grafana docker container is missing the /etc/nsswitch.conf file which
|
|
# many things rely on in order to know how to properly look up domain names.
|
|
# See: https://github.com/gliderlabs/docker-alpine/issues/367
|
|
# without this file, grafana will only use the dns server to resolve names,
|
|
# it won't look at the /etc/hosts file at all.
|
|
# Since grafana normally runs as a separate user, we have to override the container to run as root 1st
|
|
# so it can write the nsswitch.conf file, then run the grafana start script as the grafana user.
|
|
user: '0'
|
|
entrypoint: /bin/sh
|
|
command: ["-c", "echo 'hosts: files dns' > /etc/nsswitch.conf && su -s '/bin/sh' -c '/run.sh' grafana"]
|
|
extra_hosts:
|
|
- "smtp.gmail.com:${SEQUENTIALREAD_NETWORK_EXTERNAL_SERVICE_IPV4}"
|
|
networks:
|
|
- sequentialread
|
|
volumes:
|
|
- type: bind
|
|
source: ./grafana/data/
|
|
target: /var/lib/grafana
|
|
environment:
|
|
GF_SERVER_ROOT_URL: 'https://grafana.sequentialread.com'
|
|
GF_SERVER_ENABLE_GZIP: 'true'
|
|
GF_SECURITY_ADMIN_USER: admin
|
|
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
|
|
GF_SECURITY_DISABLE_GRAVATAR: 'true'
|
|
GF_SECURITY_COOKIE_SECURE: 'true'
|
|
GF_SECURITY_SECRET_KEY: ${GRAFANA_SECRET_KEY}
|
|
GF_AUTH_ANONYMOUS_ENABLED: 'true'
|
|
GF_AUTH_ANONYMOUS_ORG_NAME: sequentialread
|
|
GF_AUTH_ANONYMOUS_ORG_ROLE: Viewer
|
|
GF_SMTP_ENABLED: 'true'
|
|
GF_SMTP_HOST: 'smtp.gmail.com:465'
|
|
GF_SMTP_PASSWORD: ${GMAIL_PASSWORD}
|
|
GF_SMTP_USER: gitlab.sequentialread.com@gmail.com
|
|
GF_SMTP_FROM_ADDRESS: gitlab.sequentialread.com@gmail.com
|
|
GF_SMTP_STARTTLS_POLICY: MandatoryStartTLS
|
|
labels:
|
|
sequentialread-3000-public-port: 443
|
|
sequentialread-3000-public-protocol: https
|
|
sequentialread-3000-public-hostnames: "grafana.sequentialread.com,grafana.beta.sequentialread.com"
|
|
sequentialread-3000-container-protocol: http
|
|
|
|
sequentialread-external-service:
|
|
image: sequentialread/external-service:0.0.12
|
|
restart: always
|
|
networks:
|
|
sequentialread:
|
|
ipv4_address: ${SEQUENTIALREAD_NETWORK_EXTERNAL_SERVICE_IPV4}
|
|
internet-access:
|
|
environment:
|
|
DEBUG_LOG: 'true'
|
|
SERVICE_0_LISTEN: ':465'
|
|
SERVICE_0_DIAL: 'smtp.gmail.com:465'
|
|
SERVICE_1_LISTEN: ':8080'
|
|
SERVICE_1_DIAL: '192.168.0.46:8080'
|
|
|
|
pwm:
|
|
image: sequentialread/sequentialread-password-manager:2.0.6
|
|
restart: always
|
|
networks:
|
|
- sequentialread
|
|
environment:
|
|
- SEQUENTIALREAD_PWM_BACKBLAZE_BUCKET_NAME=sequentialread-password-manager
|
|
- SEQUENTIALREAD_PWM_BACKBLAZE_BUCKET_REGION=us-west-000
|
|
- SEQUENTIALREAD_PWM_BACKBLAZE_ACCESS_KEY_ID=0003ea77f5997840000000015
|
|
- SEQUENTIALREAD_PWM_BACKBLAZE_SECRET_ACCESS_KEY=${PWM_BACKBLAZE_SECRET_ACCESS_KEY}
|
|
volumes:
|
|
- type: bind
|
|
source: ./pwm/data/
|
|
target: /app/data/
|
|
labels:
|
|
sequentialread-8073-public-port: 443
|
|
sequentialread-8073-public-protocol: https
|
|
sequentialread-8073-public-hostnames: "pwm.sequentialread.com,pwm.beta.sequentialread.com"
|
|
sequentialread-8073-container-protocol: http
|
|
|
|
picopublish:
|
|
image: sequentialread/picopublish:0.1.7
|
|
restart: always
|
|
networks:
|
|
- sequentialread
|
|
environment:
|
|
- PICO_PUBLISH_PASSWORD=${PICOPUBLISH_PASSWORD}
|
|
volumes:
|
|
- type: bind
|
|
source: ./picopublish/data
|
|
target: /app/data
|
|
labels:
|
|
sequentialread-8080-public-port: 443
|
|
sequentialread-8080-public-protocol: https
|
|
sequentialread-8080-public-hostnames: "picopublish.sequentialread.com,picopublish.beta.sequentialread.com"
|
|
sequentialread-8080-container-protocol: http
|
|
|
|
webclip:
|
|
image: sequentialread/webclip:0.0.2
|
|
restart: always
|
|
networks:
|
|
- sequentialread
|
|
labels:
|
|
sequentialread-8080-public-port: 443
|
|
sequentialread-8080-public-protocol: https
|
|
sequentialread-8080-public-hostnames: "webclip.sequentialread.com,webclip.beta.sequentialread.com"
|
|
sequentialread-8080-container-protocol: http
|
|
|
|
|
|
gitea:
|
|
image: sequentialread/gitea-armv7:1.13.2
|
|
restart: always
|
|
ports:
|
|
- "10022:10022"
|
|
networks:
|
|
- gitea
|
|
volumes:
|
|
- type: bind
|
|
source: ./gitea/data
|
|
target: /data
|
|
environment:
|
|
- APP_NAME='SequentialRead Git'
|
|
- SSH_PORT=10022
|
|
- SSH_LISTEN_PORT=10022
|
|
- ROOT_URL=https://git.beta.sequentialread.com
|
|
- DISABLE_REGISTRATION=true
|
|
- INSTALL_LOCK=true
|
|
- SECRET_KEY=${GITEA_SECRET_KEY}
|
|
- DB_TYPE=mysql
|
|
- DB_HOST=gitea-mariadb
|
|
- DB_NAME=gitea
|
|
- DB_USER=gitea
|
|
- DB_PASSWD=${GITEA_MARIADB_GITEA_PASSWORD}
|
|
depends_on:
|
|
- gitea-mariadb
|
|
labels:
|
|
sequentialread-3000-public-port: 443
|
|
sequentialread-3000-public-protocol: https
|
|
sequentialread-3000-public-hostnames: "www.git.sequentialread.com,git.sequentialread.com,git.beta.sequentialread.com"
|
|
sequentialread-3000-container-protocol: http
|
|
|
|
gitea-mariadb:
|
|
image: sequentialread/mariadb-armv7:10.3
|
|
restart: always
|
|
networks:
|
|
- gitea
|
|
volumes:
|
|
- type: bind
|
|
source: ./gitea-mariadb/
|
|
target: /var/lib/mysql
|
|
environment:
|
|
- MYSQL_ROOT_PASSWORD=${GITEA_MARIADB_ROOT_PASSWORD}
|
|
- MYSQL_DATABASE=gitea
|
|
- MYSQL_USER=gitea
|
|
- MYSQL_PASSWORD=${GITEA_MARIADB_GITEA_PASSWORD}
|
|
|
|
stream:
|
|
image: sequentialread/owncast-caching-proxy:0.0.18
|
|
networks:
|
|
- sequentialread
|
|
command: '${SEQUENTIALREAD_NETWORK_EXTERNAL_SERVICE_IPV4}:8080'
|
|
volumes:
|
|
- type: bind
|
|
source: ./owncast-caching-proxy/cache
|
|
target: /app/cache
|
|
environment:
|
|
DEBUG: 0
|
|
labels:
|
|
sequentialread-8080-public-port: 443
|
|
sequentialread-8080-public-protocol: https
|
|
sequentialread-8080-public-hostnames: "stream.sequentialread.com,stream.beta.sequentialread.com"
|
|
sequentialread-8080-container-protocol: http
|
|
|
|
ghost:
|
|
image: ghost:3.41-alpine
|
|
restart: always
|
|
extra_hosts:
|
|
- "smtp.gmail.com:${BLOG_NETWORK_EXTERNAL_SERVICE_IPV4}"
|
|
networks:
|
|
- blog
|
|
volumes:
|
|
- type: bind
|
|
source: ./ghost
|
|
target: /var/lib/ghost/content
|
|
environment:
|
|
- NODE_ENV=production
|
|
- url=https://sequentialread.com
|
|
- database__client=sqlite3
|
|
- database__connection__filename=content/data/ghost-prod.db
|
|
- database__useNullAsDefault=true
|
|
- database__debug=false
|
|
- mail__from=gitlab.sequentialread.com@gmail.com
|
|
- mail__transport=SMTP
|
|
- mail__options__host=smtp.gmail.com
|
|
- mail__options__port=465
|
|
- mail__options__auth__user=gitlab.sequentialread.com@gmail.com
|
|
- mail__options__auth__pass=${GMAIL_PASSWORD}
|
|
labels:
|
|
sequentialread-2368-public-port: 443
|
|
sequentialread-2368-public-protocol: https
|
|
sequentialread-2368-public-hostnames: "sequentialread.com,www.sequentialread.com,beta.sequentialread.com,www.beta.sequentialread.com"
|
|
sequentialread-2368-container-protocol: http
|
|
|
|
|
|
comments:
|
|
image: sequentialread/comments:0.1.45
|
|
restart: always
|
|
extra_hosts:
|
|
- "smtp.gmail.com:${BLOG_NETWORK_EXTERNAL_SERVICE_IPV4}"
|
|
- "captcha.sequentialread.com:${BLOG_NETWORK_EXTERNAL_SERVICE_IPV4}"
|
|
networks:
|
|
- blog
|
|
volumes:
|
|
- type: bind
|
|
source: ./comments
|
|
target: /app/data
|
|
environment:
|
|
- COMMENTS_LISTEN_PORT=8080
|
|
- COMMENTS_BASE_URL=https://comments.sequentialread.com
|
|
- COMMENTS_HASH_SALT=klnv5ii043nbkjz__g34nnk_34wgn26lqlwqb7841mf
|
|
- COMMENTS_CORS_ORIGINS=https://sequentialread.com,https://www.sequentialread.com,https://beta.sequentialread.com,https://www.beta.sequentialread.com
|
|
- COMMENTS_CAPTCHA_API_TOKEN=${CAPTCHA_API_TOKEN}
|
|
- COMMENTS_CAPTCHA_URL=https://captcha.sequentialread.com
|
|
- COMMENTS_CAPTCHA_DIFFICULTY_LEVEL=8
|
|
- COMMENTS_EMAIL_HOST=smtp.gmail.com
|
|
- COMMENTS_EMAIL_PORT=465
|
|
- COMMENTS_EMAIL_USER=gitlab.sequentialread.com@gmail.com
|
|
- COMMENTS_EMAIL_PASSWORD=${GMAIL_PASSWORD}
|
|
- COMMENTS_NOTIFICATION_TARGET=forest.n.johnson@gmail.com
|
|
- COMMENTS_ADMIN_PASSWORD=${COMMENTS_ADMIN_PASSWORD}
|
|
labels:
|
|
sequentialread-8080-public-port: 443
|
|
sequentialread-8080-public-protocol: https
|
|
sequentialread-8080-public-hostnames: "comments.sequentialread.com,comments.beta.sequentialread.com"
|
|
sequentialread-8080-container-protocol: http
|
|
|
|
|
|
blog-external-service:
|
|
image: sequentialread/external-service:0.0.12
|
|
restart: always
|
|
networks:
|
|
blog:
|
|
ipv4_address: ${BLOG_NETWORK_EXTERNAL_SERVICE_IPV4}
|
|
internet-access:
|
|
environment:
|
|
DEBUG_LOG: 'true'
|
|
SERVICE_0_LISTEN: ':465'
|
|
SERVICE_0_DIAL: 'smtp.gmail.com:465'
|
|
SERVICE_1_LISTEN: ':443'
|
|
SERVICE_1_DIAL: '172.17.0.1:443'
|
|
|
|
captcha:
|
|
image: sequentialread/pow-captcha:0.0.11
|
|
restart: always
|
|
networks:
|
|
- blog
|
|
volumes:
|
|
- type: bind
|
|
source: ./captcha/tokens
|
|
target: /app/PoW_Captcha_API_Tokens
|
|
environment:
|
|
- POW_CAPTCHA_ADMIN_API_TOKEN=${CAPTCHA_ADMIN_API_TOKEN}
|
|
labels:
|
|
sequentialread-2370-public-port: 443
|
|
sequentialread-2370-public-protocol: https
|
|
sequentialread-2370-public-hostnames: "captcha.sequentialread.com,captcha.beta.sequentialread.com"
|
|
sequentialread-2370-container-protocol: http
|
|
|
|
|
|
|
|
networks:
|
|
internet-access:
|
|
driver: bridge
|
|
ipam:
|
|
driver: default
|
|
config:
|
|
- subnet: "${INTERNET_ACCESS_NETWORK_CIDR}"
|
|
gitea:
|
|
driver: bridge
|
|
internal: true
|
|
ipam:
|
|
driver: default
|
|
config:
|
|
- subnet: "${GITEA_NETWORK_CIDR}"
|
|
sequentialread:
|
|
driver: bridge
|
|
internal: true
|
|
ipam:
|
|
driver: default
|
|
config:
|
|
- subnet: "${SEQUENTIALREAD_NETWORK_CIDR}"
|
|
blog:
|
|
driver: bridge
|
|
internal: true
|
|
ipam:
|
|
driver: default
|
|
config:
|
|
- subnet: "${BLOG_NETWORK_CIDR}"
|
|
|
|
volumes:
|
|
caddy-socket-volume:
|