fly.io
를 통해서 서버를 구성 및 배포를 하고, CouchDB(카우치 DB)
로 문서를 관리 하여 실시간으로 동기화를 진행한다. 자세한 설명은 다음 문서를 참고한다.
Obsidian Self-hosted LiveSync Plugin 사용을 위한 가이드 입니다. (github.com)
deploy_couchdb_to_flyio.ipynb - Colaboratory (google.com)
모든 플랜에 무료로 포함된 리소스:
예제에서는 구글 Colab을 사용하였지만 개발자 기준에서는 추후 관리나 편의성을 위해서는 로컬에서도 괜찮겠다 싶다.
https://fly.io/ 사이트를 통해 가입하고 해외 카드를 등록한다. ( 예제 사이트에 자세히 나와있다 )
curl -L https://fly.io/install.sh | sh
https://mertyn-obsidian.fly.dev/
vi ~/.zshrc
alias flyctl="/Users/liam/.fly/bin/flyctl"
flyctl auth signup
# Opening https://fly.io/app/auth/cli/00ae0884e7fd97f6a980f73d532eaff4
# Waiting for session... Done
# successfully logged in as ...
flyctl launch --auto-confirm --detach --no-deploy --name mertyn-obsidian --image couchdb:latest --region nrt
# Using image couchdb:latest
# Creating app in /content/fly
# We're about to launch your app on Fly.io. Here's what you're getting:
# Organization: 이준명 (fly launch defaults to the personal org)
# Name: mertyn-obsidian (specified on the command line)
# Region: Tokyo, Japan (specified on the command line)
# App Machines: shared-cpu-1x, 1GB RAM (most apps need about 1GB of RAM)
# Postgres: <none> (not requested)
# Redis: <none> (not requested)
# Created app 'mertyn-obsidian' in organization 'personal'
# Admin URL: [https://fly.io/apps/mertyn-obsidian](https://fly.io/apps/mertyn-obsidian)
# Hostname: mertyn-obsidian.fly.dev
# Wrote config file fly.toml
# Validating /content/fly/fly.toml
# ✓ Configuration is valid
# Your app is ready! Deploy with `flyctl deploy`
Colab 예제를 보면 서버 생성시
--generate-name
옵션을 사용한다. 자동으로 서버 이름을 생성하는데 진행시Error: Validation failed: Name has already been taken
가 발생한다. 이에 따라 직접 중복되지 않는 이름을 지정할 수 있도록--name
으로 사용하도록 변경하였다.
flyctl volumes create --region nrt couchdata --size 2 --yes
# ID: vol_p4mo0qq333nqx6dv
# Name: couchdata
# App: mertyn-obsidian
# Region: nrt
# Zone: fe01
# Size GB: 2
# Encrypted: true
# Created at: 14 Feb 24 00:20 UTC
# Snapshot retention: 5
cat fly.toml
# app = 'mertyn-obsidian'
# primary_region = 'nrt'
# [build]
# image = 'couchdb:latest'
# [http_service]
# internal_port = 8080
# force_https = true
# auto_stop_machines = true
# auto_start_machines = true
# min_machines_running = 0
# processes = ['app']
# [[vm]]
# cpu_kind = 'shared'
# cpus = 1
# memory_mb = 1024
# Modify fly.toml
cat ./fly.toml | grep -iv "\[env\]" | sed -e 's/8080/5984/g' | sed -e 's/_machines = true/_machines = false/g'> fly.tmp
cat fly.tmp > ./fly.toml
echo -e "\n[env]\n COUCHDB_USER = \"${couchUser}\"\n[mounts]\n source=\"couchdata\"\n destination=\"/opt/couchdb/data\"" >> ./fly.toml
# app = 'mertyn-obsidian'
# primary_region = 'nrt'
# [build]
# image = 'couchdb:latest'
# [http_service]
# internal_port = 5984
# force_https = true
# auto_stop_machines = false
# auto_start_machines = false
# min_machines_running = 0
# processes = ['app']
# [[vm]]
# cpu_kind = 'shared'
# cpus = 1
# memory_mb = 1024
# [env]
# COUCHDB_USER = "..."
# [mounts]
# source="couchdata"
# destination="/opt/couchdb/data"
flyctl secrets set COUCHDB_PASSWORD=${couchPwd}
# Secrets are staged for the first deployment
flyctl deploy --detach --remote-only
flyctl status
# ==> Verifying app config
# Validating /content/fly/fly.toml
# ✓ Configuration is valid
# --> Verified app config
# ==> Building image
# Searching for image 'couchdb:latest' remotely...
# image found: img_589kp9e8el94oj2e
# Watch your deployment at https://fly.io/apps/mertyn-obsidian/monitoring
# Provisioning ips for mertyn-obsidian
# Dedicated ipv6: 2a09:8280:1::2a:a53d:0
# Shared ipv4: 66.241.125.8
# Add a dedicated ipv4 with: fly ips allocate-v4
# This deployment will:
# * create 1 "app" machine
# No machines in group app, launching a new machine
# Finished launching new machines
# -------
# Checking DNS configuration for mertyn-obsidian.fly.dev
# Visit your newly deployed app at https://mertyn-obsidian.fly.dev/
# App
# Name = mertyn-obsidian
# Owner = personal
# Hostname = mertyn-obsidian.fly.dev
# Image = library/couchdb:latest
# Machines
# PROCESS ID VERSION REGION STATE ROLE CHECKS LAST UPDATED
# app 6e82d339f521d8 1 nrt created 2024-02-14T00:23:53Z
curl -X POST "${couchHost}/_cluster_setup" -H "Content-Type: application/json" -d "{\"action\":\"enable_single_node\",\"username\":\"${couchUser}\",\"password\":\"${couchPwd}\",\"bind_address\":\"0.0.0.0\",\"port\":5984,\"singlenode\":true}" --user "${couchUser}:${couchPwd}"
# {"ok":true}
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/chttpd/require_valid_user" -H "Content-Type: application/json" -d '"true"' --user "${couchUser}:${couchPwd}"
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/chttpd_auth/require_valid_user" -H "Content-Type: application/json" -d '"true"' --user "${couchUser}:${couchPwd}"
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/httpd/WWW-Authenticate" -H "Content-Type: application/json" -d '"Basic realm=\"couchdb\""' --user "${couchUser}:${couchPwd}"
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/httpd/enable_cors" -H "Content-Type: application/json" -d '"true"' --user "${couchUser}:${couchPwd}"
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/chttpd/enable_cors" -H "Content-Type: application/json" -d '"true"' --user "${couchUser}:${couchPwd}"
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/chttpd/max_http_request_size" -H "Content-Type: application/json" -d '"4294967296"' --user "${couchUser}:${couchPwd}"
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/couchdb/max_document_size" -H "Content-Type: application/json" -d '"50000000"' --user "${couchUser}:${couchPwd}"
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/cors/credentials" -H "Content-Type: application/json" -d '"true"' --user "${couchUser}:${couchPwd}"
curl -X PUT "${couchHost}/_node/nonode@nohost/_config/cors/origins" -H "Content-Type: application/json" -d '"app://obsidian.md,capacitor://localhost,http://localhost"' --user "${couchUser}:${couchPwd}"
==Application list 확인==
flyctl app list
# NAME OWNER STATUS LATEST DEPLOY
# mertyn-obsidian personal deployed 5h34m ago
==Application 삭제==
flyctl apps destroy [name] -y
# Destroyed app [name]
생성된 URL을 통해 접속을 하면 UI가 보이지 않는다. 이때 다음의 주소로 접속하여 ID/PASS 를 입력한다.
https://mertyn-obsidian.fly.dev/_utils
==접속화면==
==업데이트된 데이터==
이후 스텝은 예제의 내용을 그대로 따라한다. 하단은 필요부분을 복사-붙여넣기 한 부분이다.
self-hosted livesync 링크를 눌러 옵시디언에서 플러그인 설치화면으로 갑니다.
Install
버튼을 눌러 설치합니다.
Enable
버튼을 눌러 플러그인을 활성화 합니다.
Ctrl
+ P
를 눌러 설정에 들어간 후에, Self-hosted LiveSync
설정을 누릅니다. 상단에 🛰️ 탭을 누릅니다. 그리고 이전에 Colab을 통해 설치한 CouchDB의 접속 정보를 입력합니다.
/
로 끝나지 않게 작성해주세요.이제 플러그인에서 DB에 잘 접속되는지 확인을 해봐야 합니다. Check database configuration
의 Check
을 눌러봅니다. 대부분은 Fix
버튼이 나오는 것을 확인할 수 있습니다. Fix
버튼을 모두 눌러줍니다.
!!! 주의 !!! 다음 동기화 이전에 vault를 꼭 백업해주세요.
이제 처음 동기화를 위해 Rebuild everything
의 Rebuild
버튼을 누릅니다. 시간이 조금 걸릴 수 있습니다.
동기화가 완료되었으면, 이제 라이브 싱크 설정을 합니다. 사실 라이브 싱크를 사용하지 않고 주기적으로 동기화를 하는 등의 옵션이 있습니다만, 이 플러그인을 사용하는 주 목적은 라이브 싱크입니다. 🔧 탭을 누르고 아래 설정을 해줍니다.
한번 설정하면 Presets의 항목이 다시 비어버리는 경우가 있는데, 이건 버그인 것 같습니다.
확인을 위해서는 🔁 탭에 들어가신 후, LiveSync가 활성화 되어 있는지 확인합니다.
이제 다른 기기에서 obsidian을 실행하고 self-hosted livesync를 설치해주세요. 그리고 위에서 설정했던 것 처럼, CouchDB 설정을 해줍니다. 여기서는 절대 Rebuild 같은 것을 하지 않을 겁니다. CouchDB 설정만 합니다. 마찬가지로 DB에 접속이 되는지 확인하기 위해 Check database configuration
의 Check
을 눌러봅니다.
📦 탭을 누르고 Fetch rebuilt DB
의 Fetch
버튼을 누릅니다. Fetch 하는데 시간이 조금 걸리지만, 바로 LiveSync 설정을 해봅니다.
🔧 탭을 누르고 아래 설정을 해줍니다.
이제 라이브 싱크가 제대로 되는지 확인해봅니다.
위에서 Show status inside editor
를 활성화를 같이 했는데요. 이럴경우 에디터 우측 상단에 다음과 같은 상태를 확인할 수 있습니다.
처음에 밀린 동기화를 하게 되면 ⚡️ 상태입니다. 보통은 💤 상태에서 ⏳ 와 ↑, ↓ 이 발생합니다.