1P by GN⁺ | ★ favorite | 댓글 1개
  • 개인 서버의 bare Git 저장소에 post-receive을 추가해 테스트, 빌드, 파일 이동을 자동화하는 간단한 CI 구성임
  • 기존 CI는 복잡한 YAML 설정과 느린 실행, 어려운 자체 호스팅에 비해 완전한 빌드 격리나 비밀정보 관리까지 필요하지 않았음
  • 훅에서 작업을 직접 실행하면 실패 시 push가 거부되거나 완료가 지연되므로, 최소형 작업 큐 nq 로 백그라운드 처리함
  • 훅은 nq만 호출하고 로그는 ssh server nqtail -a 로 확인해 빠르고 간단하게 운영할 수 있음
  • 필요에 따라 landdown·Podman으로 빌드를 격리하고 sops로 비밀정보를 관리하거나, Git 이메일 패치·git-shell·git http-backend로 개발 방식을 확장할 수 있음

post-receive 훅과 nq 구성

  • 개인 서버에서 ssh server git init --bare repo로 저장소를 만들고 git clone server:repo로 복제함
  • bare 저장소의 hooks 디렉터리에 셸 스크립트 형태의 post-receive을 넣어 push할 때마다 CI를 시작함
  • 작업을 훅에서 직접 실행하면 두 가지 문제가 생김
    • 스크립트가 실패할 경우 push가 거부됨
    • 스크립트 실행이 느리면 push 완료도 함께 지연됨
  • 훅에서는 최소형 작업 큐 nq를 호출해 작업을 백그라운드 큐에 추가함
    • 로그는 ssh server nqtail -a로 확인함
    • 설정 과정은 짧은 튜토리얼에서 확인할 수 있음

격리와 개발 방식 확장

  • 빌드를 샌드박스에서 실행하려면 landdown을 사용할 수 있음
  • Podman으로 빌드를 호스트 환경과 격리하거나 sops로 비밀정보를 관리할 수 있음
  • bazaar 방식 개발에는 이메일로 Git 패치를 받는 구성이 적합함
  • cathedral 방식 개발은 git-shell 또는 git http-backend로 구성 가능함

댓글과 토론

Lobste.rs 의견들
  • CI에는 적어도 두 가지 문제가 있음
    쉬운 문제는 코드 변경 시 make test를 실행하는 것이고, 어려운 문제는 Linux, Windows, Mac 모두에서 make test를 실행하는 것임

    • Linux는 쉽고 Windows는 어렵지만, macOS는 고통스러운 수준
    • CI에서 어려운 부분은 실패 시 디버깅까지 지원하는 작업 실행 엔진이라고 봄
      기존 엔진들의 개발자 경험과 디버깅 기능이 늘 뒷전이라 불만이어서 https://ci.pico.sh 에서 CI 시스템을 만들고 있음. DSL도 싫고, 계층적으로 이어지는 YAML은 서서히 생명력을 빨아들이는 느낌
    • 이 방식은 쉬운 문제를 해결하며, QEMU로 BSD 계열을 지원하고 Docker로 여러 배포판까지 확장할 수는 있겠지만 그 이상에는 더 완전한 도구가 필요해 보임
  • gitolite 위에 이를 구축하고 Temporal로 전달해 빌드 과정을 제한 없이 제어한 적이 있음
    실행 실패 시 푸시를 거부할 수도 있지만, 보통은 훅을 통과시킨 뒤 실패를 별도로 처리하는 편이며 구성도 단순하고 재미있었음

    • gitolite의 접근 제어 도구가 특히 마음에 들고, 존재하지 않는 저장소로 푸시해 새 저장소를 만들 수 있는 방식도 훌륭함
  • 셸 스크립트 실행을 중심으로 하는 또 다른 최소형 CI로 laminar CI가 있으며, 웹 UI도 제공함

  • 오래전 Windows 전용 기업 환경에서 팀 전체가 사용하는 로컬 CI 서버로 Mac mini를 두고 iOS 앱을 빌드했으며, 초기에 시도한 Git 활용법 중 하나였음

  • https://mccd.space/git/ 에서 찾았는데, stagit 포크를 사용하는 것으로 보임
    몇 달 전까지 Forgejo와 Woodpecker를 운영했지만 필요하지 않은 기능이 대부분이라 모두 제거하고 이와 비슷한 더 가벼운 구성을 찾고 있었음. 다음 과제가 CI였기에 시기적절하며, 곧 공개할 작은 라이브러리를 SourceHut에 미러링할지 고민 중임

    • stagit를 포크해 연락처 이메일과 내비게이션 바를 추가하고, CSS 변경용 ID를 넣었으며 불필요한 정보는 제거했음
      저장소는 git-daemon으로 웹에 읽기 전용 공개하며, 전체 구성 방법은 여기에 정리해 두었음
  • 이 글로 nq를 처음 알았지만 아마 systemd-run 을 사용할 듯함
    거의 모든 실행기에 Nix를 쓰고 있으므로 nix flake check 결과를 OTLP 지표와 로그로 노출하면, CI 요구 사항을 모니터링 시스템으로 해결할 수 있을 것 같음

  • 이처럼 단순한 자체 호스팅 개발 플랫폼 구성이 마음에 듦
    CI용으로 가볍고 단순한 컨테이너 시스템인 bubblewrap을 쉽게 설정해 사용할 수 있음. 다만 nq를 쓰면 CI 실패 시 푸시 거부는 불가능해 보이는데 어떻게 처리하는지 궁금함

    • 스크립트를 제한하는 데 Landlock을 사용하는 보조 도구도 있으며, 사용법은 조금 더 단순하다고 봄
      격리가 더 필요하면 Podman, Docker, bubblewrap을 추가할 수 있음. 테스트를 실행하는 커밋 전 훅을 두지 않는 것과 같은 이유로 CI 실패 시 푸시를 거부하지 않는데, 깨진 작업도 커밋하거나 푸시해야 할 때가 있고 푸시가 매우 느려질 수 있기 때문임. 거부가 필요하면 nq 없이 CI를 동기 실행해 종료 코드가 0이 아닐 때 푸시를 막으면 됨
      또는 main이 아닌 브랜치nq로 실행하고 main 브랜치만 동기 실행할 수 있음
  • landdown 링크가 깨진 것으로 보임