이 프로젝트의 목표는 Mac을 전원 장애 복구 기능을 포함한 서버로 구성하고, Cloudflare를 사용하여 호스팅된 앱에 대한 공용 액세스를 제공하며, SSH를 통한 원격 접속을 가능하게 하고, 여러 웹 애플리케이션 호스팅을 단순화하며 코드 배포를 자동화하는 것이었습니다. 필자는 개인 프로젝트의 특성을 고려하여 최대한 단순한 구성을 지향했습니다. Kubernetes와 같은 복잡한 솔루션 대신 Docker를 중심으로 한 최소한의 자동화 스크립트를 사용했으며, SSH, DNS, Docker에 대한 기본적인 이해를 전제로 합니다.
장비 구성: Mac Mini는 고성능 멀티 코어 CPU와 충분한 디스크 용량을 제공하며, 메모리가 주요 제한 요소입니다. 필자는 24GB RAM 모델을 사용하지만, 16GB에서 64GB까지 다양하며, Mac Studio는 512GB까지 지원합니다. 통합 메모리는 LLM(대규모 언어 모델) 자체 호스팅에 유리합니다. 필자의 전체 설정(Ghost, 두 개의 Rails 앱, PostgreSQL, Chroma, MySQL, Clickhouse 기반의 Plausible Analytics)은 약 8GB 메모리와 1개의 CPU 코어를 사용합니다. LLM의 경우, Mistral-7B나 Llama 3 8B와 같은 GPT-3.5 스타일 모델은 4비트 양자화 형태로 6GB 메모리, Llama 3 70B와 같은 GPT-4 스타일 모델은 4비트 양자화 형태로 60GB 메모리를 필요로 합니다.
기본 컴퓨터 설정: Mac에 모니터를 연결하여 사용자 계정 생성, 재부팅 후 앱이 계속 실행되도록 ‘자동 로그인’ 활성화, 전원 장애 후 자동 재시작을 위한 ‘전원 공급 중단 시 자동으로 시동’ 활성화, 일정 시간 비활성 후 화면 잠금 설정을 진행합니다. 이후 Brew, asdf, Git을 설치하고 GitHub 인증을 설정합니다. Toolbox 저장소를 포크하고 클론한 뒤, ‘사용자 및 그룹 → 로그인 항목’에 lock_screen_on_login.app
스크립트를 추가하여 자동 로그인 시에도 화면 잠금을 유지하도록 합니다.
Cloudflare 설정: Cloudflare는 DNS 및 터널 역할을 하며, 무료 티어를 활용합니다. Cloudflare Tunnel은 Mac과 Cloudflare를 안전한 터널로 연결하여 인터넷 트래픽을 특정 포트로 전달하고, 수신 요청을 제한하여 보안을 강화합니다. Cloudflare Access를 통해 특정 서비스에 대한 권한 있는 접근을 제한할 수 있습니다. Cloudflare Tunnel 설정 가이드를 참고하여 config.yml
파일을 구성하고, 터널을 Mac에서 실행하며 공용 DNS를 터널로 라우팅합니다. 이를 통해 Cloudflare Access를 통한 SSH 접근도 가능해집니다.
1Password 및 Heartbeat 스크립트: 모든 서버 비밀은 1Password의 전용 Vault에 저장하고, 1Password CLI 및 서비스 계정 토큰을 통해 접근합니다. Toolbox는 매분 실행되는 heartbeat.sh
스크립트에 의존하며, 이는 .plist
파일을 통해 설치됩니다. ruby install_launch_agent.rb
를 실행하여 .plist
파일을 생성하고 1Password Vault ID를 삽입한 뒤 로드합니다.
웹 앱 설정: tail -f ~/code/toolbox/*.log
명령어로 heartbeat 스크립트의 실행을 확인한 후 앱을 추가할 수 있습니다. 서비스는 Docker Hub 이미지나 Dockerfile이 포함된 Git 저장소에서 가져올 수 있습니다. Git 저장소의 업데이트는 푸시 시 트리거되며, Docker 이미지는 일관성을 위해 고정된 버전 태그를 사용합니다. 각 Docker 서비스는 로컬 포트를 노출하고, config.yml
에서 해당 포트와 공용 호스트를 매핑합니다. DNS가 업데이트되면 트래픽이 흐릅니다.
마무리 및 데이터 마이그레이션: config.rb
파일에는 UptimeRobot 통합을 통한 heartbeat 스크립트 모니터링 및 Papertrail을 통한 원격 로그 보기와 같은 선택적 기능이 포함되어 있습니다. 데이터 마이그레이션 시에는 Postico를 사용하여 데이터베이스를 관리하고, pgsync --defer-constraints
플래그를 사용하여 테이블을 복사하는 것이 유용합니다. 재해 복구를 위해 Time Machine을 통한 외부 하드 드라이브 백업을 사용하며, 화재나 도난에 대비하여 데이터베이스를 iCloud나 S3에 주기적으로 백업할 계획입니다.