From 10140fabba12b8b1a279d9f6b78b15494a9a0f59 Mon Sep 17 00:00:00 2001 From: Kevin Heyer Date: Sun, 23 Mar 2025 20:13:11 +0000 Subject: [PATCH 1/4] Add Solidtime container --- solidtime/.env-example | 5 ++ solidtime/docker-compose.yml | 109 ++++++++++++++++++++++++++++++++++ solidtime/laravel.env.example | 44 ++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 solidtime/.env-example create mode 100644 solidtime/docker-compose.yml create mode 100644 solidtime/laravel.env.example diff --git a/solidtime/.env-example b/solidtime/.env-example new file mode 100644 index 0000000..3d8cc1b --- /dev/null +++ b/solidtime/.env-example @@ -0,0 +1,5 @@ +SOLIDTIME_VERSION=latest +SOLIDTIME_DOMAIN=solidtime.example.com +SOLIDTIME_POSTGRES_DATABASE=solidtime +SOLIDTIME_POSTGRES_USERNAME=solidtime +SOLIDTIME_POSTGRES_PASSWORD=randompassword \ No newline at end of file diff --git a/solidtime/docker-compose.yml b/solidtime/docker-compose.yml new file mode 100644 index 0000000..35a3eae --- /dev/null +++ b/solidtime/docker-compose.yml @@ -0,0 +1,109 @@ +services: + app: + image: "solidtime/solidtime:${SOLIDTIME_VERSION:-latest}" + container_name: solidtime + restart: always + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik" + - "traefik.http.routers.solidtime.entrypoints=http" + - "traefik.http.routers.solidtime.rule=Host(`${SOLIDTIME_DOMAIN:?error}`)" + - "traefik.http.middlewares.solidtime-https-redirect.redirectscheme.scheme=https" + - "traefik.http.routers.solidtime.middlewares=solidtime-https-redirect" + - "traefik.http.routers.solidtime-secure.entrypoints=https" + - "traefik.http.routers.solidtime-secure.rule=Host(`${SOLIDTIME_DOMAIN:?error}`)" + - "traefik.http.routers.solidtime-secure.tls=true" + - "traefik.http.routers.solidtime-secure.service=solidtime" + - "traefik.http.services.solidtime.loadbalancer.server.port=8000" + networks: + - traefik + - solidtime + volumes: + - "app-storage:/var/www/html/storage" + - "./data/logs:/var/www/html/storage/logs" + - "./data/app-storage:/var/www/html/storage/app" + environment: + CONTAINER_MODE: http + healthcheck: + test: [ "CMD-SHELL", "curl --fail http://localhost:8000/health-check/up || exit 1" ] + env_file: + - laravel.env + depends_on: + - database + + scheduler: + image: "solidtime/solidtime:${SOLIDTIME_VERSION:-latest}" + restart: always + networks: + - solidtime + volumes: + - "app-storage:/var/www/html/storage" + - "./data/logs:/var/www/html/storage/logs" + - "./data/app-storage:/var/www/html/storage/app" + environment: + CONTAINER_MODE: scheduler + healthcheck: + test: [ "CMD-SHELL", "supervisorctl status scheduler:scheduler_00" ] + env_file: + - laravel.env + depends_on: + - database + + queue: + restart: always + image: "solidtime/solidtime:${SOLIDTIME_VERSION:-latest}" + networks: + - solidtime + volumes: + - "app-storage:/var/www/html/storage" + - "./data/logs:/var/www/html/storage/logs" + - "./data/app-storage:/var/www/html/storage/app" + environment: + CONTAINER_MODE: worker + WORKER_COMMAND: "php /var/www/html/artisan queue:work" + healthcheck: + test: [ "CMD-SHELL", "supervisorctl status worker:worker_00" ] + env_file: + - laravel.env + depends_on: + - database + + database: + restart: always + image: 'postgres:${SOLIDTIME_POSTGRES_VERSION:-16}' + environment: + PGPASSWORD: '${SOLIDTIME_POSGRES_PASSWORD:?error}' + POSTGRES_DB: '${SOLIDTIME_POSTGRES_DATABASE:?error}' + POSTGRES_USER: '${SOLIDTIME_POSTGRES_USERNAME:?error}' + POSTGRES_PASSWORD: '${SOLIDTIME_POSTGRES_PASSWORD:?error}' + volumes: + - 'database-storage:/var/lib/postgresql/data' + networks: + - solidtime + healthcheck: + test: + - CMD + - pg_isready + - '-q' + - '-d' + - '${SOLIDTIME_POSTGRES_DATABASE}' + - '-U' + - '${SOLIDTIME_POSTGRES_USERNAME}' + retries: 3 + timeout: 5s + + gotenberg: + image: gotenberg/gotenberg:8 + networks: + - solidtime + healthcheck: + test: [ "CMD", "curl", "--silent", "--fail", "http://localhost:3000/health" ] + +networks: + traefik: + external: true + internal: + +volumes: + database-storage: + app-storage: \ No newline at end of file diff --git a/solidtime/laravel.env.example b/solidtime/laravel.env.example new file mode 100644 index 0000000..c133b6b --- /dev/null +++ b/solidtime/laravel.env.example @@ -0,0 +1,44 @@ +APP_ENV="production" +APP_DEBUG="false" +APP_URL="https://solidtime.example.com" +APP_FORCE_HTTPS="true" +TRUSTED_PROXIES="0.0.0.0/0,2000:0:0:0:0:0:0:0/3" + +# Authentication +APP_KEY="" +PASSPORT_PRIVATE_KEY="" +PASSPORT_PUBLIC_KEY="" +SUPER_ADMINS="" + +# Logging +LOG_CHANNEL="stderr_daily" +LOG_LEVEL="debug" + +# Database +DB_CONNECTION="pgsql" +DB_HOST="database" +DB_PORT="5432" +DB_SSLMODE="require" +DB_DATABASE="solidtime" +DB_USERNAME="solidtime" +DB_PASSWORD="randompassword" + +# Mail +MAIL_MAILER="smtp" +MAIL_HOST="" +MAIL_PORT="" +MAIL_ENCRYPTION="tls" +MAIL_FROM_ADDRESS="no-reply@solidtime.example.com" +MAIL_FROM_NAME="solidtime" +MAIL_USERNAME="" +MAIL_PASSWORD="" + +# Queue +QUEUE_CONNECTION="database" + +# File storage +FILESYSTEM_DISK="local" +PUBLIC_FILESYSTEM_DISK="public" + +# Services +GOTENBERG_URL="http://gotenberg:3000" \ No newline at end of file -- 2.45.3 From 4b0f042b9a9a5f44281677cb028171485789dcba Mon Sep 17 00:00:00 2001 From: Kevin Heyer Date: Sun, 23 Mar 2025 20:15:17 +0000 Subject: [PATCH 2/4] add Obsidian-Live-Sync container --- obisidian/.env-example | 9 +++++++++ obisidian/data/local.ini | 0 obisidian/docker-compose.yml | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+) create mode 100644 obisidian/.env-example create mode 100644 obisidian/data/local.ini create mode 100644 obisidian/docker-compose.yml diff --git a/obisidian/.env-example b/obisidian/.env-example new file mode 100644 index 0000000..c328495 --- /dev/null +++ b/obisidian/.env-example @@ -0,0 +1,9 @@ +# OBSIDIAN Version (Standard: latest) +OBSIDIAN_VERSION=latest + +# OBSIDIAN Domain +OBSIDIAN_DOMAIN=obsidian.example.com + +# OBSIDIAN CouchDB Config +OBSIDIAN_COUCHDB_USER=couchdb_user +OBSIDIAN_COUCHDB_PASSWORD=couchdb_password \ No newline at end of file diff --git a/obisidian/data/local.ini b/obisidian/data/local.ini new file mode 100644 index 0000000..e69de29 diff --git a/obisidian/docker-compose.yml b/obisidian/docker-compose.yml new file mode 100644 index 0000000..b0c0ce0 --- /dev/null +++ b/obisidian/docker-compose.yml @@ -0,0 +1,37 @@ +--- +services: + couchdb: + image: couchdb:${OBSIDIAN_COUCHDB_VERSION:-latest} + container_name: obsidian-livesync + environment: + - COUCHDB_USER=${OBSIDIAN_COUCHDB_USER:?error} + - COUCHDB_PASSWORD=${OBSIDIAN_COUCHDB_PASSWORD:?error} + volumes: + - couchdb-data:/opt/couchdb/data + - ./data/local.ini:/opt/couchdb/etc/local.ini + restart: unless-stopped + networks: + - traefik + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik" + - "traefik.http.routers.obsidian-livesync.rule=Host(`${OBSIDIAN_DOMAIN}`)" + - "traefik.http.routers.obsidian-livesync.entrypoints=websecure" + - "traefik.http.routers.obsidian-livesync.service=obsidian-livesync" + - "traefik.http.services.obsidian-livesync.loadbalancer.server.port=5984" + - "traefik.http.routers.obsidian-livesync.tls=true" + - "traefik.http.routers.obsidian-livesync.middlewares=obsidiancors" + # The part needed for CORS to work on Traefik 2.x starts here + - "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowmethods=GET,PUT,POST,HEAD,DELETE" + - "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowheaders=accept,authorization,content-type,origin,referer" + - "traefik.http.middlewares.obsidiancors.headers.accesscontrolalloworiginlist=app://obsidian.md,capacitor://localhost,http://localhost" + - "traefik.http.middlewares.obsidiancors.headers.accesscontrolmaxage=3600" + - "traefik.http.middlewares.obsidiancors.headers.addvaryheader=true" + - "traefik.http.middlewares.obsidiancors.headers.accessControlAllowCredentials=true" + +networks: + traefik: + external: true + +volumes: + couchdb-data: \ No newline at end of file -- 2.45.3 From 58579c67ab8749e93aea36b825a72d185ff53904 Mon Sep 17 00:00:00 2001 From: Kevin Heyer Date: Mon, 24 Mar 2025 20:13:52 +0000 Subject: [PATCH 3/4] Now its a productive version --- .../.env-example | 0 obisidian-livesync/README.md | 82 +++++++++++++++++++ obisidian-livesync/data/local.ini | 26 ++++++ .../docker-compose.yml | 13 +-- obisidian/data/local.ini | 0 5 files changed, 116 insertions(+), 5 deletions(-) rename {obisidian => obisidian-livesync}/.env-example (100%) create mode 100644 obisidian-livesync/README.md create mode 100644 obisidian-livesync/data/local.ini rename {obisidian => obisidian-livesync}/docker-compose.yml (73%) delete mode 100644 obisidian/data/local.ini diff --git a/obisidian/.env-example b/obisidian-livesync/.env-example similarity index 100% rename from obisidian/.env-example rename to obisidian-livesync/.env-example diff --git a/obisidian-livesync/README.md b/obisidian-livesync/README.md new file mode 100644 index 0000000..9f4a060 --- /dev/null +++ b/obisidian-livesync/README.md @@ -0,0 +1,82 @@ +# Obsidian LiveSync with CouchDB + +This configuration sets up a **CouchDB** container for **Obsidian LiveSync** with **Traefik** as a reverse proxy. + +## Prerequisites + +- Docker & Docker-Compose +- Traefik as a reverse proxy +- A configured `.env` file with the required environment variables + +## Environment Variables + +Copy `.env-example` to `.env` and adjust the values accordingly. + +## `local.ini` Configuration + +Modify the file `data/local.ini`: + +```ini +[admins] +admin = +``` + +## Starting the Container + +Run the following command to start the container: + +```sh +docker-compose up -d +``` + +## Testing the CouchDB Connection + +1. **Via Browser (Fauxton UI):** + + ``` + http://your.domain.com/_utils/ + ``` + +2. **Using cURL:** + + ```sh + curl -u ${OBSIDIAN_COUCHDB_USER}:${OBSIDIAN_COUCHDB_PASSWORD} http://your.domain.com:5984/ + ``` + +## Configuration of Endpoint Device using the LiveSync Plugin + +One final step is needed to complete the setup: configuring the LiveSync plugin on any Obsidian client that will be part of the data synchronization process. + +Installing the plugin inside Obsidian is simple: + +1. Go to the plugin section. +2. Search for the **Self-hosted LiveSync** plugin. +3. Install and enable the plugin. + +Once installed, the plugin needs to be configured. There is a quick wizard on the [GitHub page](https://github.com/vrtmrz/obsidian-livesync) of the plugin that describes the process in detail. + +### Configuring the Remote Database + +The most important step is setting up the **Remote Database configuration**. This is the actual Docker container, which should be accessible over an HTTP or HTTPS address, depending on the setup. + +![Remote Database Configuration](https://github.com/vrtmrz/obsidian-livesync/raw/main/images/quick_setup_3.png) + +As shown in the image above, the **URI** parameter should point to the CouchDB container. The example shows a local address and the default database port. If using a reverse proxy, replace this with an HTTPS URL. + +- **Username and Password**: These are the credentials defined in the `docker-compose` file. +- **Database Name**: This is a user-defined name. If the database does not exist, Obsidian will create one automatically. + +### Enabling End-to-End Encryption + +E2E encryption of the database is supported and recommended. Be sure to configure this for additional security. + +![Encryption Configuration](https://github.com/vrtmrz/obsidian-livesync/raw/main/images/quick_setup_4.png) + +### Finalizing the Setup + +This configuration must be repeated on all devices that will participate in synchronization. Any changes on one device will be automatically pushed to the CouchDB sync database and then forwarded to all other connected Obsidian clients. + +If everything is working correctly, a sync status icon should appear in the upper right corner of the Obsidian app. + +This setup provides a fast and stable self-hosted Obsidian sync solution. However, keep in mind that maintenance, plugin updates, and LiveSync Docker container updates are the responsibility of the end user. + diff --git a/obisidian-livesync/data/local.ini b/obisidian-livesync/data/local.ini new file mode 100644 index 0000000..6a0fd18 --- /dev/null +++ b/obisidian-livesync/data/local.ini @@ -0,0 +1,26 @@ +[couchdb] +single_node=true +max_document_size = 50000000 + +[chttpd] +require_valid_user = true +max_http_request_size = 4294967296 +enable_cors = true + +[chttpd_auth] +require_valid_user = true +authentication_redirect = /_utils/session.html + +[httpd] +WWW-Authenticate = Basic realm="couchdb" +bind_address = 0.0.0.0 + +[cors] +origins = app://obsidian.md, capacitor://localhost, http://localhost +credentials = true +headers = accept, authorization, content-type, origin, referer +methods = GET,PUT,POST,HEAD,DELETE +max_age = 3600 + +[admins] +admin = \ No newline at end of file diff --git a/obisidian/docker-compose.yml b/obisidian-livesync/docker-compose.yml similarity index 73% rename from obisidian/docker-compose.yml rename to obisidian-livesync/docker-compose.yml index b0c0ce0..33476c6 100644 --- a/obisidian/docker-compose.yml +++ b/obisidian-livesync/docker-compose.yml @@ -15,12 +15,15 @@ services: labels: - "traefik.enable=true" - "traefik.docker.network=traefik" - - "traefik.http.routers.obsidian-livesync.rule=Host(`${OBSIDIAN_DOMAIN}`)" - - "traefik.http.routers.obsidian-livesync.entrypoints=websecure" - - "traefik.http.routers.obsidian-livesync.service=obsidian-livesync" + - "traefik.http.routers.obsidian-livesync.entrypoints=http" + - "traefik.http.routers.obsidian-livesync.rule=Host(`${OBSIDIAN_DOMAIN:?error}`)" + - "traefik.http.middlewares.obsidian-livesync-https-redirect.redirectscheme.scheme=https" + - "traefik.http.routers.obsidian-livesync.middlewares=obsidian-livesync-https-redirect" + - "traefik.http.routers.obsidian-livesync-secure.entrypoints=https" + - "traefik.http.routers.obsidian-livesync-secure.rule=Host(`${OBSIDIAN_DOMAIN:?error}`)" + - "traefik.http.routers.obsidian-livesync-secure.tls=true" + - "traefik.http.routers.obsidian-livesync-secure.service=obsidian-livesync" - "traefik.http.services.obsidian-livesync.loadbalancer.server.port=5984" - - "traefik.http.routers.obsidian-livesync.tls=true" - - "traefik.http.routers.obsidian-livesync.middlewares=obsidiancors" # The part needed for CORS to work on Traefik 2.x starts here - "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowmethods=GET,PUT,POST,HEAD,DELETE" - "traefik.http.middlewares.obsidiancors.headers.accesscontrolallowheaders=accept,authorization,content-type,origin,referer" diff --git a/obisidian/data/local.ini b/obisidian/data/local.ini deleted file mode 100644 index e69de29..0000000 -- 2.45.3 From fee7afb7c632bbf8ec03c6fdf469305e7ecd6fff Mon Sep 17 00:00:00 2001 From: Kevin Heyer Date: Mon, 24 Mar 2025 20:14:01 +0000 Subject: [PATCH 4/4] add README.md --- obisidian-livesync/README.md | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/obisidian-livesync/README.md b/obisidian-livesync/README.md index 9f4a060..0ffa6b9 100644 --- a/obisidian-livesync/README.md +++ b/obisidian-livesync/README.md @@ -80,3 +80,47 @@ If everything is working correctly, a sync status icon should appear in the uppe This setup provides a fast and stable self-hosted Obsidian sync solution. However, keep in mind that maintenance, plugin updates, and LiveSync Docker container updates are the responsibility of the end user. +# Obsidian LiveSync with CouchDB + +This configuration sets up a **CouchDB** container for **Obsidian LiveSync** with **Traefik** as a reverse proxy. + +## Prerequisites + +- Docker & Docker-Compose +- Traefik as a reverse proxy +- A configured `.env` file with the required environment variables + +## Environment Variables + +Copy `.env-example` to `.env` and adjust the values accordingly. + +## `local.ini` Configuration + +Modify the file `data/local.ini`: + +```ini +[admins] +admin = +``` + +## Starting the Container + +Run the following command to start the container: + +```sh +docker-compose up -d +``` + +## Testing the CouchDB Connection + +1. **Via Browser (Fauxton UI):** + + ``` + http://your.domain.com/_utils/ + ``` + +2. **Using cURL:** + + ```sh + curl -u ${OBSIDIAN_COUCHDB_USER}:${OBSIDIAN_COUCHDB_PASSWORD} http://your.domain.com:5984/ + ``` \ No newline at end of file -- 2.45.3