This commit is contained in:
DoTheEvo 2023-02-12 19:45:01 +01:00
parent f1823c60ff
commit 3f85e11fb8
7 changed files with 291 additions and 265 deletions

View File

@ -9,7 +9,7 @@
---
* [caddy_v2](caddy_v2/) - reverse proxy
* [bitwarden_rs](bitwarden_rs/) - password manager
* [vaultwarden](vaultwarden/) - password manager
* [bookstack](bookstack/) - notes and documentation
* [borg_backup](borg_backup/) - backup utility
* [ddclient](ddclient/) - automatic DNS update
@ -49,6 +49,8 @@ Repo documents self hosted apps in similar format and also uses caddy for revers
just documentation.<br>
- For persistent storage bind mount `./whatever_data` is used.
No volumes, nor static path somewhere... just relative path next to compose file.
- no version is declared in compose, as the practice was
[deprecated](https://nickjanetakis.com/blog/docker-tip-51-which-docker-compose-api-version-should-you-use)
# Requirements
@ -105,7 +107,9 @@ the variables directly in the compose file only under containers that want them.
Most of the time the images are without any tag,
which defaults to `latest` tag being used.</br>
This is [frowned upon](https://vsupalov.com/docker-latest-tag/),
but feel free to put there the current version to lower the chance of a fuckup.
and you should put there the current tags once things are going.
It will make updates easier when you know you can go back to a working version
with backups and knowing image version.<br>
---
@ -160,15 +164,19 @@ or enable freshly discovered feature for all deployments.
---
### SendGrid and Sendinblue
### Sendinblue
Services often need ability to send emails, for registration, password recset and such...
Services often need ability to send emails, for registration, password reset and such...
I got free sendgrid account which provides 100 free emails a day.
But I heard complains that is not as easy as it was to register on SendGrid.
Sendinblue offers 300 mails a day and is easy to setup.
I also use Sendinblue, I guess it was easy cuz I dont remember anything about it.
It works and got 300 mails a day
```
EMAIL_HOST=smtp-relay.sendinblue.com
EMAIL_PORT=587
EMAIL_HOST_USER=<registration_email@gmail.com>
EMAIL_HOST_PASSWORD=xs...... S1Rzp
EMAIL_USE_TLS=1
```
---

View File

@ -1,246 +0,0 @@
# Bitwarden_rs in docker
###### guide-by-example
![logo](https://i.imgur.com/tT3FQLJ.png)
# Purpose & Overview
Password manager.
* [Official site](https://bitwarden.com/)
* [Github](https://github.com/dani-garcia/bitwarden_rs)
* [DockerHub](https://hub.docker.com/r/bitwardenrs/server)
Bitwarden is a modern popular open source password manager
with wide cross platform support.
But the official Bitwarden server is bit over-engineered,
requiring Microsoft SQL server among other things,
which makes it not an ideal fit for smaller deployments
So here is where Bitwarden_rs by Daniel García comes in.</br>
It is a Bitwarden API implementation written in Rust.
It's very resource efficient, uses about 10MB of RAM,
and close to no CPU.</br>
Webapp part is build using Rocket, a web framework for Rust,
and user data are stored in a simple sqlite database file.
All the client apps are still officials coming from bitwarden,
only the server is a different implementation.
# Files and directory structure
```
/home/
└── ~/
└── docker/
└── bitwarden/
├── bitwarden-data/
├── .env
├── docker-compose.yml
└── bitwarden-backup-script.sh
```
* `bitwarden-data/` - a directory where bitwarden will store its database and other data
* `.env` - a file containing environment variables for docker compose
* `docker-compose.yml` - a docker compose file, telling docker how to run the container
* `bitwarden-backup-script.sh` - a backup script if you want it
You only need to provide the files.</br>
The directory is created by docker compose on the first run.
# docker-compose
[Documentation](https://github.com/dani-garcia/bitwarden_rs/wiki/Using-Docker-Compose) on compose.
`docker-compose.yml`
```yml
version: "3"
services:
bitwarden:
image: bitwardenrs/server
container_name: bitwarden
hostname: bitwarden
restart: unless-stopped
env_file: .env
volumes:
- ./bitwarden-data/:/data/
networks:
default:
external:
name: $DOCKER_MY_NETWORK
```
`.env`
```bash
# GENERAL
MY_DOMAIN=example.com
DOCKER_MY_NETWORK=caddy_net
TZ=Europe/Bratislava
# BITWARDEN
DOMAIN=https://passwd.example.com
ADMIN_TOKEN=YdLo1TM4MYEQ948GOVZ29IF4fABSrZMpk9
SIGNUPS_ALLOWED=false
WEBSOCKET_ENABLED=true
# USING SENDGRID FOR SENDING EMAILS
SMTP_SSL=true
SMTP_EXPLICIT_TLS=true
SMTP_HOST=smtp.sendgrid.net
SMTP_PORT=465
SMTP_FROM=admin@example.com
SMTP_USERNAME=apikey
SMTP_PASSWORD=<sendgrid-api-key-goes-here>
```
**All containers must be on the same network**.</br>
Which is named in the `.env` file.</br>
If one does not exist yet: `docker network create caddy_net`
# Reverse proxy
Caddy v2 is used, details
[here](https://github.com/DoTheEvo/selfhosted-apps-docker/tree/master/caddy_v2).</br>
Bitwarden_rs documentation has a
[section on reverse proxy.](https://github.com/dani-garcia/bitwarden_rs/wiki/Proxy-examples)
`Caddyfile`
```
bitwarden.{$MY_DOMAIN} {
encode gzip
header {
# Enable cross-site filter (XSS) and tell browser to block detected attacks
X-XSS-Protection "1; mode=block"
# Disallow the site to be rendered within a frame (clickjacking protection)
X-Frame-Options "DENY"
# Prevent search engines from indexing (optional)
X-Robots-Tag "none"
# Server name removing
-Server
}
# Notifications redirected to the websockets server
reverse_proxy /notifications/hub bitwarden:3012
# Proxy the Root directory to Rocket
reverse_proxy bitwarden:80
}
```
# Forward port 3012 TCP on your router
[WebSocket](https://youtu.be/2Nt-ZrNP22A) protocol is used for notifications
so that all web based clients, including desktop app,
can immediately sync when a change happens on the server.
* environment variable `WEBSOCKET_ENABLED=true` needs to be set in the `.env` file</br>
* reverse proxy needs to route `/notifications/hub` to port 3012</br>
* your router/firewall needs to **forward port 3012** to the docker host,
same as port 80 and 443 are forwarded
To test if websocket works, have the desktop app open
and make changes through browser extension, or through the website.
Changes should immediately appear in the desktop app. If it's not working,
you need to manually sync for changes to appear.
# Extra info
**Bitwarden can be managed** at `<url>/admin` and entering `ADMIN_TOKEN`
set in the `.env` file. Especially if sign ups are disabled it is the only way
to invite users.
**Push notifications** are not working at this moment.
[Github issue](https://github.com/dani-garcia/bitwarden_rs/issues/126).</br>
The purpose of [Push notifications](https://www.youtube.com/watch?v=8D1NAezC-Dk)
is the same as WebSocket notifications, to tell the clients that a change
happened on the server so that they are synced immediately.
But they are for apps on mobile devices and it would likely take releasing and
maintaining own bitwarden_rs version of the Android/iOS mobile apps
to have them working.</br>
So you better manually sync before making changes.
---
![interface-pic](https://i.imgur.com/5LxEUsA.png)
# Update
[Watchtower](https://github.com/DoTheEvo/selfhosted-apps-docker/tree/master/watchtower)
updates the image automatically.
Manual image update:
- `docker-compose pull`</br>
- `docker-compose up -d`</br>
- `docker image prune`
# Backup and restore
#### Backup
Using [borg](https://github.com/DoTheEvo/selfhosted-apps-docker/tree/master/borg_backup)
that makes daily snapshot of the entire directory.
#### Restore
* down the bitwarden container `docker-compose down`</br>
* delete the entire bitwarden directory</br>
* from the backup copy back the bitwarden directory</br>
* start the container `docker-compose up -d`
# Backup of just user data
Users data daily export using the
[official procedure.](https://github.com/dani-garcia/bitwarden_rs/wiki/Backing-up-your-vault)</br>
For bitwarden_rs it means sqlite database dump and backing up `attachments` directory.</br>
Daily [borg](https://github.com/DoTheEvo/selfhosted-apps-docker/tree/master/borg_backup) run
takes care of backing up the directory.
So only database dump is needed.</br>
The created backup sqlite3 file is overwritten on every run of the script,
but that's ok since borg is making daily snapshots.
#### Create a backup script
Placed inside `bitwarden` directory on the host.
`bitwarden-backup-script.sh`
```bash
#!/bin/bash
# CREATE SQLITE BACKUP
docker container exec bitwarden sqlite3 /data/db.sqlite3 ".backup '/data/BACKUP.bitwarden.db.sqlite3'"
```
the script must be **executable** - `chmod +x bitwarden-backup-script.sh`
#### Cronjob
Running on the host, so that the script will be periodically run.
* `su` - switch to root
* `crontab -e` - add new cron job</br>
* `0 21 * * * /home/bastard/docker/bitwarden/bitwarden-backup-script.sh`</br>
runs it every day [at 21:00](https://crontab.guru/#0_21_*_*_*)
* `crontab -l` - list cronjobs to check
# Restore the user data
Assuming clean start.
* start the bitwarden container: `docker-compose up -d`
* let it run so it creates its file structure
* down the container `docker-compose down`
* in `bitwarden/bitwarden-data/`</br>
replace `db.sqlite3` with the backup one `BACKUP.bitwarden.db.sqlite3`</br>
replace `attachments` directory with the one from the borg repository
* start the container `docker-compose up -d`
Again, the above steps are based on the
[official procedure.](https://github.com/dani-garcia/bitwarden_rs/wiki/Backing-up-your-vault)

View File

@ -17,4 +17,4 @@ Most of the stuff around here is about deployment, how to deploy others people w
# Basics
tag - not just version number, tags are not even present on local docker..

View File

@ -18,7 +18,7 @@ Instant notifications if email feels old timey and crowded
* **gotify** - great for single person use, but the moment theres more people
they need to share single account and so lack the ability to choose
what to get and what not to get
what to get and what not to get.
* **ntfy** - simple original approach to just subscribing to "topics" without
authentification. Very simple single line push notification.
Support for multiple user, supports ios.

View File

@ -0,0 +1,193 @@
{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"target": {
"limit": 100,
"matchAny": false,
"tags": [],
"type": "dashboard"
},
"type": "dashboard"
}
]
},
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 1,
"links": [],
"liveNow": false,
"panels": [
{
"datasource": {
"type": "loki",
"uid": "Dsg1O90Vk"
},
"description": "",
"fieldConfig": {
"defaults": {
"color": {
"mode": "fixed"
},
"custom": {
"axisCenteredZero": false,
"axisColorMode": "series",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "bars",
"fillOpacity": 73,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 10,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "normal"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"min": 0,
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "string"
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 24,
"x": 0,
"y": 0
},
"id": 4,
"interval": "1m",
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": false
},
"tooltip": {
"mode": "multi",
"sort": "none"
}
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "Dsg1O90Vk"
},
"editorMode": "code",
"expr": "count_over_time({compose_service=\"minecraft\"} |= `` [1m])",
"hide": false,
"queryType": "range",
"refId": "A"
}
],
"title": "Logs volume",
"transformations": [
{
"id": "renameByRegex",
"options": {
"regex": "(.*)",
"renamePattern": "Logs"
}
}
],
"transparent": true,
"type": "timeseries"
},
{
"datasource": {
"type": "loki",
"uid": "Dsg1O90Vk"
},
"gridPos": {
"h": 17,
"w": 24,
"x": 0,
"y": 8
},
"id": 2,
"options": {
"dedupStrategy": "none",
"enableLogDetails": true,
"prettifyLogMessage": false,
"showCommonLabels": false,
"showLabels": false,
"showTime": false,
"sortOrder": "Descending",
"wrapLogMessage": false
},
"targets": [
{
"datasource": {
"type": "loki",
"uid": "Dsg1O90Vk"
},
"editorMode": "builder",
"expr": "{container_name=\"minecraft\"} |= ``",
"queryType": "range",
"refId": "A"
}
],
"timeFrom": "now-12h",
"title": "Panel Title",
"type": "logs"
}
],
"refresh": "1m",
"schemaVersion": 37,
"style": "dark",
"tags": [],
"templating": {
"list": []
},
"time": {
"from": "now-3h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Minecraft",
"uid": "CQjQd9A4k",
"version": 11,
"weekStart": ""
}

View File

@ -203,6 +203,12 @@ TZ=Europe/Bratislava
GF_SECURITY_ADMIN_USER=admin
GF_SECURITY_ADMIN_PASSWORD=admin
GF_USERS_ALLOW_SIGN_UP=false
# GRAFANA EMAIL
GF_SMTP_ENABLED=true
GF_SMTP_HOST=smtp-relay.sendinblue.com:587
GF_SMTP_USER=example@gmail.com
GF_SMTP_PASSWORD=xzu0dfFhn3eqa
```
**All containers must be on the same network**.</br>
@ -713,17 +719,82 @@ Including pushing information from windows powershell.
```
</details>
### Logs in grafana
![logo](https://i.imgur.com/MHYmxPi.png)
Now with driver installed, files in place, compose edited,..
Now with the driver installed, config files in place, compose edited,..
* In grafana, loki needs to be added as a datasource.<br>
If everything works as it should, there should be no red notice, down left side
only gree:<br>
`Data source connected and labels found.`
* In `Explore` section, if the input is set to `Builder`, picking from dropdown
If everything works as it should, there should be no red notice, down left side,
only green: `Data source connected and labels found.`
* In `Explore` section, input set to `Builder`, picking from dropdown
filter menu container_name = minecraft, and hitting run query..
this should result in seeing minecraft logs.
* In Alert grafana section,
this should result in seeing minecraft logs and their volume/time graph.
* To recreat this Explore view as a dashboard, as a practice...
- new dashboard, panel
- datasource - Loki
- query - `count_over_time({compose_service="minecraft"} |= `` [1m])`<br>
switch from `builder` to `code` is needed to paste it
- `Query options` - Min interval=1m
- `transformation` - Rename by regex - `(.*)` - `Logs`
- time series graph
- Title - Logs volume
- transparent background
- legend off
- graph styles - bar
- graph styles - bar - point size = 10
- stack series - normal
- color scheme - single color
### Alerts for Loki
* Alerts section in grafana
* Alert rules, new alert
- 1. Set a query and alert condition
- **A**
- now-5min to now
- container_name=minecraft
- line contains=joined the game
- **B**
- Reduce - because alerts can only work with single number
- Function=Last
- Input=A
- Mode=Strict
- **C** - the actual condition for alert
- Input=B
- is above 0
- click - Make this the alert condition
- 2. Alert evaluation behavior
- evaluate every 5m for 0s
- Configure no data and error handling
- Alert state if no data or all values are null=OK
- 3. Add details for your alert
- Rule name=Minecraft-player-joined
- Folder, add new, "Alerts"
- Group, add new, "Docker"
- 4. Notifications
- nothing
- Save and exit
* **Contact points**
- New contact point
- Name = ntfy
- Contact point type = Webhook
- URL = https://ntfy.example.com/grafana
- Test; Save
* Notification policies
- edit default
- Default contact point = ntfy

View File

@ -95,8 +95,8 @@ services:
networks:
default:
external:
name: $DOCKER_MY_NETWORK
name: $DOCKER_MY_NETWORK
external: true
```
`.env`