.
├── docker-compose.yml
├── docker-files
│ ├── backend
│ │ └── Dockerfile
│ └── nginx
│ └── nginx.conf
├── scripts
│ ├── set-github-secrets.sh
│ └── setup-ssh-key.sh
└── src
배포 관련 파일 구조는 이런 식으로 만들었다.
docker-files에 컨테이너 관련 설정 파일들을 넣고 루트 디렉토리에는 docker-compose.yml 파일을 두었다.
backend의 Dockerfile은 GitHub Actions에서 Spring 애플리케이션 이미지를 빌드할 때 사용된다. 코드를 GitHub에 push하면 GitHub Actions가 이 Dockerfile을 사용해 이미지를 빌드하고 GitHub Container Registry에 push한다. 그리고 이렇게 만들어진 이미지를 docker-compose.yml에서 pull해와서 실행하는 것이다.
nginx와 mariadb는 이미 만들어진 공식 이미지를 그대로 사용할 수 있어서 별도의 Dockerfile이 필요하지 않았지만, backend는 우리가 작성한 Spring 애플리케이션을 포함한 이미지를 새로 만들어야 했기 때문에 Dockerfile이 필요했다.
# 빌드 스테이지
FROM amazoncorretto:17-alpine as build
WORKDIR /workspace/app
COPY gradle gradle
COPY build.gradle settings.gradle gradlew ./
COPY src src
RUN chmod +x ./gradlew
RUN ./gradlew bootJar
# 실행 스테이지
FROM amazoncorretto:17-alpine
VOLUME /tmp
COPY --from=build /workspace/app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=dev", "/app.jar"]
nginx는 공식 이미지를 그대로 사용하고 설정 파일만 변경해주면 된다. 그래서 nginx.conf 파일만 작성해줬다.
server {
listen 80;
server_name ${DOMAIN_NAME};
location / {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
mariadb는 docker-compose.yml에서의 설정만으로 충분하다. 그래서 따로 파일을 작성하진 않았다.
민감한 정보들은 github secrets를 사용하여 관리해줬다.
github secrets를 사용하기 전 우선 environments 설정을 해주었다.
github settings -> environments에서 환경을 하나 생성해준다.
난 development 관련 변수들을 secret으로 등록해줄 것이기 때문에 development 환경을 새로 생성해줬다.
그리고 environment에 secret을 등록해줄 건데
웹페이지에서 Add environment secret으로 일일이 secret을 등록해줄 수 있지만 귀찮다.
스크립트를 사용해서 로컬에서 .env 파일에 있는 환경변수들을 한꺼번에 secret으로 등록해주도록 하자.
#!/bin/bash
# ANSI 색상 코드
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
# 사용법 체크
if [ -z "$1" ]; then
echo "${RED}Usage: ./set-github-env-secrets.sh <environment_name>${NC}"
echo "${YELLOW}Example: ./set-github-env-secrets.sh development${NC}"
exit 1
fi
ENVIRONMENT=$1
# Environment secrets 설정
echo "⚙️ ${GREEN}GitHub ${ENVIRONMENT} environment secrets 설정을 시작합니다...${NC}"
# .env 파일이 존재하는지 확인
if [ ! -f .env ]; then
echo "${RED}Error: .env 파일을 찾을 수 없습니다.${NC}"
exit 1
fi
# .env 파일을 읽어서 secrets 설정
while IFS='=' read -r key value
do
if [ ! -z "$key" ] && [ ! -z "$value" ]; then
gh secret set "$key" -b"$value" --env $ENVIRONMENT || exit 1
fi
done < .env
# SSH key 설정 (선택적)
if [ -f ~/.ssh/id_ed25519 ]; then
gh secret set SSH_PRIVATE_KEY -b"$(cat ~/.ssh/id_ed25519)" --env $ENVIRONMENT || exit 1
fi
echo "✅ ${GREEN}GitHub ${ENVIRONMENT} environment secrets 설정이 완료되었습니다!${NC}"
$ sh scripts/set-github-secrets.sh [environment]
이런식으로 사용 가능. .env 파일이 있는 위치에서 스크립트를 실행해야 한다.
GitHub Actions workflow에서 라즈베리파이에 ssh 접속을 해주기 위해 ssh key가 필요하다.
~/.ssh/authorized_keys
에 등록이 과정을 자동화하기 위해 스크립트를 작성해줬다.
#!/bin/bash
# ANSI 색상 코드
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m'
# SSH 디렉토리 및 파일 확인
echo "SSH 설정을 확인합니다..."
# .ssh 디렉토리가 없으면 생성
if [ ! -d ~/.ssh ]; then
echo ".ssh 디렉토리를 생성합니다..."
mkdir -p ~/.ssh
chmod 700 ~/.ssh
fi
# id_ed25519 파일이 이미 존재하는지 확인
if [ -f ~/.ssh/id_ed25519 ]; then
echo "${YELLOW}SSH 키가 이미 존재합니다.${NC}"
echo "기존 키를 사용하시겠습니까? (y/n)"
read -r response
if [ "$response" = "y" ]; then
echo "${GREEN}기존 SSH 키를 사용합니다.${NC}"
else
echo "새로운 키로 대체하시겠습니까? 이 작업은 되돌릴 수 없습니다. (y/n)"
read -r replace
if [ "$replace" = "y" ]; then
echo "${RED}Warning: 필요한 경우 기존 키를 먼저 백업하는 것을 추천합니다.${NC}"
echo "계속하시겠습니까? (y/n)"
read -r confirm
if [ "$confirm" = "y" ]; then
echo "새로운 SSH 키를 생성합니다..."
echo "이메일 주소를 입력해주세요:"
read -r email
rm ~/.ssh/id_ed25519*
ssh-keygen -t ed25519 -b 4096 -C "$email"
else
echo "${RED}스크립트를 종료합니다.${NC}"
exit 1
fi
else
echo "${RED}스크립트를 종료합니다.${NC}"
exit 1
fi
fi
else
# SSH 키 생성
echo "새로운 SSH 키를 생성합니다..."
echo "이메일 주소를 입력해주세요:"
read -r email
ssh-keygen -t ed25519 -b 4096 -C "$email"
fi
# authorized_keys 설정
echo "authorized_keys 파일을 설정합니다..."
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
echo "${GREEN}SSH 키 설정이 완료되었습니다!${NC}"
.ssh
디렉토리가 없다면 생성생성된 비밀키는 앞서 살펴본 set-github-secrets.sh
스크립트를 통해 GitHub Secrets에 등록한다.