애플리케이션을 EC2에 배포하는 과정에서 도커 이미지에 민감정보가 올라가는 문제를 해결한 과정을 작성했습니다.
약과를 개발하면서, AWS EC2에 애플리케이션을 배포하는 과정을 점진적으로 개선해왔습니다. 처음에는 애플리케이션을 직접 git clone
으로 배포했지만, 이제는 GitHub Actions를 활용하여 git push
만으로 자동으로 EC2에 배포되도록 설정했습니다.
초기 배포는 아래와 같은 과정을 거쳤습니다:
git push
를 하면 GitHub Actions가 실행됩니다.이 과정은 비교적 간단했지만, 주의할 점이 있었습니다. 약과 프로젝트는 public 레포지토리이기 때문에 민감한 정보를 코드에 포함시키면 안 된다는 것입니다.
그렇다면 GitHub Actions는 깃허브 코드를 기반으로 동작하는데, 민감한 정보(예: DB 접속 정보나 보안 키 값)는 어떻게 처리했을까요?
이 문제를 해결하기 위해 GitHub의 Secrets 기능을 활용했습니다. Secrets에 민감한 정보를 저장하면, 레포지토리에 올리지 않고도 GitHub Actions 실행 시 해당 값을 사용할 수 있습니다.
처음에는 Docker 이미지를 생성하기 전에 Secrets에 저장한 application.yml
파일을 가져와 Docker 이미지에 포함시켰습니다.
하지만 이 방식에는 치명적인 문제가 있었습니다. Docker 이미지를 공개된 Docker Registry에 업로드할 경우, 이미지 안에 포함된 민감한 정보가 노출될 위험이 있었습니다. 이에 따라 더 안전한 배포 방법을 찾아야 했습니다.
Docker 이미지에 민감 정보를 포함하지 않기 위해 docker-compose를 사용해 민감 정보를 외부에서 주입하는 방식으로 수정했습니다.
Spring 프레임워크는 환경 변수를 외부에서 설정해 애플리케이션에 주입할 수 있습니다. Docker Compose를 활용하면 이러한 환경 변수 설정이 더 쉬워집니다.
이 방식의 장점은 다음과 같습니다:
Docker Compose는 여러 Docker 컨테이너를 하나의 서비스로 묶어 관리할 수 있는 도구로, 다양한 설정을 유연하게 처리할 수 있습니다.
아래는 수정된 배포 과정에서 사용한 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 이미지를 보다 안전하게 사용할 수 있게 되었습니다. 이를 통해 민감 정보를 보호하면서도 효율적인 배포 자동화를 유지할 수 있었습니다.