7P by GN⁺ | ★ favorite | 댓글 1개
  • Dokku는 단일 VPS를 Heroku처럼 쓰게 해주는 오픈소스 PaaS로, 여러 앱을 직접 소유한 인프라에 저렴하게 배포하려는 개인·소규모 작업에 잘 맞음
  • 비-GPU 워크로드는 월 7달러 OVHcloud VPS에서 운영 중이며, LLM 컨설팅처럼 자주 앱을 올려야 하는 환경에서 배포 비용과 복잡도를 낮춤
  • Dockerfile 기반 앱은 Dokku 앱 생성, Git remote 추가, git push dokku main만으로 배포되고 dokku ps:scale로 프로세스 수를 조정할 수 있음
  • 정적 사이트도 _site, .static, nginx buildpack, dokku-http-auth를 조합하면 비공개 GitHub 저장소 기반 배포와 비밀번호 보호가 가능함
  • GitHub Actions, 원격 SSH 명령, Docker 캐시 무효화, push 없는 rebuild까지 연결하면 개인용 PaaS를 반복 가능한 운영 환경으로 만들 수 있음

단일 VPS를 Heroku처럼 쓰는 Dokku

  • Dokku는 사용자가 선택한 단일 서버에서 실행되는 오픈소스 PaaS
  • Heroku와 비슷한 배포 경험을 제공하지만, 인프라는 사용자가 직접 소유함
  • Heroku 비용이 커질 수 있기 때문에, 여러 애플리케이션을 배포해야 하는 LLM 컨설팅 작업에서는 비용 효율적인 배포 플랫폼이 중요함
  • 비-GPU 워크로드용으로 월 7달러 OVHcloud VPS에서 Dokku 서버를 운영함

Heroku식 배포 경험과 운영 기능

  • Dokku는 Heroku처럼 쓰기 쉬운 배포 흐름을 제공함
  • Let’s Encrypt를 통한 자동 SSL 인증서 관리를 지원함
  • Basic Auth로 사이트에 비밀번호 보호를 걸 수 있음
  • 단일 명령으로 scale up/down을 수행할 수 있음
  • Node, Python 등 다양한 앱을 처리하고, 필요한 경우 Docker 컨테이너도 직접 정의할 수 있음
  • 공식 플러그인이 많아 필요한 기능 대부분을 확장할 수 있음
  • 배포는 Git 명령만으로 진행 가능함

Docker 컨테이너로 앱 배포하기

  • Dokku를 VPS에 설치한 뒤, 앱 저장소 루트에 Dockerfile을 두면 Docker 컨테이너로 배포할 수 있음
  • 예시 Dockerfile은 python:3.10 이미지를 사용하고, 코드를 /app으로 복사한 뒤 pip install .을 실행함
  • entrypoint.sh는 로컬 또는 Docker 컨테이너에서 앱을 쉽게 실행하기 위해 사용됨
    • 예시는 uvicorn main:app --port "$PORT" --host 0.0.0.0로 FastAPI 앱을 실행함
  • Dokku 호스트에서 먼저 앱을 생성함
dokku apps:create myapp
  • 로컬에서는 ~/.ssh/config에 Dokku 호스트 접근 정보를 설정하고, 해당 호스트 이름을 dokku로 지정함
  • 로컬 Git 저장소에 Dokku를 remote로 추가한 뒤 push하면 배포됨
git remote add dokku dokku@dokku:myapp
git push dokku main
  • 배포 후 로컬 로그에 앱 URL이 출력되며, 기본값은 myapp.yourdomain.com 형태임
  • 워커 수는 다음 명령으로 조정할 수 있음
dokku ps:scale myapp web=2
  • 더 자세한 내용은 Dokku docs에서 확인할 수 있음

비공개 정적 사이트와 Basic Auth

  • GitHub Pages는 비공개 정적 사이트를 쉽게 배포하려면 비싼 Enterprise 계정이 필요해 불편함
  • Dokku를 사용하면 비공개 GitHub 저장소의 정적 사이트를 배포하고 비밀번호로 보호할 수 있음
  • 정적 사이트가 Git 저장소의 _site 폴더에 있다고 가정함
  • Dokku 호스트에서 앱을 만들고 NGINX_ROOT 환경 변수를 _site로 설정함
dokku apps:create mysite
dokku config:set static-site NGINX_ROOT=_site
sudo dokku plugin:install https://github.com/dokku/dokku-http-auth.git
sudo chmod +x /home/dokku
  • 정적 사이트가 들어 있는 Git 저장소 루트에서 다음 작업을 수행함
touch .static
echo BUILDPACK_URL=https://github.com/dokku/buildpack-nginx > .env
git remote add dokku dokku@dokku:mysite
  • .static은 Dokku에 정적 사이트임을 알려줌
  • BUILDPACK_URL은 nginx buildpack을 사용하도록 지정함
    • 보통 자동 감지되지만, 코드와 정적 사이트가 함께 있는 프로젝트에서는 nginx buildpack을 명시해야 혼동을 줄일 수 있음
  • 배포는 git push dokku main으로 수행함
  • 인증은 Dokku 호스트에서 다음 명령으로 활성화함
dokku http-auth:enable mysite <username> <password>
  • 여러 사용자명/비밀번호를 추가할 수 있고 특정 IP 필터링도 가능함
  • HTTPS는 Let’s Encrypt Plugin으로 설정할 수 있으며 자동 갱신도 지원함
  • Cloudflare 프록시로 HTTPS를 처리하는 경우에는 Let’s Encrypt 플러그인 대신 Cloudflare에 맡기는 구성을 사용함

GitHub Actions로 자동 배포하기

  • Dokku 앱은 GitHub Actions로 자동 배포할 수 있음
  • Dokku 호스트에 직접 push하는 작업을 수동으로 반복하지 않아도 됨
  • 예시 workflow는 workflow_dispatchmain 브랜치 push에서 실행됨
  • concurrency 설정으로 이전 job을 취소해 Dokku의 deploy lock을 피함
  • workflow는 코드를 checkout하고, secrets.DOKKU_SSH_PRIVATE_KEY에서 SSH private key를 만든 뒤, Git remote를 추가하고 Dokku로 강제 push함
name: CI
on:
  workflow_dispatch:
  push:
    branches: [main]

concurrency:
  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 사용자로 원격 명령을 실행할 수 있음
ssh dokku@rechat.co apps:list
  • Docker 캐시를 무효화해 새 빌드를 수행할 수 있음
ssh dokku@rechat.co repo:purge-cache llm-eval
  • push 없이 rebuild가 필요할 때는 여러 방법이 있으며, 한 가지 방법은 다음 명령임
ssh dokku@rechat.co ps:rebuild llm-eval

반복 배포를 위한 개인 참고 자료

  • 새 앱을 배포할 때마다 같은 세부 정보를 다시 찾아야 해서 정리함
  • Dokku를 이용한 개인용 배포 플랫폼 구성을 반복적으로 사용할 수 있는 참고 자료로 남김
GeekNews Weekly에 포함된 글입니다. 에디터 코멘트 보기

댓글과 토론

Hacker News 의견들
  • 최근 Dokploy를 즐겨 쓰고 있음
    https://github.com/Dokploy/dokploy
    Dokku와 비슷하지만 웹 UI가 괜찮고, Docker/Compose 기반 배포가 더 쉬우며, 자동 Let’s Encrypt 기능이 별도 플러그인이 아니라 기본 설계로 들어가 있음
    여기에 호스팅된 앱 배포를 트리거하는 GitHub Actions 워크플로도 만들었음. 기본적인 cURL 명령이지만 잘 동작함
    https://github.com/benbristow/dokploy-deploy-action
    여러 앱을 바로 배포할 수 있는 사전 구성 Compose 파일도 모아둠
    https://github.com/benbristow/dokploy-compose-templates

    • 살짝 주제에서 벗어나지만, 특정 도구를 칭찬하는 글에서 현재 최상단 댓글이 더 새로운 다른 도구 링크라는 게 조금 웃김
      링크 공유가 잘못이라는 뜻은 아니지만, HN에는 약간 남의 떡이 더 커 보이는 성향이 있는 듯함. 어떤 도구가 나쁘다는 논의에서 대안을 제시하는 건 더 이해되지만, 특정 주제 글에서는 그 주제를 써본 사람들이 의견과 팁을 나누는 댓글이 가장 유용하게 느껴짐
      이번 경우 Dokku에 대해 커뮤니티가 가장 가치 있게 본 댓글이 Dokploy 링크인데, 커밋 기록을 보면 올해 4월쯤 생긴 새 프로젝트로 보임
    • 최근 HN의 Dokku 글을 보고 배포 과정을 자세히 파다가 멀티 노드 지원이 전혀 없다는 걸 알게 됨
      한 서버를 넘어 확장하고 싶어지는 순간 Dokku로는 안 되는데, Heroku 비슷한 도구를 쓰는 핵심 이유 대부분이 거기에 있다고 봄. 예전에 k3s도 써봤지만, Kubernetes는 비기업 환경에는 늘 과하게 느껴졌음
      Dokploy가 멀티 노드를 지원한다니 한번 봐야겠음
    • 추천을 보고 바로 써봤는데 좋아 보임. 예전에 coolify.io를 써봤지만 멀티 노드/Swarm 지원이 좋지 않았고 레지스트리도 동작하지 않았음
      Dokploy는 처음부터 바로 잘 돌아가는 느낌이었음. 다만 배포 미리보기가 있으면 좋겠음. Coolify에는 있었지만 없어도 감수할 수 있음
    • 이 대안의 또 다른 대안으로 Dokku 자체용 웹 UI를 쓰는 방법도 있음. 예를 들면 https://github.com/ledokku/ledokku
    • 좋아 보이지만 이건 꽤 큰 보안 이슈
      https://github.com/Dokploy/dokploy/releases/tag/v0.7.2
  • 최근 새 서버로 옮기면서 “셀프 호스팅 Heroku”류 솔루션을 많이 찾아봤고, coolify.io, ploi 같은 선택지에 대한 HN 논의도 많이 읽었음
    매번 nginx 설정을 복사하고 고치는 일이 지겨워졌기 때문임
    결국 Dokku로 정착했는데, 개입되는 “마법”이 가장 적고 설령 나중에 쓰지 않게 되더라도 제거만 하면 모든 게 그대로 돌아갈 수 있어서였음. 강력 추천함
    개발자도 매우 반응이 빠르고, 잘 모르는 상태에서도 도움을 받아 커스텀 플러그인을 만들 수 있었음. 블로그에도 정리해둠: https://blog.notmyhostna.me/posts/deploying-docker-images-wi...

    • “새 서버 만들고 설정 복사하는 것도 괜찮다”에서 “이제 귀찮으니 추상화하고 싶다”로 넘어가는 데 얼마나 걸렸는지 궁금함
      몇 년에 걸친 여정이었는지, 아니면 서버가 N대쯤 되면 바로 분명해지는 종류인지 궁금함
      지금은 “아파트 안의 물리 머신”과 “전부 클라우드 네이티브” 사이 공간을 배우는 중이고, cloud-init으로 서버를 설정한 뒤 작은 Docker Compose 시스템들을 돌리며 꽤 만족하고 있음
    • 실제로 찾고 있는 건 Ansible이라고 부르는 도구임
  • 여러 해 동안 새 소프트웨어를 시험해보면 실제 사용에서 곧바로 장애물에 부딪힐 위험이 크다는 걸 알게 됨
    반쯤 기본적인 요구사항에서도 어떤 세부사항, 복잡성, 버그 때문에 GitHub 이슈로 직행하는 경우가 있음
    Dokku는 그렇지 않았음. 자기가 하는 일을 잘하고, 명령줄 인자 순서가 살짝 특이한 점 몇 개를 빼면 가벼운 용도로는 훌륭했음
    더 많이 쓴다면 전체 아키텍처를 선언형 설정 파일로 구성하고 싶어질 텐데, Dokku가 그걸 할 수 있는지는 모르겠음

    • 그러고 나면 그런 GitHub 이슈들은 한 달 뒤 stalebot이 닫아버리고, 저장소는 이슈가 별로 없는 것처럼 보이게 됨
  • Dokku는 정말 괜찮음. 직접 Docker 이미지를 만들고 Swarm으로 배포하기 전까지 잘 썼음
    내가 만든 셀프 호스팅 PaaS인 Lunni에도 어느 정도 동기가 되었음: https://lunni.dev/
    전반적으로 Heroku나 AWS 대신 자기 서버에서 모든 걸 돌리는 발상이 정말 좋음. 단순하고 예측 가능한 월 요금은 마음을 편하게 해줌

    • 대역폭 비용 상한이 있는 괜찮은 호스팅을 찾았는지 궁금함
      이런 걸 찾고 있지만, 뭔가 잘못 설정했을 때 예상치 못한 네트워크 요금이 나오는 건 피하고 싶음
    • Swarm에 대한 생각이 궁금함
      Swarm은 Docker 회사가 어려워 보인다는 점이 걱정됨
      경쟁자로는 Nomad가 있지만, 최근 IBM 인수 때문에 Nomad의 미래도 걱정됨
    • Docker Swarm을 골랐는지 궁금함
      Swarm을 잘 몰라서 Kubernetes와 비교했을 때 쉬운 점, 좋은 점, 빠진 점 등이 어떻게 느껴지는지 알고 싶음
  • 오늘 첫 페이지에 관련 논의가 있음: “Coolify’s rise to fame, and why it could be a big deal” https://news.ycombinator.com/item?id=41356239
    “Coolify는 어떤 규모의 조직이든 임의 개수의 무료 셀프 호스팅 소프트웨어를 그 어느 때보다 쉽게 호스팅하게 해줄 수 있다”
    https://github.com/coollabsio/coolify
    “오픈소스이자 셀프 호스팅 가능한 Heroku / Netlify / Vercel 대안”

  • “사이트에 HTTPS를 쓰고 싶은 경우가 많다. Dokku는 Let’s Encrypt 플러그인으로 이를 쉽게 해주며 자동 갱신도 해준다. 나는 Cloudflare 프록시에 맡기고 있어서 이걸 쓰지 않는다”라고 되어 있는데, Cloudflare와 Dokku 사이에도 TLS를 쓰고 있기를 바람
    자체 서명 인증서라도 없으면, 기본 인증 뒤에 둘 만큼 민감해 보이는 개인 사이트들이 인터넷 구간에서 평문으로 오가게 됨

    • Cloudflare가 바로 이 목적의 origin certificate를 생성할 수 있고, dokku certs:add myapp으로 Dokku에 인증서를 추가할 수 있는 걸로 이해하고 있음
    • 동의함. Cloudflare IP에서 오는 인바운드만 허용하도록 방화벽이나 EC2 Security Group을 설정해도 나쁠 게 없음: https://www.cloudflare.com/ips/
      또는 Cloudflare Tunnel을 쓰고 모든 들어오는 연결을 막을 수도 있음
    • Dokku로 와일드카드 인증서를 발급할 수 있는지 궁금함
      사용자 도메인을 미리 알 수 없으니 TXT 레코드를 등록하려면 프록시 도메인이 필요해 보임
    • 여기서 실제 위협 모델이 뭔지 진심으로 궁금함
  • Dokku를 여러 해 동안 써왔음. 놀라울 정도로 안정적이고 쓰기 쉬움
    2018년에 Dokku로 여러 앱과 웹사이트를 배포하는 긴 튜토리얼을 썼는데 [1], 6년이 지난 지금도 같은 단계를 따라 하면 여전히 동작할 거라고 확신함
    1: https://maxschmitt.me/posts/tutorial-deploy-apps-websites-do...

  • 여기서 Dokku를 보니 반가움. 정말 훌륭한 제품이고 창업자도 매우 겸손하고 도움을 잘 줌
    지금은 많은 돈을 보태기 어렵지만, 더 많은 사람이 재정적으로 후원해주면 좋겠음

  • Dokku를 써본 경험은 꽤 안 좋았음. 처음 시작은 빨랐지만 VPS가 크래시 후 재시작되면 앱들이 다시 올라오지 않았음
    Dokku 명령을 다시 실행해야 했음. 내가 뭔가 잘못했을 수도 있지만, 결국 단일 노드 Kubernetes 구성으로 옮겼고 그쪽이 더 안정적이었음

    • Dokku 유지보수자임. 더 자세한 피드백이 있으면 꼭 듣고 싶음. 그래도 잘 맞는 대안을 찾았다니 다행임 :)
    • systemctl enable foo
  • 이런 종류의 인프라에서는 파일/객체 저장소로 뭘 쓰는지 궁금함
    AWS 같은 걸 쓰면 송신 트래픽 비용 때문에 절감 효과가 사라질 것 같음

    • 호스팅형 S3 호환 저장소가 필요하다면, Backblaze B2, Wasabi, Cloudflare R2 중 하나를 Bandwidth Alliance에 속한 VPS 제공자와 조합하면 될 것 같음
      https://www.cloudflare.com/bandwidth-alliance/
      그러면 송신 비용이 완화될 것임. 덤으로 저장소 자체도 훨씬 저렴함
    • 용량 요구가 크지 않다면 웹 서버의 디렉터리에 그냥 데이터를 저장하면 됨
      https://dokku.com/docs/advanced-usage/persistent-storage/
    • Hetzner Cloud VPS에 붙인 스토리지 위에서 Pocketbase를 쓰고 있음. Pocketbase도 Dokku 기반 컨테이너로 돌림
      말도 안 되게 싸고, 매우 안정적임
    • minIO도 S3 대안으로 셀프 호스팅할 수 있음. 아니면 데이터베이스를 호스팅할 수도 있음
      결국 어떤 종류의 저장소를 찾는지에 따라 달라질 가능성이 큼
    • 좋은 옛날식 로컬 디스크가 있음