GitHub Actions + Docker | Container Job·Service Container 실전 활용

okorion·2025년 12월 6일

📡 GitHub Actions

목록 보기
8/11
post-thumbnail

GitHub Actions는 기본적으로 VM 환경을 제공하지만, Docker를 활용하면 완전히 통제된 실행환경을 구성할 수 있다.
특히 언어·OS 차이, DB 연동 테스트, 로컬 개발과의 환경 일치가 중요한 프로젝트에서 Docker Job은 필수다.

이 글은 Docker 기반 GitHub Actions의 핵심 요소인
Container Job / Service Container / Dockerfile 기반 커스텀 빌드 / DB 테스트 환경 구성을 구조적으로 정리한다.


1. Docker 기반 GitHub Actions의 구조

GitHub Actions의 Docker 활용은 크게 두 가지로 나뉜다.

종류목적특징
Container JobJob 전체를 특정 Docker 이미지로 실행실행환경 통일, 의존성 충돌 제거
Service Container테스트에 필요한 외부 서비스(DB 등) 제공컨테이너 간 네트워크 자동 구성

이 두 기능을 조합하면 애플리케이션 + DB + 메시지 브로커 환경까지 CI에서 그대로 재현할 수 있다.


2. Container Job: Job 전체를 컨테이너에서 실행

Container Job은 실행 VM 대신 Docker 이미지를 Job 실행 환경으로 사용한다.

최소 예제

jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: node:18
    steps:
      - uses: actions/checkout@v4
      - run: node -v

해석

  • VM은 단순 호스트 역할
  • 실제 Job은 node:18 컨테이너 내부에서 실행
  • 개발환경과 CI 환경을 1:1로 일치시키는 데 유리

2.1 Container Job에서 env, secrets 사용

컨테이너 내부에서도 동일하게 접근할 수 있다.

steps:
  - run: echo $TOKEN
    env:
      TOKEN: ${{ secrets.API_TOKEN }}

경로가 달라지는 경우도 있으므로 컨테이너 OS 기준 경로를 정확히 지정해야 한다.


3. Dockerfile 기반 커스텀 컨테이너 실행

프로젝트에서 자체 Dockerfile을 활용할 수 있다.

예제: Repository의 Dockerfile 사용

jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: ghcr.io/org/app:latest

혹은 Workflow에서 직접 빌드 후 container로 사용하려면 다음과 같은 패턴이 필요하다.

Dockerfile 빌드 후 실행

steps:
  - uses: actions/checkout@v4
  - run: docker build -t app-image .
  - run: docker run app-image npm test

이 방식은 container job이 아니라 VM 내 Docker 실행이므로 구분해야 한다.


4. Service Container: DB·캐시·브로커 환경 구성

Service Container는 테스트에서 필요한 외부 서비스를 컨테이너로 제공한다.

예: PostgreSQL + Redis 테스트 환경

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      postgres:
        image: postgres:14
        env:
          POSTGRES_PASSWORD: pass
        ports:
          - 5432:5432
        options: >-
          --health-cmd="pg_isready"
          --health-interval=5s

      redis:
        image: redis:7
        ports:
          - 6379:6379

    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test
        env:
          DB_HOST: postgres
          REDIS_HOST: redis

핵심 구조:

  • 각 서비스는 컨테이너 이름(postgres, redis) 으로 접근
  • 포트 매핑은 CI 내부에서만 유효
  • health check 옵션으로 안정적 부팅 보장 가능

5. Container Job + Service Container 조합

Container Job 내부에서 Service Container와 함께 사용하는 것도 가능하다.

jobs:
  test:
    runs-on: ubuntu-latest
    container:
      image: node:18

    services:
      mysql:
        image: mysql:8
        env:
          MYSQL_ROOT_PASSWORD: root

    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test
        env:
          DB_HOST: mysql

컨테이너 간 네트워크 연결은 GitHub Actions가 자동 구성하므로 별도 docker network 설정이 필요 없다.


6. DB Container 실전 활용

DB 테스트는 Service Container의 대표적인 사용처이다.

예: PostgreSQL + Prisma 테스트

services:
  db:
    image: postgres:15
    env:
      POSTGRES_PASSWORD: test
    ports:
      - 5432:5432

Step에서 연결:

env:
  DATABASE_URL: "postgres://postgres:test@db:5432/app"

주의:

  • DB 컨테이너가 완전히 기동될 때까지 health check가 필요
  • 초기화 스크립트를 넣고 싶다면 docker-entrypoint-initdb.d 를 활용

7. 실무에서 오해하기 쉬운 컨테이너 관련 포인트

1) Dockerfile 빌드는 Container Job과 다르다

  • Container Job: Job 환경 자체가 Docker 컨테이너
  • docker build: VM 내에서 Docker 실행

이 둘을 섞어 이해하면 경로·환경 변수 혼동이 발생한다.

2) Service Container는 외부 네트워크 서비스와 다르다

  • 테스트 전용
  • GitHub Actions 내부 네트워크에서만 접근
  • 포트 매핑은 로컬 포트 개념과 다르다

3) Secrets는 컨테이너에서도 그대로 노출될 수 있다

환경 변수를 통해 컨테이너 내부로 전달되므로, 출력 금지 규칙을 동일하게 적용해야 한다.

4) Docker-in-Docker(DIND) 환경 요구 시 별도 설정 필수

docker build를 직접 수행하려면 privileged runner 환경이 필요할 수 있다.


8. 실무형 Docker CI 구축 예제

Node + PostgreSQL 테스트 + 빌드 파이프라인

name: docker-ci

on: push

jobs:
  test:
    runs-on: ubuntu-latest
    container:
      image: node:18

    services:
      postgres:
        image: postgres:14
        env:
          POSTGRES_PASSWORD: pass
        options: >-
          --health-cmd="pg_isready"
          --health-interval=5s

    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm run test

  build:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: docker build -t app .

구조적 해석:

  • 테스트 Job은 node:18 컨테이너에서 실행
  • PostgreSQL Service Container와 함께 테스트 수행
  • 테스트 통과 후 build Job에서 Docker 이미지 빌드

9. 핵심 개념 정리

  • Container Job: Job 실행 환경을 Docker 이미지로 대체
  • Service Container: 테스트용 외부 서비스(DB 등)를 컨테이너로 제공
  • Dockerfile 빌드와 Container Job은 완전히 다른 구조
  • 컨테이너 간 네트워크는 GitHub Actions가 자동 구성
  • DB 테스트는 Service Container가 가장 안정적

Docker 기반 실행은 CI/CD 환경을 표준화하고 테스트 신뢰성을 크게 올릴 수 있다.


10. 실수하기 쉬운 포인트

  • docker build와 container job을 혼동
  • health check 없이 DB 컨테이너 사용 → 테스트 실패
  • 컨테이너 내부 경로와 호스트 경로 혼동
  • Secrets를 컨테이너에서 echo 출력
  • container job과 service container의 역할을 섞어서 이해
  • docker-in-docker 환경 요구 여부를 파악하지 않고 빌드 구성

Docker는 GitHub Actions CI/CD 환경의 확장성과 재현성을 모두 확보하는 핵심 기능이다.

profile
Tech Blog

0개의 댓글