Merge pull request #1 from ruanbekker/base

Base
main
Ruan Bekker 3 years ago committed by GitHub
commit 22fca48f2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 20
      .drone.yml
  2. 19
      README.md
  3. 23
      bitwarden/bitwarden/frontend/bitwarden.conf
  4. 80
      bitwarden/docker-compose.yml
  5. 2
      bitwarden/sample-env
  6. 175
      logging-loki/docker-compose.yml
  7. 15
      logging-loki/loki/configs/fluentbit/fluent-bit.conf
  8. 82
      logging-loki/loki/configs/loki/consul_config.yaml
  9. 55
      logging-loki/loki/configs/promtail/promtail-config.yaml
  10. 4
      logging-loki/sample-env
  11. 128
      rocket-chat/docker-compose.yml
  12. 10
      rocket-chat/sample-env
  13. 82
      traefik/docker-compose.yml
  14. 3
      traefik/sample-env

@ -8,3 +8,23 @@ steps:
image: busybox
commands:
- echo hi
- name: gotify
image: fredix/drone-gotify
settings:
gotifytoken:
from_secret: plugin_gotifytoken
gotifyendpoint:
from_secret: plugin_gotifyendpoint
gotifytitle:
from_secret: plugin_gotifytitle
gotifypriority:
from_secret: plugin_gotifypriority
message: >
{{#success build.status}}
build {{build.number}} succeeded on {{repo.name}}. Good job {{build.author}} {{build.link}}
{{else}}
build {{build.number}} failed on {{repo.name}}. Fix me please {{build.author}} {{build.link}}
{{/success}}
when:
status: [ success, failure ]

@ -1,2 +1,21 @@
# docker-selfhosted-server
My Hobby Server for Self-Hosted Applications on Docker
## Usage
In each application directory resides a `sample-env` file, which includes the required environment variables that you can copy to `.env`:
```
$ cd folder/
$ cp sample-env .env
# modify .env to desired values
```
## Included Applications
I will add more over time:
- `traefik`
- `bitwarden`
- `rocket-chat`
- `grafana loki`

@ -0,0 +1,23 @@
server {
listen 80;
server_name _;
client_max_body_size 128M;
location / {
proxy_pass http://bitwarden-backend:80;
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 /notifications/hub {
proxy_pass http://bitwarden-backend:3012;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /notifications/hub/negotiate {
proxy_pass http://bitwarden-backend:80;
}
}

@ -0,0 +1,80 @@
# resource
# https://github.com/JulianRunnels/Bitwarden_Self_Host/blob/master/docker-compose.yml
# https://medium.com/swlh/set-up-your-own-personal-password-vault-313d76374046
# to use grafana loki for logging:
# logging:
# driver: loki
# options:
# loki-url: http://$SERVER_IP:3100/loki/api/v1/push
# loki-external-labels: job=dockerlogs
version: "3.8"
services:
bitwarden-frontend:
image: nginx:1.15-alpine
container_name: bitwarden-frontend
restart: unless-stopped
volumes:
- $DOCKER_VOLUME_PATH/bitwarden/frontend/bitwarden.conf:/etc/nginx/conf.d/bitwarden.conf
networks:
- public
depends_on:
- bitwarden-backend
labels:
- "traefik.enable=true"
- "traefik.http.routers.bitwarden.rule=Host(`bitwarden.$DOMAIN`)"
- "traefik.http.routers.bitwarden.entrypoints=https"
- "traefik.http.routers.bitwarden.tls.certresolver=dns-cloudflare"
- "traefik.http.routers.bitwarden.service=bitwarden-service"
- "traefik.http.services.bitwarden-service.loadbalancer.server.port=80"
logging:
driver: "json-file"
options:
max-size: "1m"
bitwarden-backend:
image: vaultwarden/server:latest
container_name: bitwarden-backend
restart: unless-stopped
volumes:
- $DOCKER_VOLUME_PATH/bitwarden/backend/data:/data
environment:
- WEBSOCKET_ENABLED=true
- SIGNUPS_ALLOWED=false
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
bitwarden-backup:
image: bruceforce/bw_backup:latest
container_name: bitwarden-backup
restart: unless-stopped
depends_on:
- bitwarden-backend
volumes:
- $DOCKER_VOLUME_PATH/bitwarden/backend/data:/data
- $DOCKER_VOLUME_PATH/bitwarden/backend/backup:/backup
- /etc/timezone:/etc/timezone:ro
- /etc/localtime:/etc/localtime:ro
environment:
- DB_FILE=/data/db.sqlite3
- BACKUP_FILE=/backup/backup.sqlite3
- CRON_TIME=0 1 * * *
- TIMESTAMP=false
- UID=0
- GID=0
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
networks:
public:
name: public

@ -0,0 +1,2 @@
DOCKER_VOLUME_PATH=.
DOMAIN=

@ -0,0 +1,175 @@
version: '3.8'
services:
loki-redis:
image: bitnami/redis:latest
restart: unless-stopped
container_name: loki-redis
environment:
ALLOW_EMPTY_PASSWORD: "yes"
ports:
- 6379
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
loki-minio:
image: minio/minio:latest
container_name: loki-minio
volumes:
- $DOCKER_VOLUME_PATH/loki/minio/data:/data
env_file: .env
environment:
- MINIO_ROOT_USER=${MINIO_ROOT_USER:-EXAMPLEACCESSKEY}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD:-EXAMPLEACCESSSECRET}
command: server /data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 20s
retries: 3
restart: unless-stopped
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
loki-consul:
container_name: loki-consul
image: consul:1.9
command: agent -log-level=info -dev -client 0.0.0.0
restart: unless-stopped
volumes:
- $DOCKER_VOLUME_PATH/loki/consul/config:/consul/config
- $DOCKER_VOLUME_PATH/loki/consul/data:/consul/data
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
loki-distributor:
image: grafana/loki:2.2.1
container_name: loki-distributor
restart: unless-stopped
ports:
- 3100:3100
depends_on:
- loki-redis
- loki-consul
- loki-minio
volumes:
- $DOCKER_VOLUME_PATH/loki/configs/loki/consul_config.yaml:/etc/loki/config.yaml
command: -config.file=/etc/loki/config.yaml -target=distributor
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
loki-querier:
image: grafana/loki:2.2.1
container_name: loki-querier
restart: unless-stopped
ports:
- 3100
depends_on:
- loki-redis
- loki-consul
- loki-minio
volumes:
- $DOCKER_VOLUME_PATH/loki/configs/loki/consul_config.yaml:/etc/loki/config.yaml
command: -config.file=/etc/loki/config.yaml -target=querier
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
loki-ingester:
image: grafana/loki:2.2.1
container_name: loki-ingester
restart: unless-stopped
ports:
- 3100
depends_on:
- loki-redis
- loki-consul
- loki-minio
volumes:
- $DOCKER_VOLUME_PATH/loki/configs/loki/consul_config.yaml:/etc/loki/config.yaml
command: -config.file=/etc/loki/config.yaml -target=ingester
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
loki-table-manager:
image: grafana/loki:2.2.1
container_name: loki-table-manager
restart: unless-stopped
ports:
- 3100
depends_on:
- loki-redis
- loki-consul
- loki-minio
volumes:
- $DOCKER_VOLUME_PATH/loki/configs/loki/consul_config.yaml:/etc/loki/config.yaml
command: -config.file=/etc/loki/config.yaml -target=table-manager
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
promtail:
image: grafana/promtail:latest
container_name: promtail
restart: unless-stopped
volumes:
- $DOCKER_VOLUME_PATH/loki/configs/promtail/promtail-config.yaml:/etc/promtail/docker-config.yaml
- /var/log:/var/log
- /var/lib/docker/:/var/lib/docker:ro
command: -config.file=/etc/promtail/docker-config.yaml
depends_on:
- loki-ingester
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
fluent-bit:
image: grafana/fluent-bit-plugin-loki:latest
container_name: fluent-bit
environment:
- LOKI_URL=http://loki-distributor:3100/loki/api/v1/push
volumes:
- $DOCKER_VOLUME_PATH/loki/configs/fluentbit/fluent-bit.conf:/fluent-bit/etc/fluent-bit.conf
ports:
- "24224:24224"
- "24224:24224/udp"
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
networks:
public:
name: public

@ -0,0 +1,15 @@
[INPUT]
Name forward
Listen 0.0.0.0
Port 24224
[Output]
Name grafana-loki
Match *
Url ${LOKI_URL}
RemoveKeys source,container_id
Labels {job="fluentbit"}
LabelKeys container_name
BatchWait 1s
BatchSize 1001024
LineFormat json
LogLevel info

@ -0,0 +1,82 @@
auth_enabled: false
server:
http_listen_port: 3100
ingester:
lifecycler:
ring:
kvstore:
store: consul
consul:
host: loki-consul:8500
heartbeat_timeout: 1m
replication_factor: 1
num_tokens: 128
heartbeat_period: 5s
join_after: 0s
min_ready_duration: 10s
interface_names:
- "eth0"
final_sleep: 30s
chunk_idle_period: 5m
chunk_retain_period: 30s
schema_config:
configs:
- from: 2020-05-15
store: boltdb-shipper
object_store: s3
schema: v11
index:
prefix: loki_
period: 24h
storage_config:
aws:
bucketnames: loki
endpoint: minio.$DOMAIN
access_key_id: EXAMPLEACCESSKEY
secret_access_key: EXAMPLEACCESSSECRET
insecure: false
s3forcepathstyle: true
#s3: s3://EXAMPLEACCESSKEY:EXAMPLEACCESSSECRET@minio.:3000/loki
#s3forcepathstyle: true
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/index_cache
resync_interval: 5s
shared_store: s3
limits_config:
enforce_metric_name: false
reject_old_samples: true
reject_old_samples_max_age: 168h
chunk_store_config:
chunk_cache_config:
redis:
endpoint: "loki-redis:6379"
timeout: 100ms
expiration: 0s
max_look_back_period: 0s
write_dedupe_cache_config:
redis:
endpoint: "loki-redis:6379"
timeout: 100ms
expiration: 0s
table_manager:
chunk_tables_provisioning:
inactive_read_throughput: 1
inactive_write_throughput: 1
provisioned_read_throughput: 5
provisioned_write_throughput: 5
index_tables_provisioning:
inactive_read_throughput: 1
inactive_write_throughput: 1
provisioned_read_throughput: 5
provisioned_write_throughput: 5
retention_deletes_enabled: false
retention_period: 0s

@ -0,0 +1,55 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki-distributor:3100/loki/api/v1/push
scrape_configs:
- job_name: logs
pipeline_stages:
static_configs:
- targets:
- localhost
labels:
job: hostlogs
environment: home
__path__: /var/log/*.log
- job_name: containers
static_configs:
- targets:
- localhost
labels:
job: containerlogs
__path__: /var/lib/docker/containers/*/*log
pipeline_stages:
- json:
expressions:
output: log
stream: stream
attrs:
- json:
expressions:
tag:
source: attrs
- regex:
expression: (?P<image_name>(?:[^|]*[^|])).(?P<container_name>(?:[^|]*[^|])).(?P<image_id>(?:[^|]*[^|])).(?P<container_id>(?:[^|]*[^|]))
source: tag
- timestamp:
format: RFC3339Nano
source: time
- labels:
tag:
stream:
image_name:
container_name:
image_id:
container_id:
- output:
source: output

@ -0,0 +1,4 @@
DOMAIN=
MINIO_ROOT_USER=
MINIO_ROOT_PASSWORD=
DOCKER_VOLUME_PATH=.

@ -0,0 +1,128 @@
version: "3.7"
services:
rocketchat:
image: rocketchat/rocket.chat:latest
container_name: rocketchat
restart: unless-stopped
command: >
bash -c
"for i in `seq 1 30`; do
INSTANCE_IP=$$(hostname -i) node main.js &&
s=$$? && break || s=$$?;
echo \"Tried $$i times. Waiting 5 secs...\";
sleep 5;
done; (exit $$s)"
volumes:
- ${DOCKER_VOLUME_PATH}/rocketchat/app/data/uploads:/app/uploads
- /tmp:/tmp
environment:
- PORT=3000
- ROOT_URL=http://chat.$DOMAIN
- MONGO_URL=mongodb://rocketchat-mongo:27017/rocketchat
- MONGO_OPLOG_URL=mongodb://rocketchat-mongo:27017/local
ports:
- 9458:9458 # prometheus
labels:
- "traefik.enable=true"
- "traefik.http.routers.rocketchat-app.rule=Host(`chat.$DOMAIN`)"
- "traefik.http.routers.rocketchat-app.entrypoints=https"
- "traefik.http.routers.rocketchat-app.tls.certresolver=dns-cloudflare"
- "com.centurylinklabs.watchtower.enable=true"
depends_on:
- rocketchat-mongo
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
rocketchat-mongo:
image: mongo:4.0
container_name: rocketchat-mongo
restart: unless-stopped
command: mongod --oplogSize 128 --replSet rs0
volumes:
- ${DOCKER_VOLUME_PATH}/rocketchat/mongo/data/db:/data/db
- ${DOCKER_VOLUME_PATH}/rocketchat/mongo/data/backups:/dump
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
rocketchat-mongo-init-replica:
image: mongo:4.0
container_name: rocketchat-mono-init-replica
command: >
bash -c
"for i in `seq 1 30`; do
mongo rocketchat-mongo/rocketchat --eval \"
rs.initiate({
_id: 'rs0',
members: [ { _id: 0, host: 'localhost:27017' } ]})\" &&
s=$$? && break || s=$$?;
echo \"Tried $$i times. Waiting 5 secs...\";
sleep 5;
done; (exit $$s)"
depends_on:
- rocketchat-mongo
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
rocketchat-hubot:
image: rocketchat/hubot-rocketchat:v1.0.11
container_name: rocketchat-hubot
restart: unless-stopped
environment:
- MONGODB_URL=mongodb://rocketchat-mongo:27017/hubot-brain
- ROCKETCHAT_URL=rocketchat:3000
- ROCKETCHAT_ROOM=GENERAL
- ROCKETCHAT_USER=${ROCKETCHAT_USER}
- ROCKETCHAT_PASSWORD=${ROCKETCHAT_PASSWORD}
- BOT_NAME=${ROCKETCHAT_BOT_NAME}
- RESPOND_TO_DM=true
- LISTEN_ON_ALL_PUBLIC=true
- EXTERNAL_SCRIPTS=${ROCKETCHAT_EXTERNAL_SCRIPTS}
- TZ=${TZ}
depends_on:
- rocketchat
volumes:
- ${DOCKER_VOLUME_PATH}/rocketchat/hubot/data/hubotscripts:/home/hubot/scripts
ports:
- 3011:8081
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
rocketchat-mongo-express:
image: mongo-express
container_name: roccketchat-mongo-express
environment:
- ME_CONFIG_MONGODB_URL=mongodb://rocketchat-mongo:27017/
- ME_CONFIG_MONGODB_ENABLE_ADMIN=true
- ME_CONFIG_BASICAUTH_USERNAME=admin
- ME_CONFIG_BASICAUTH_PASSWORD=$ME_CONFIG_BASICAUTH_PASSWORD
ports:
- 18087:8081
networks:
- public
depends_on:
- rocketchat-mongo
logging:
driver: "json-file"
options:
max-size: "1m"
networks:
public:
name: public

@ -0,0 +1,10 @@
DOMAIN=
ME_CONFIG_BASICAUTH_PASSWORD=
DOCKER_VOLUME_PATH=.
ROCKETCHAT_ROOM=GENERAL
ROCKETCHAT_USER=hubot
ROCKETCHAT_PASSWORD=
ROCKETCHAT_BOT_NAME=hubot
# https://developer.rocket.chat/guides/bots-guides/create-and-run-a-bot/run-a-hubot-bot
ROCKETCHAT_EXTERNAL_SCRIPTS=hubot-help,hubot-diagnostics,hubot-seen,hubot-links,hubot-pugme,hubot-memes,hubot-isup
TZ=/usr/share/zoneinfo/Africa/Johannesburg

@ -0,0 +1,82 @@
# Resources
# - https://www.smarthomebeginner.com/cloudflare-settings-for-traefik-docker/
# - https://www.smarthomebeginner.com/traefik-2-docker-tutorial/
# - https://gist.github.com/coltenkrauter/124ec31d616fa4c0dcf25d79462a6237
# - https://faun.pub/deploy-nextcloud-with-docker-compose-traefik-2-postgresql-and-redis-fd1ffc166173
# - https://github.com/jnsgruk/nextcloud-docker-compose/blob/master/traefik/docker-compose.yml
# - https://doc.traefik.io/traefik/middlewares/basicauth/
# Generate auth:
# echo $(htpasswd -nb user password) | sed -e s/\\$/\\$\\$/g
# https://gist.github.com/coltenkrauter/124ec31d616fa4c0dcf25d79462a6237
version: '3.8'
services:
traefik:
image: traefik:livarot
container_name: traefik
restart: unless-stopped
env_file: .env
command:
- "--api=true"
- "--api.dashboard=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=http"
- "--certificatesresolvers.letsencrypt.acme.email=$EMAIL"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
- "--certificatesresolvers.dns-cloudflare.acme.email=$EMAIL"
- "--certificatesresolvers.dns-cloudflare.acme.storage=/cloudflare/acme.json"
- "--certificatesresolvers.dns-cloudflare.acme.dnsChallenge.provider=cloudflare"
- "--certificatesresolvers.dns-cloudflare.acme.dnsChallenge.resolvers=1.1.1.1:53,1.0.0.1:53"
- "--certificatesresolvers.dns-cloudflare.acme.dnsChallenge.delayBeforeCheck=90"
- "--entrypoints.http.address=:80"
- "--entrypoints.https.address=:443"
- "--entrypoints.https.forwardedHeaders.trustedIPs=173.245.48.0/20,103.21.244.0/22,103.22.200.0/22,103.31.4.0/22,141.101.64.0/18,108.162.192.0/18,190.93.240.0/20,188.114.96.0/20,197.234.240.0/22,198.41.128.0/17,162.158.0.0/15,104.16.0.0/13,104.24.0.0/14,172.64.0.0/13,131.0.72.0/22,104.16.0.0/13,104.24.0.0/14" # allow cloudflare source ips to set x-forwarded-for headers - https://www.cloudflare.com/ips-v4
- "--entrypoints.https.http.tls.certresolver=dns-cloudflare"
- "--entrypoints.https.http.tls.domains[0].main=$DOMAIN"
- "--entrypoints.https.http.tls.domains[0].sans=*.$DOMAIN"
- "--entrypoints.https.http.tls.domains[1].main=$DOMAIN2"
- "--entrypoints.https.http.tls.domains[1].sans=*.$DOMAIN2"
- "--entrypoints.https.http.tls.options=tls-opts@file"
- "--log.level=INFO"
- "--log.format=json"
- "--metrics.prometheus=true"
- "--ping=true"
- "--providers.docker=true"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.network=public"
- "--providers.docker.swarmMode=false"
environment:
- CF_API_EMAIL=$CF_API_EMAIL
- CF_API_KEY=$CF_API_KEY
ports:
- 80:80
- 443:443
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- $DOCKER_VOLUME_PATH/traefik/auth:/auth
- $DOCKER_VOLUME_PATH/traefik/letsencrypt:/letsencrypt
- $DOCKER_VOLUME_PATH/traefik/cloudflare:/cloudflare
labels:
- "traefik.enable=true"
# catchall for redirecting http to https
- "traefik.http.routers.http-catchall.entrypoints=http"
- "traefik.http.routers.http-catchall.rule=HostRegexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
- "traefik.http.routers.traefik-rtr.entrypoints=https"
- "traefik.http.routers.traefik-rtr.rule=Host(`traefik.$DOMAIN`)"
- "traefik.http.routers.traefik-rtr.service=api@internal"
- "traefik.http.routers.traefik-rtr.middlewares=dashboard-auth"
- "traefik.http.middlewares.dashboard-auth.basicauth.usersfile=/auth/passwords"
- "traefik.http.services.api@internal.loadbalancer.server.port=8080"
networks:
- public
logging:
driver: "json-file"
options:
max-size: "1m"
networks:
public:
name: public

@ -0,0 +1,3 @@
DOCKER_VOLUME_PATH=.
DOMAIN=
DOMAIN2=
Loading…
Cancel
Save