히스토리

  • [2026-04-06 Mon 10:53] @junghan — openglg-config라고 부를거야. 공개했는데 이거 근데 왜 봇로그 메타노트가 없지? GitHub - junghan0611/openglg-config: A openglg-config for your digital garden…
  • [2026-04-05 Sun 11:16] @junghan — W님이랑 이제 이야기 할거야.
  • [2026-04-05 Sun 11:14] 생성 — 스타벅스 공덕역에서 W님과 대면. Oracle 프리티어 Ubuntu 셀프호스팅 구성 시작.

배경

  • W님: PKM 옵시디언 사용자. 마크다운 볼트 보유. 노트 다수.
  • 수년간 정한님과 책/지식관리 이야기를 나눈 동료.
  • Oracle Cloud 프리티어로 Ubuntu 인스턴스 생성 예정.
  • 정한님 공개키를 등록하여 세팅/관리 대행.
  • OpenClaw(AI 에이전트) Docker 방식 설치 관심.

아키텍처 개요

Docker Compose 4~5개 파일이면 끝. Caddy가 HTTPS를 알아서 해결하고, 각 서비스는 독립 컨테이너. 옵시디언 사용자라면 Quartz가 가장 자연스러운 퍼블리싱 경로.

┌─── Oracle Cloud Free Tier (ARM Ampere A1) ────────────────┐
│  Ubuntu 22.04 / Docker + Docker Compose                    │
│                                                            │
│  Caddy (자동 HTTPS, Let's Encrypt)  ← :80/:443            │
│    ├─ garden.example.com  → Quartz (정적 사이트)           │
│    ├─ comments.example.com → Remark42 (댓글)               │
│    ├─ analytics.example.com → Umami (방문자 분석)          │
│    └─ (SSH 터널 전용) → OpenClaw (AI 에이전트)             │
│                                                            │
│  Docker 네트워크: proxy (Caddy ↔ 서비스 연결)              │
└────────────────────────────────────────────────────────────┘

힣의 Oracle(NixOS)과 대조

항목힣 (정한님)W님
OSNixOS (aarch64)Ubuntu 22.04 (aarch64)
PKMOrg-mode / Denote 3,300+ 노트Obsidian 마크다운 볼트
퍼블리싱Geworfen (Clojure 커스텀) + HugoQuartz (Obsidian 네이티브)
댓글Remark42Remark42
분석UmamiUmami
AI 에이전트OpenClaw (Docker)OpenClaw (Docker)
리버스 프록시Caddy (자동 HTTPS)Caddy (자동 HTTPS)
관리직접정한님 SSH 대행

1단계: Oracle 프리티어 + Ubuntu + Docker

1.1 인스턴스 생성

  • Oracle Cloud 가입 (무료, 신용카드 등록 필요하나 과금 없음)
  • Compute → Create Instance
    • Shape: VM.Standard.A1.Flex (ARM Ampere)
    • 프리티어 한도: 최대 4 OCPU / 24GB RAM / 200GB 스토리지
    • 추천: 2 OCPU / 12GB RAM (여유 있게)
    • OS: Ubuntu 22.04 (Canonical)
  • SSH 키 등록 (본인 키 + 정한님 공개키)

1.2 SSH 접근 + 기본 보안

# 로컬에서 접속
ssh ubuntu@<인스턴스-공개IP>
 
# 정한님 공개키 추가
echo "ssh-ed25519 AAAA... junghan@thinkpad" >> ~/.ssh/authorized_keys
 
# 기본 패키지 업데이트
sudo apt update && sudo apt upgrade -y
 
# 방화벽 (iptables — Oracle Ubuntu 기본)
sudo iptables -I INPUT 6 -m state --state NEW -p tcp --dport 80 -j ACCEPT
sudo iptables -I INPUT 7 -m state --state NEW -p tcp --dport 443 -j ACCEPT
sudo netfilter-persistent save

Oracle Cloud 보안 규칙도 별도 설정 필요! VCN → Subnet → Security List → Ingress Rules에서 80, 443 포트 열기.

1.3 Docker + Docker Compose 설치

# Docker 공식 설치
curl -fsSL https://get.docker.com | sudo sh
sudo usermod -aG docker $USER
newgrp docker
 
# Compose 확인 (Docker 25+ 에는 내장)
docker compose version
 
# 작업 디렉토리 생성
mkdir -p ~/docker/{caddy,quartz,remark42,umami,openclaw}

1.4 도메인 연결

  • 도메인 구매 또는 기존 도메인 사용
  • DNS 레코드 (Cloudflare 등):
    • garden.example.com → A 레코드 → 인스턴스 공개 IP
    • comments.example.com → A 레코드 → 동일 IP
    • analytics.example.com → A 레코드 → 동일 IP
  • 와일드카드 *.example.com 도 가능

2단계: Caddy (리버스 프록시 + 자동 HTTPS)

2.1 Docker 네트워크 생성

docker network create proxy

2.2 docker-compose.yml

# ~/docker/caddy/docker-compose.yml
services:
  caddy:
    image: caddy:2-alpine
    container_name: caddy
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config
    networks:
      - proxy
 
volumes:
  caddy_data:
  caddy_config:
 
networks:
  proxy:
    external: true

2.3 Caddyfile

# ~/docker/caddy/Caddyfile
 
# Quartz 디지털 가든
garden.example.com {
    root * /srv/quartz
    file_server
}
 
# Remark42 댓글
comments.example.com {
    reverse_proxy remark42:8080
}
 
# Umami 분석
analytics.example.com {
    reverse_proxy umami:3000
}
cd ~/docker/caddy && docker compose up -d

3단계: Quartz (Obsidian → 디지털 가든)

3.1 개요

  • Quartz: Obsidian 마크다운을 정적 사이트로 변환
  • 공식: https://quartz.jzhao.xyz
  • Obsidian 볼트의 [[wikilink]] , 태그, 그래프 뷰 지원
  • 빌드 결과물(HTML)을 Caddy가 서빙

3.2 서버에서 빌드하는 방식

# ~/docker/quartz/
# Node.js 필요 — Docker로 빌드
git clone https://github.com/jackyzha0/quartz.git ~/docker/quartz/quartz
cd ~/docker/quartz/quartz
npm i
 
# Obsidian 볼트를 content/ 에 심링크 또는 복사
ln -s ~/vault ~/docker/quartz/quartz/content
 
# 빌드
npx quartz build --output ~/docker/quartz/public
 
# Caddy에 마운트 (Caddyfile에서 /srv/quartz → 이 경로)
# caddy docker-compose.yml 에 볼륨 추가:
#   - ~/docker/quartz/public:/srv/quartz:ro

3.3 자동 배포 옵션

  • (A) GitHub Actions: vault 리포 push → Quartz 빌드 → scp/rsync → 서버
  • (B) 서버 cron: git pull && npx quartz build 매시간
  • (C) 수동: 변경 시 SSH 접속하여 빌드

W님 볼트 구조 확인 후 Quartz 설정 커스터마이징

4단계: Remark42 (댓글 시스템)

4.1 docker-compose.yml

# ~/docker/remark42/docker-compose.yml
services:
  remark42:
    image: ghcr.io/umputun/remark42:latest
    container_name: remark42
    restart: unless-stopped
    environment:
      - REMARK_URL=https://comments.example.com
      - SITE=garden
      - SECRET=<랜덤-시크릿-생성>
      - AUTH_GITHUB_CID=<GitHub-OAuth-Client-ID>
      - AUTH_GITHUB_CSEC=<GitHub-OAuth-Client-Secret>
      - AUTH_GOOGLE_CID=<Google-OAuth-Client-ID>
      - AUTH_GOOGLE_CSEC=<Google-OAuth-Client-Secret>
    volumes:
      - remark42_data:/srv/var
    networks:
      - proxy
 
volumes:
  remark42_data:
 
networks:
  proxy:
    external: true

4.2 Quartz에 Remark42 임베드

<!-- quartz layout 커스터마이징에 추가 -->
<div id="remark42"></div>
<script>
  var remark_config = {
    host: 'https://comments.example.com',
    site_id: 'garden',
  }
</script>
<script>
  !function(e,n){for(var o=0;o<e.length;o++){
    var r=n.createElement("script");
    r.src=remark_config.host+"/web/"+e[o]+".js";
    r.defer=!0;(n.head||n.body).appendChild(r)
  }}(remark_config.components||["embed"],document);
</script>

5단계: Umami (방문자 분석)

5.1 docker-compose.yml

# ~/docker/umami/docker-compose.yml
services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    container_name: umami
    restart: unless-stopped
    environment:
      DATABASE_URL: postgresql://umami:umami@umami-db:5432/umami
      DATABASE_TYPE: postgresql
      APP_SECRET: <랜덤-시크릿>
    depends_on:
      umami-db:
        condition: service_healthy
    networks:
      - proxy
      - umami-internal
 
  umami-db:
    image: postgres:16-alpine
    container_name: umami-db
    restart: unless-stopped
    environment:
      POSTGRES_DB: umami
      POSTGRES_USER: umami
      POSTGRES_PASSWORD: umami
    volumes:
      - umami_db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U umami"]
      interval: 5s
      timeout: 5s
      retries: 5
    networks:
      - umami-internal
 
volumes:
  umami_db:
 
networks:
  proxy:
    external: true
  umami-internal:

5.2 초기 설정

  • https://analytics.example.com 접속
  • 기본 로그인: admin / umami → 즉시 비밀번호 변경
  • 웹사이트 추가 → tracking 스크립트 → Quartz에 삽입

6단계: OpenClaw (AI 에이전트)

6.1 개요

  • OpenClaw: 오픈소스 AI 에이전트 게이트웨이
  • 텔레그램/웹 인터페이스로 AI와 대화
  • 로컬 파일(Obsidian 볼트)을 참조하여 답변
  • SSH 터널 전용 (외부 노출 안 함)

6.2 docker-compose.yml (기본형)

# ~/docker/openclaw/docker-compose.yml
services:
  openclaw-gateway:
    image: node:22-slim
    container_name: openclaw-gateway
    restart: unless-stopped
    ports:
      - "127.0.0.1:18789:18789"
    env_file: .env
    environment:
      - HOME=/home/node
    volumes:
      # Obsidian 볼트 (read-only)
      - ~/vault:/home/node/vault:ro
    networks:
      - proxy
 
networks:
  proxy:
    external: true

OpenClaw 설치는 정한님이 SSH 접속 후 직접 세팅. Docker 이미지 빌드 + 설정 파일(.env, config) + API 키 등록 필요. Obsidian 볼트를 read-only로 마운트하여 AI가 노트를 참조하게 함.

OpenClaw 정식 설치 — 정한님 SSH 접속 후 진행

운영 가이드

서비스 관리 명령어

# 전체 상태 확인
docker ps
 
# 개별 서비스 재시작
cd ~/docker/caddy && docker compose restart
cd ~/docker/remark42 && docker compose restart
cd ~/docker/umami && docker compose restart
 
# 로그 확인
docker logs caddy --tail 50
docker logs remark42 --tail 50
 
# 디스크 확인
df -h /
docker system df

백업

# Remark42 데이터
docker run --rm -v remark42_data:/data -v ~/backup:/backup \
  alpine tar czf /backup/remark42-$(date +%Y%m%d).tar.gz /data
 
# Umami DB
docker exec umami-db pg_dump -U umami umami > ~/backup/umami-$(date +%Y%m%d).sql
 
# Obsidian 볼트는 Git으로 관리 권장

디스크 관리 (프리티어 주의사항)

Oracle 프리티어는 200GB 제한. Docker 이미지/로그가 쌓이면 금방 찬다. docker system prune 정기 실행 권장.

Q&A 로그

도메인 보유 여부 확인

Obsidian 볼트 구조/규모 확인

GitHub/Google OAuth 설정 가능 여부

Quartz 테마/커스터마이징 취향

관련 노트