Files
project-base/ci
ttipo 1c0176640e
CI / Backend (lint · test · e2e · build) (push) Successful in 10m30s
CI / Frontend (lint · type-check · test) (push) Successful in 9m52s
CI / 에러 코드 SSOT 동기화 검사 (push) Has been cancelled
CI / Flutter (analyze · test) (push) Has been cancelled
fix(ci): 서비스 컨테이너 포트 매핑 제거 — 잡이 시작조차 못 하던 문제
러너를 붙이고 첫 실행에서 backend 잡의 모든 스텝이 checkout 부터 failure 로 표시됐다.
스텝이 실패한 게 아니라 서비스 컨테이너가 뜨지 못해 잡 준비 단계에서 죽은 것이다.

원인은 postgres 서비스의 ports: 5432:5432 였다.
개발 DB(project-db)가 이미 호스트 5432 를 점유하고 있어 바인딩이 충돌했다.

Gitea 러너는 잡을 컨테이너로 실행하고 서비스와 같은 네트워크에 붙이므로
호스트 포트 매핑이 애초에 필요 없고, 접근도 localhost 가 아니라 서비스 이름으로 해야 한다.
(GitHub Actions 는 잡이 VM 위에서 직접 돌아 localhost + ports 를 쓰는 점이 다르다)

- 서비스의 ports 매핑 제거
- e2e 스텝의 DB_HOST 를 localhost → postgres(서비스 이름)로 변경
- 두 플랫폼의 차이와 "모든 스텝이 한꺼번에 실패" 증상을 ci/README.md 에 정리

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 22:45:26 +09:00
..

CI 러너 설정

.github/workflows/ci.yml 을 실제로 실행하는 Gitea Actions 러너 설정입니다. 러너가 없으면 워크플로는 "Waiting for a runner" 상태로 대기만 합니다.

어디에 띄울 것인가

위치 장점 단점
Gitea 서버 (권장) 항상 켜져 있어 CI 가 늘 동작 서버에 Docker 필요
개발 PC 바로 시작 가능 PC 가 꺼지면 CI 도 멈춤

CI 의 목적이 "내가 없어도 검사되는 것"이므로 서버 쪽을 권장합니다.

설치

# 1) 저장소 Settings → Actions → Runners → Create new Runner 에서 토큰 발급
# 2) 설정 파일 준비
cd ci
cp .env.example .env        # 편집기로 열어 GITEA_RUNNER_REGISTRATION_TOKEN 채우기

# 3) 기동
docker compose -f docker-compose.runner.yml --env-file .env up -d

# 4) 등록 확인
docker compose -f docker-compose.runner.yml --env-file .env logs -f runner
#    "Runner registered successfully" 가 보이면 성공

저장소 Settings → Actions → Runners 에서 러너가 Idle 로 표시되면 준비 완료입니다. 이후 푸시하면 Actions 탭에서 실행이 시작됩니다.

잘 안 될 때

증상 원인 해결
잡이 계속 대기 중 라벨 불일치 RUNNER_LABELS 의 ubuntu-latest 가 워크플로 runs-on 과 같은지 확인
uses: 액션 다운로드 실패 서버에서 github.com 접근 불가 방화벽 확인. 폐쇄망이면 액션 미러 필요
등록 실패 (401/404) 토큰 만료·오타, URL 끝 / 토큰 재발급, GITEA_INSTANCE_URL 확인
잡 시작 직후 실패 도커 소켓 마운트 누락 /var/run/docker.sock 마운트 확인 (Windows 는 //var/run/docker.sock)
모든 스텝이 한꺼번에 실패(checkout 포함) 서비스 컨테이너가 뜨지 못함 아래 "서비스 컨테이너" 참고

서비스 컨테이너 주의 (GitHub Actions 와 다른 점)

Gitea 러너는 잡을 컨테이너로 실행하고 서비스와 같은 네트워크에 붙인다. GitHub Actions 는 잡이 VM 위에서 직접 돌기 때문에 관례가 다르다.

GitHub Actions Gitea act_runner
서비스 접근 주소 localhost + ports 매핑 서비스 이름 (postgres:5432)
ports: 필요 여부 필요 불필요 — 오히려 해롭다

ports: - 5432:5432 를 두면 호스트 포트를 점유하려 하는데, 개발 DB 가 이미 그 포트를 쓰고 있으면 잡이 시작조차 못 하고 모든 스텝이 failure 로 표시된다. (스텝이 실패한 게 아니라 잡 준비 단계에서 죽은 것이다)

ci.yml 의 backend 잡은 이 규칙에 맞춰 ports 없이 DB_HOST: postgres 를 쓴다.

리소스 참고

ci.yml 은 네 개의 잡을 실행합니다.

  • backend — postgres 서비스 컨테이너를 띄워 단위 테스트와 e2e 를 실행
  • frontend — lint·type-check·테스트
  • flutter — 매 실행마다 Flutter SDK 를 내려받아 수 분 소요
  • error-codes-sync — 에러 코드 생성 파일 드리프트 검사

서버 사양이 넉넉하지 않다면 처음에는 flutter 잡을 빼고 시작해도 됩니다. 나머지 세 개만으로도 대부분의 회귀는 걸립니다.

주의

  • 토큰은 ci/.env 에만 둡니다. 이 파일은 루트 .gitignore 로 커밋되지 않습니다.
  • runner-data/ 에 등록 정보가 저장됩니다. 지우면 토큰으로 재등록해야 합니다.
  • 러너는 도커 소켓에 접근하므로 호스트에 대한 사실상의 관리자 권한을 갖습니다. 신뢰할 수 있는 저장소의 워크플로만 실행되도록 하세요 (공개 저장소의 PR 실행 정책 확인).