[CI/CD 구축] Redis를 docker 이용하여 메인 서버에 띄우기
1. 개요
이번 프로젝트에서는 redis를 따로 띄우지 않고, 메인 서버 안에다 docker로 띄우도록 구성하였다.
그 이유는 프로젝트 예상 규모가 크지 않기 때문에, 자금적 여유를 위해서 이다.
2. 코드 구성
redis를 구성하기 이전 코드는 아래와 같다.
name: Deploy to EC2 using Docker and ECR
on:
push:
branches:
- dev
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v2
with:
distribution: 'adopt'
java-version: '17'
- name: Grant execute permission for gradlew
run: chmod +x ./gradlew
- name: Create application-secret.yml from secret
run: |
mkdir -p ./src/main/resources/yml
echo "${{ secrets.APPLICATION_SECRET_YML }}" > ./src/main/resources/yml/application-secret.yml
- name: Build with Gradle
run: ./gradlew build
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v2
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Login to Amazon ECR
run: aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin ${{ secrets.ECR_URI }}
- name: Build Docker image
run: docker build -t aper-repository .
- name: Tag Docker image
run: docker tag aper-repository:latest ${{ secrets.ECR_URI }}:latest
- name: Delete latest image from ECR
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
aws ecr batch-delete-image --repository-name aper-repository --image-ids imageTag=latest
- name: Push Docker image to ECR
run: docker push ${{ secrets.ECR_URI }}:latest
- name: Login to ECR on EC2
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
aws ecr get-login-password --region ap-northeast-2 | sudo docker login --username AWS --password-stdin ${{ secrets.ECR_URI }}
- name: Stop running containers on EC2
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
sudo docker ps -q | xargs -r sudo docker stop
- name: Remove all containers on EC2
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
sudo docker ps -asq | xargs -r sudo docker rm
- name: Delete images on EC2
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
sudo docker images -q | xargs -r sudo docker rmi
- name: Prune unused Docker resources on EC2
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
sudo docker system prune -af
- name: Pull Docker image from ECR on EC2
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
sudo docker pull ${{ secrets.ECR_URI }}:latest
- name: Run Docker container on EC2
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
sudo docker stop hdev_server || true
sudo docker rm hdev_server || true
sudo docker run -d —env-file /root/.env -p 5000:8080 ${{ secrets.ECR_URI }}:latest
여기서 수정된 것은 마지막 아래 pull docker image from ECR on EC2 와 Run Docker container on EC2 부분이 지워지고,
- name: Deploy using Docker Compose
uses: appleboy/ssh-action@v0.1.6
with:
host: ${{ secrets.EC2_PUBLIC_IP }}
username: ${{ secrets.EC2_USERNAME }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
cd /home/ubuntu/docker-compose
export ECR_URI=${{ secrets.ECR_URI }}
sudo docker-compose down
sudo docker-compose pull
sudo docker-compose up -d
이 코드가 추가되었다는 것이다.
docker-compose 폴더를 만들고, 아래에 docker-compose.yml을 만들어 주었다.
다음으로 서버에 docker-compose를 다운로드 받아주고, 위 코드를 실행함을 통해 docker-compose.yml이 실행되도록 하였다.
ECR에서 이미지를 가져와서 실행하는 부분의 주체를 docker-compose.yml로 이동시켜준 것과 같다.
따라서 app: 부분에, ECR에서 이미지를 가져와서 실행하도록 구성하였다.
docker-compose.yml파일은 아래와 같다.
version: '3.8'
services:
app:
image: ECR-URI 넣어주기:latest
container_name: app_container
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: dev
depends_on:
- redis
redis:
image: redis:latest
container_name: redis_container
ports:
- "6379:6379"
command: redis-server --requirepass 비밀번호 넣어주기 --port 6379 --appendonly yes
volumes:
- redis-data:/data
restart: always
healthcheck:
test: ["CMD", "redis-cli", "-a", "비밀번호 넣어주기", "ping"]
interval: 10s
timeout: 5s
retries: 5
volumes:
redis-data:
이를 통해서 docker로 spring 서버와 redis 서버를 하나의 EC2에서 띄우도록 구성하였다.
또한 application-dev.yml과 application-secret.yml을 수정을 해야했다.
dev-redis:
host: redis_container
port: 6379
password: 비밀번호 넣기
위와 같이 application-secret.yml을 수정했따. container_name 부분이 host로 들어가게 된다.
application-secert.yml의 경우 아래와 같이 구성했다.
처음엔 data: 부분없이 바로 redis로 코드를 작성했지만, deprecated 되어서 작성할 수 없었다.
spring:
data:
redis:
host: ${dev-redis.host}
port: ${dev-redis.port}
password: ${dev-redis.password}