[Docker] 민감정보 완벽 숨겨버리기~

coding_ticket·2025년 1월 13일
0
post-thumbnail

애플리케이션을 EC2에 배포하는 과정에서 도커 이미지에 민감정보가 올라가는 문제를 해결한 과정을 작성했습니다.

약과를 개발하면서, AWS EC2에 애플리케이션을 배포하는 과정을 점진적으로 개선해왔습니다. 처음에는 애플리케이션을 직접 git clone으로 배포했지만, 이제는 GitHub Actions를 활용하여 git push만으로 자동으로 EC2에 배포되도록 설정했습니다.


배포 자동화의 흐름

배포 자동화 과정

초기 배포는 아래와 같은 과정을 거쳤습니다:

  1. git push를 하면 GitHub Actions가 실행됩니다.
  2. Docker 이미지를 빌드합니다.
  3. EC2에 접근해 생성된 Docker 이미지를 실행합니다.

이 과정은 비교적 간단했지만, 주의할 점이 있었습니다. 약과 프로젝트는 public 레포지토리이기 때문에 민감한 정보를 코드에 포함시키면 안 된다는 것입니다.

그렇다면 GitHub Actions는 깃허브 코드를 기반으로 동작하는데, 민감한 정보(예: DB 접속 정보나 보안 키 값)는 어떻게 처리했을까요?


민감 정보 처리: 초기 방식

이 문제를 해결하기 위해 GitHub의 Secrets 기능을 활용했습니다. Secrets에 민감한 정보를 저장하면, 레포지토리에 올리지 않고도 GitHub Actions 실행 시 해당 값을 사용할 수 있습니다.

처음에는 Docker 이미지를 생성하기 전에 Secrets에 저장한 application.yml 파일을 가져와 Docker 이미지에 포함시켰습니다.

초기 방식

하지만 이 방식에는 치명적인 문제가 있었습니다. Docker 이미지를 공개된 Docker Registry에 업로드할 경우, 이미지 안에 포함된 민감한 정보가 노출될 위험이 있었습니다. 이에 따라 더 안전한 배포 방법을 찾아야 했습니다.


민감 정보를 안전하게 처리하는 새로운 방식

Docker 이미지에 민감 정보를 포함하지 않기 위해 docker-compose를 사용해 민감 정보를 외부에서 주입하는 방식으로 수정했습니다.

수정된 배포 흐름

수정된 배포 방식

Spring 프레임워크는 환경 변수를 외부에서 설정해 애플리케이션에 주입할 수 있습니다. Docker Compose를 활용하면 이러한 환경 변수 설정이 더 쉬워집니다.

이 방식의 장점은 다음과 같습니다:

  • Docker Hub에 업로드되는 이미지는 민감한 정보를 포함하지 않습니다.
  • 환경 변수를 외부에서 관리하므로 보안이 강화됩니다.

Docker Compose는 여러 Docker 컨테이너를 하나의 서비스로 묶어 관리할 수 있는 도구로, 다양한 설정을 유연하게 처리할 수 있습니다.


GitHub Actions 스크립트

아래는 수정된 배포 과정에서 사용한 GitHub Actions 스크립트입니다. 이를 통해 환경 변수 파일을 EC2로 전달하고, 민감 정보가 없는 Docker 이미지를 가져와 환경 변수를 설정해 실행합니다.

name: Java CI with Gradle

on:
  push:
    branches:
      - dev

permissions:
  contents: read

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'adopt'

      - name: Send docker-compose.yml
        uses: appleboy/scp-action@master
        with:
          username: ubuntu
          host: ${{ secrets.AWS_PUBLIC_DNS }}
          key: ${{ secrets.AWS_PEM_KEY }}
          port: 22
          source: ./infra/docker/docker-compose.yml
          target: "/home/ubuntu/"
          strip_components: 3

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Build with Gradle
        run: ./gradlew :fitdo-web:build

      - name: Docker login
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_TOKEN }}

      - name: Docker build & push
        run: |
          docker build -f ./yakgwa/Dockerfile-web.dev -t ${{ secrets.DOCKER_USERNAME }}/yakgwa-web .
          docker push ${{ secrets.DOCKER_USERNAME }}/yakgwa-web

      - name: Deploy to dev
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.AWS_PUBLIC_DNS }}
          username: ubuntu
          key: ${{ secrets.AWS_PEM_KEY }}
          script: |
            cd /home/ubuntu
            sudo touch .env
            echo "${{ secrets.ENV_VARS }}" | sudo tee .env > /dev/null
            sudo chmod 666 /var/run/docker.sock
            sudo docker pull ${{ secrets.DOCKER_USERNAME }}/yakgwa-web
            docker compose -f docker-compose.yml --env-file ./.env up -d yakgwa-web
            docker image prune -f

마무리

환경 변수를 외부에서 관리하면서 Docker 이미지를 보다 안전하게 사용할 수 있게 되었습니다. 이를 통해 민감 정보를 보호하면서도 효율적인 배포 자동화를 유지할 수 있었습니다.

0개의 댓글