Heroku처럼 쓰되, 내 것으로 직접 운영한다.
VPS에 먼저 Dokku를 설치해야 한다. 앞서 언급했듯이 나는 OVH를 사용한다.
애플리케이션을 배포하는 가장 간편한 방법 중 하나는 Docker 컨테이너를 이용하는 것이다.
Docker 컨테이너로 배포하려면 git 저장소 루트에 다음과 같이 Dockerfile을 넣으면 된다:
Dockerfile
Dokku 호스트에서 앱을 생성한다:
로컬에서는 Dokku 호스트에 대한 접근을 설정하고, ~/.ssh/config 파일에 dokku라는 이름으로 등록한다. 내 경우를 예로 들면:
Host dokku
HostName <The external IP address of your Dokku host>
User ubuntu
IdentityFile /Users/hamel/.ssh/dokku
로컬에서 Dokku 호스트를 리모트로 추가하고 푸시한다:
이게 전부다 — 이제 앱이 Dokku 호스트에서 실행 중일 것이다! 로컬 로그에 애플리케이션이 서비스되는 URL이 출력되며, 기본값은 myapp.yourdomain.com이다. 다음 명령어로 스케일을 조정할 수도 있다:
여기서는 기본적인 내용만 다뤘다. 더 자세한 내용은 Dokku 공식 문서를 참고하자.
GitHub Pages는 비공개 정적 사이트를 배포하려면 비싼 Enterprise 계정이 필요해 불편하다. Dokku를 쓰면 비공개 GitHub 저장소에서 정적 사이트를 손쉽게 배포하고 비밀번호 보호까지 걸 수 있다.
이 예제에서는 _site 폴더에 정적 사이트가 git 저장소 형태로 있다고 가정한다.
Dokku 호스트에서 mysite라는 이름의 앱을 생성하고, NGINX_ROOT 환경 변수를 _site으로 설정한다:
마찬가지로 Dokku 호스트에서 basic auth를 설치하고, 플러그인이 정상 동작할 수 있도록 권한을 설정한다.
이제 정적 사이트가 담긴 git 저장소 루트에서 다음 명령어들을 실행한다:
dokku에게 이것이 정적 사이트임을 알린다
2
dokku에게 정적 사이트용 nginx 빌드팩을 사용하도록 지정한다(보통은 자동으로 감지되지만, 코드와 정적 사이트가 함께 있는 프로젝트라면 혼동을 방지하기 위해 명시적으로 nginx 빌드팩을 지정해야 한다).
3
dokku 호스트를 리모트로 추가한다. 이 과정이 동작하려면 이전 섹션에서 설명한 대로 dokku이 ~/.ssh/config 파일에 호스트명으로 등록되어 있어야 한다.
마지막으로 애플리케이션을 배포한다:
Dokku 호스트에서 다음 명령어를 실행하면 인증을 추가할 수 있다:
사용자 이름과 비밀번호를 여러 개 추가하거나 특정 IP를 필터링하는 것도 가능하다. 공식 문서를 참고하자.
사이트에 HTTPS를 적용하고 싶은 경우가 많은데, Dokku에서는 Let's Encrypt 플러그인을 통해 간단하게 설정할 수 있고 자동 갱신까지 지원한다. 나는 이 플러그인을 쓰지 않는데, Cloudflare 프록시를 통해 HTTPS를 처리하고 있기 때문이다.
Cloudflare를 이런 방식으로 사용 중이라면 이 플러그인을 활성화할 경우 충돌이 생길 수 있다(비활성화는 어렵지 않으니 걱정할 필요는 없다). 솔직히 이미 Cloudflare를 쓰고 있다면 그쪽에 맡기는 편이 훨씬 편하다.
Dokku 호스트에 직접 푸시하는 번거로움을 없애고 싶다면 GitHub Actions로 배포를 자동화할 수 있다. 아래는 이를 구현한 GitHub Actions 워크플로우 예제다:
deploy-dokku.yml
name: CI
on:
workflow_dispatch:
push:
branches: [main]
concurrency: # Cancel previous jobs to avoid deploy locks on dokku
group: ${{ github.ref }}
cancel-in-progress: true
jobs:
deploy-dokku:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Install SSH key
run: |
echo "${{ secrets.DOKKU_SSH_PRIVATE_KEY }}" > private_key.pem
chmod 600 private_key.pem
- name: Add remote and push
run: |
git remote add dokku dokku@rechat.co:llm-eval
GIT_SSH_COMMAND="ssh -i private_key.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no" git push dokku main -f자꾸 잊어버리는 것들을 여기 정리해둔다. 아래 예제에서 앱 이름은 llm-eval, 호스트는 rechat.co으로 가정한다.
명령어 실행을 위해 Dokku 호스트에 직접 SSH로 접속할 필요는 없다. dokku 사용자를 통해 다음과 같이 원격으로 실행할 수 있다:
깨끗하게 새로 빌드하기 위해 Docker 캐시를 무효화하는 방법은 다음과 같다:
푸시 없이 재빌드만 하고 싶을 때가 있다. 여러 방법이 있지만 그중 하나는 다음과 같다:
새 앱을 배포할 때마다 이 내용을 매번 다시 찾아야 했기에, 어차피 정리해야겠다 싶었다. 다른 분들에게도 도움이 되길 바란다!