히스토리
- @junghan — openglg-config라고 부를거야. 공개했는데 이거 근데 왜 봇로그 메타노트가 없지? GitHub - junghan0611/openglg-config: A openglg-config for your digital garden…
- @junghan — W님이랑 이제 이야기 할거야.
- 생성 — 스타벅스 공덕역에서 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님 |
|---|---|---|
| OS | NixOS (aarch64) | Ubuntu 22.04 (aarch64) |
| PKM | Org-mode / Denote 3,300+ 노트 | Obsidian 마크다운 볼트 |
| 퍼블리싱 | Geworfen (Clojure 커스텀) + Hugo | Quartz (Obsidian 네이티브) |
| 댓글 | Remark42 | Remark42 |
| 분석 | Umami | Umami |
| 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)
- Shape:
- 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 saveOracle 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 레코드 → 인스턴스 공개 IPcomments.example.com→ A 레코드 → 동일 IPanalytics.example.com→ A 레코드 → 동일 IP
- 와일드카드
*.example.com도 가능
2단계: Caddy (리버스 프록시 + 자동 HTTPS)
2.1 Docker 네트워크 생성
docker network create proxy2.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: true2.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 -d3단계: 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:ro3.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: true4.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: trueOpenClaw 설치는 정한님이 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 테마/커스터마이징 취향
관련 노트
- §entwurf 분신 에이전트 가이드 — 분신 운영 전체 맥락
- 힣봇군단 유료구독 정책 — OpenClaw 모델 정책 참고
Comments