From 361196253612c51c9c51e82c66bc029ed20bdb91 Mon Sep 17 00:00:00 2001 From: Adrien Poupa Date: Tue, 2 Jan 2024 01:59:48 -0500 Subject: [PATCH] feat(joplin): Add Joplin Server --- .env.example | 2 +- README.md | 6 +++ joplin/.env.example | 8 +++ joplin/.gitignore | 4 ++ joplin/README.md | 49 +++++++++++++++++ joplin/backup.env.example | 6 +++ {tandoor/backup => joplin/database}/.gitkeep | 0 joplin/docker-compose.yml | 55 ++++++++++++++++++++ joplin/healthcheck/healthcheck.js | 28 ++++++++++ tandoor/README.md | 2 +- tandoor/database/.gitkeep | 0 tandoor/mediafiles/.gitkeep | 0 12 files changed, 158 insertions(+), 2 deletions(-) create mode 100644 joplin/.env.example create mode 100644 joplin/.gitignore create mode 100644 joplin/README.md create mode 100644 joplin/backup.env.example rename {tandoor/backup => joplin/database}/.gitkeep (100%) create mode 100644 joplin/docker-compose.yml create mode 100644 joplin/healthcheck/healthcheck.js delete mode 100644 tandoor/database/.gitkeep delete mode 100755 tandoor/mediafiles/.gitkeep diff --git a/.env.example b/.env.example index 3e7da31..dbd15e9 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,5 @@ COMPOSE_PROFILES= -COMPOSE_FILE=docker-compose.yml:adguardhome/docker-compose.yml:tandoor/docker-compose.yml +COMPOSE_FILE=docker-compose.yml:adguardhome/docker-compose.yml:tandoor/docker-compose.yml:joplin/docker-compose.yml USER_ID=1000 GROUP_ID=1000 TIMEZONE="America/New_York" diff --git a/README.md b/README.md index d344ded..baee727 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ I am running it in Ubuntu Server 22.04; I also tested this setup on a [Synology * [DHCP](#dhcp) * [Expose DNS Server with Tailscale](#expose-dns-server-with-tailscale) * [Tandoor](#tandoor) + * [Joplin](#joplin) * [Customization](#customization) * [Optional: Using the VPN for *arr apps](#optional-using-the-vpn-for-arr-apps) * [Synology Quirks](#synology-quirks) @@ -72,6 +73,7 @@ I am running it in Ubuntu Server 22.04; I also tested this setup on a [Synology | [FlareSolverr](https://github.com/FlareSolverr/FlareSolverr) | Optional - Proxy server to bypass Cloudflare protection in Prowlarr
Enable with `COMPOSE_PROFILES=flaresolverr` | [flaresolverr/flaresolverr](https://hub.docker.com/r/flaresolverr/flaresolverr) | | | [AdGuard Home](https://adguard.com/en/adguard-home/overview.html) | Optional - Network-wide software for blocking ads & tracking
Enable with `COMPOSE_PROFILES=adguardhome` | [adguard/adguardhome](https://hub.docker.com/r/adguard/adguardhome) | | | [Tandoor](https://tandoor.dev) | Optional - Smart recipe management
Enable with `COMPOSE_PROFILES=tandoor` | [vabene1111/recipes](https://hub.docker.com/r/vabene1111/recipes) | /recipes | +| [Joplin](https://joplinapp.org/) | Optional - Note taking application
Enable with `COMPOSE_PROFILES=joplin` | [joplin/server](https://hub.docker.com/r/joplin/server) | /joplin | Optional containers are not enabled by default, they need to be enabled, see [Optional Services](#optional-services) for more information. @@ -370,6 +372,10 @@ Just make sure that AdGuard Home listens to all interfaces. See [here](./tandoor/README.md). +### Joplin + +See [here](./joplin/README.md). + ## Customization You can override the configuration of a service or add new services by creating a new `docker-compose.override.yml` file, diff --git a/joplin/.env.example b/joplin/.env.example new file mode 100644 index 0000000..d65ee4f --- /dev/null +++ b/joplin/.env.example @@ -0,0 +1,8 @@ +MAILER_ENABLED=false +MAILER_HOST= +MAILER_PORT=465 +MAILER_SECURITY=MailerSecurity.Tls +MAILER_AUTH_USER= +MAILER_AUTH_PASSWORD= +MAILER_NOREPLY_NAME= +MAILER_NOREPLY_EMAIL= \ No newline at end of file diff --git a/joplin/.gitignore b/joplin/.gitignore new file mode 100644 index 0000000..ba6d14b --- /dev/null +++ b/joplin/.gitignore @@ -0,0 +1,4 @@ +/database +/storage +.env +backup.env \ No newline at end of file diff --git a/joplin/README.md b/joplin/README.md new file mode 100644 index 0000000..53ae6f6 --- /dev/null +++ b/joplin/README.md @@ -0,0 +1,49 @@ +# Joplin + +[Joplin](https://joplinapp.org/) is an open source note-taking app. Capture your thoughts and securely access them from any device. + +This service lets you host your own Joplin server, which your clients can connect to. + +## Installation + +Enable Joplin by setting `COMPOSE_PROFILES=joplin`. It will be accessible at `/joplin`. + +Copy the example environment file and edit as needed before running Joplin: `cp joplin/env.example joplin/.env`. + +## Backup + +Joplin's database and media files can be backed up in the cloud storage product of your choice with [Rclone](https://rclone.org/). + +Before a backup can be made, `rclone config` must be run to generate the configuration file: + +```shell +docker compose run --rm -it joplin-backup rclone config +``` + +It will generate a `rclone.conf` configuration file in ./joplin/rclone/rclone.conf. + +Copy the backup environment file to `backup.env` and fill it as needed: +`cp backup.env.exmple backup.env` + +| Variable | Description | Default | +|------------------------|---------------------------------------------------------------------|---------------------------| +| `MAILER_ENABLED` | Enable Joplin mailer | `false` | +| `MAILER_HOST` | Mailer hostname | | +| `MAILER_PORT` | Mailer port | `465` | +| `MAILER_SECURITY` | Mailer security protocol | `MailerSecurity.Tls` | +| `MAILER_AUTH_USER` | Mailer user | | +| `MAILER_AUTH_PASSWORD` | Mailer password | | +| `MAILER_NOREPLY_NAME` | No reply email name | | +| `MAILER_NOREPLY_EMAIL` | No reply email address | | +| `RCLONE_REMOTE_NAME` | Name of the remote you chose during rclone config | | +| `RCLONE_REMOTE_DIR` | Name of the rclone remote dir, eg: S3 bucket name, folder name, etc | | +| `CRON` | How often to run the backup | `@daily` backup every day | +| `TIMEZONE` | Timezone, used for cron times | `America/New_York` | +| `ZIP_PASSWORD` | Password to protect the backup archive with | `123456` | +| `BACKUP_KEEP_DAYS` | How long to keep the backup in the destination | `31` days | + +You can test your backup manually with: + +```shell +docker compose run --rm -it joplin-backup backup +``` diff --git a/joplin/backup.env.example b/joplin/backup.env.example new file mode 100644 index 0000000..d32fc9d --- /dev/null +++ b/joplin/backup.env.example @@ -0,0 +1,6 @@ +RCLONE_REMOTE_NAME= +RCLONE_REMOTE_DIR= +CRON=@daily +TIMEZONE=America/New_York +ZIP_PASSWORD=123456 +BACKUP_KEEP_DAYS=31 diff --git a/tandoor/backup/.gitkeep b/joplin/database/.gitkeep similarity index 100% rename from tandoor/backup/.gitkeep rename to joplin/database/.gitkeep diff --git a/joplin/docker-compose.yml b/joplin/docker-compose.yml new file mode 100644 index 0000000..68ab008 --- /dev/null +++ b/joplin/docker-compose.yml @@ -0,0 +1,55 @@ +services: + joplin: + image: joplin/server:latest + user: root # Not pretty, but non-root breaks volumes: https://github.com/laurent22/joplin/issues/9489 + container_name: joplin + restart: always + environment: + - APP_PORT=22300 + - APP_BASE_URL=https://${HOSTNAME}/joplin + - HOSTNAME=${HOSTNAME} + - DB_CLIENT=sqlite3 + - SQLITE_DATABASE=/database/joplin.db + - STORAGE_DRIVER=Type=Filesystem; Path=/storage + volumes: + - ./joplin/database:/database + - ./joplin/storage:/storage + - ./joplin/healthcheck:/healthcheck + healthcheck: + test: ["CMD", "node", "/healthcheck/healthcheck.js"] + interval: 5s + retries: 10 + labels: + - traefik.enable=true + - traefik.http.routers.joplin.rule=(Host(`${HOSTNAME}`) && PathPrefix(`/joplin`)) + - traefik.http.routers.joplin.tls=true + - traefik.http.routers.joplin.tls.certresolver=myresolver + - traefik.http.routers.joplin.middlewares=joplin-stripprefix + - traefik.http.middlewares.joplin-stripprefix.stripPrefix.prefixes=/joplin + - traefik.http.services.joplin.loadbalancer.server.port=22300 + - homepage.group=Apps + - homepage.name=joplin + - homepage.icon=joplin.png + - homepage.href=/joplin + - homepage.description=Note-taking application + - homepage.weight=2 + profiles: + - joplin + + joplin-backup: + image: adrienpoupa/rclone-backup:latest + container_name: joplin-backup + restart: always + env_file: + - ./joplin/backup.env + environment: + - BACKUP_FOLDER_NAME=storage + - BACKUP_FOLDER_PATH=/storage + - DB_TYPE=sqlite + - SQLITE_DATABASE=/database/joplin.db + volumes: + - ./joplin/database:/database + - ./joplin/storage:/storage + - ./joplin/backup:/config + profiles: + - joplin \ No newline at end of file diff --git a/joplin/healthcheck/healthcheck.js b/joplin/healthcheck/healthcheck.js new file mode 100644 index 0000000..5194c18 --- /dev/null +++ b/joplin/healthcheck/healthcheck.js @@ -0,0 +1,28 @@ +// Inspired by: https://anthonymineo.com/docker-healthcheck-for-your-node-js-app/ +const http = require('http'); +const options = { + host: '127.0.0.1', + port: 22300, + timeout: 2000, + path: '/api/ping', + headers: { + 'Host': process.env.HOSTNAME, + } +}; + +const healthCheck = http.request(options, (res) => { + console.log(`HEALTHCHECK STATUS: ${res.statusCode}`); + if (res.statusCode === 200) { + process.exit(0); + } + else { + process.exit(1); + } +}); + +healthCheck.on('error', function (err) { + console.error('ERROR:' + err); + process.exit(1); +}); + +healthCheck.end(); diff --git a/tandoor/README.md b/tandoor/README.md index 7c325a2..d1dfdc8 100644 --- a/tandoor/README.md +++ b/tandoor/README.md @@ -1,6 +1,6 @@ # Tandoor -Tandoor is a recipe manager that allows you to manage your ever growing collection of digital recipes. +[Tandoor](https://tandoor.dev/) is a recipe manager that allows you to manage your ever growing collection of digital recipes. ## Installation diff --git a/tandoor/database/.gitkeep b/tandoor/database/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/tandoor/mediafiles/.gitkeep b/tandoor/mediafiles/.gitkeep deleted file mode 100755 index e69de29..0000000