🐳 Docker
Docker를 활용한 React 프로젝트 배포 (feat. Nginx, Jenkins)
MNY
2024. 10. 15. 15:59
728x90
반응형
Keyword
- docker
- dockerfile
- compose(app, db, nginx)
- nginx(react deploy)
- nginx(reverse proxy)
Dockerfile 만들기
프로젝트 디렉토리 구조
: 프로젝트의 루트 디렉토리에 위치
today-space-front/
├── package-lock.json
├── package.json
├── public
├── src/
│ └── main/
│ ├── component
│ ├── pages
│ └── redux
└── Dockerfile
Dockerfile 만들기
: 검색 keyword → react Dockerfile
# 1. Node.js 환경에서 빌드 수행
FROM node:14 AS build
WORKDIR /app
# package.json과 package-lock.json 복사
COPY package*.json ./
# 종속성 설치
RUN npm install
# 애플리케이션 소스 코드 복사
COPY . .
# 애플리케이션 빌드
RUN npm run build
# 2. Nginx 이미지에 빌드 결과물 포함
FROM nginx:alpine
# 빌드 결과물 복사
COPY --from=build /app/build /usr/share/nginx/html
# Nginx 실행
CMD ["nginx", "-g", "daemon off;"]
프로젝트 빌드 및 이미지 푸시
// 1. Docker image build
docker build -t [docker account ID]/[project name] .
ex) docker build -t ysy561356/today-space-front .
// -t, --tag: 빌드된 이미지에 태그를 지정. 이미지이름:태그 형식으로 사용.
// 2. Docker image push
docker push [docker account ID]/[project name]
ex) docker push ysy561356/today-space-front
/*
denied: requested access to the resource is denied 발생
참고 자료: https://nirsa.tistory.com/53
*/
1. 인텔리제이에서 터미널 열고 프로젝트 빌드(window & mac)
2 & 3. Dockerhub 확인
프로젝트(Docker image) 업로드
* 해당 과정은 EC2 인스턴스에서 진행
Docker image pull
Docker image pull:
docker pull [docker account ID]/[project name]:tag
ex) docker pull ysy561356/today-space-front:latest
// tag를 따로 지정하지 않았다면 기본적으로 latest
Docker image 확인:
docker images
docker-compose 업데이트
* 해당 과정은 EC2 인스턴스에서 진행
docker-compose 업데이트
docker-compose 업데이트:
vi docker-compose.yml // app.conf 파일 작성하기
i // 작성 모드
// docker-compose.yml 파일 내용
version: '3.8'
services:
back:
image: today-space-back:latest
container_name: today-space-back
env_file:
- ./config/.env
ports:
- "8080:8080"
depends_on:
- db
db:
image: postgres:14
container_name: today-space-db
env_file:
- ./config/.env
volumes:
- db_data:/var/lib/postgresql/data
ports:
- "5432:5432"
front:
image: today-space-front:latest
container_name: today-space-front
ports:
- "80:80"
- "443:443"
volumes:
- ./data/nginx/app.conf:/etc/nginx/conf.d/default.conf
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
depends_on:
- back
certbot:
image: certbot/certbot
restart: unless-stopped
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
volumes:
db_data:
------------------------------------------------------------------------------------
ESC(버튼) + :wq // 작성 모드 종료 후 저장하고 나가기
w // 저장
q // 나가기
프론트 Jenkins(CI/CD )
프론트용 Jenkins pipeline 생성
- Jenkins 세팅 참고
2024.10.11 - [🐳 Docker] - EC2의 Docker 안에 Jenkins Container 올리기 (feat. Webhook CI/CD 구축 & DooD)
EC2의 Docker 안에 Jenkins Container 올리기 (feat. Webhook CI/CD 구축 & DooD)
Keyword1. DooD2. docker network Flow1. 새로운 EC2 인스턴스 생성 -> 젠킨스만2. docker 설치3. docker 컨테이너 젠킨스 실행4. 서브 도메인 세팅5. 젠킨스 Webhook 연결6. 파이프라인 작성 후 배포 확인 EC2 인스
moonnight0.tistory.com
Jenkins Script 작성
pipeline {
agent any
environment {
// GitHub credentials
GIT_CREDENTIALS_ID = 'github-token'
GIT_URL = 'https://github.com/today-space/today-space-front.git'
GIT_BRANCH = 'release'
// EC2
SSH_CREDENTIALS_ID = 'ec2-ssh-key'
EC2_USER = 'ubuntu'
EC2_DOMAIN = 'front.today-space.com'
// Docker Hub credentials
DOCKER_HUB_CREDENTIALS = 'docker-hub-credentials'
DOCKER_HUB_REPO = 'ysy561356/today-space-front'
DOCKER_IMAGE_TAG = 'latest'
REACT_APP_API_URL='https://today-space.com'
REACT_APP_KAKAO_AUTH_URL='https://kauth.kakao.com/oauth/authorize'
REACT_APP_KAKAO_REST_API_KEY='6cd61cbdb917a1046bf437980b1e2ac9'
REACT_APP_KAKAO_REDIRECT_URL='https://today-space.com/oauth/kakao'
REACT_APP_NAVER_AUTH_URL='https://nid.naver.com/oauth2.0/authorize'
REACT_APP_NAVER_REST_API_KEY='mgvICujU1zvQrtz_IQOA'
REACT_APP_NAVER_REDIRECT_URL='https://today-space.com/oauth/naver'
REACT_APP_NAVER_STATE='reactNaverSocialState'
REACT_APP_GOOGLE_AUTH_URL='https://accounts.google.com/o/oauth2/v2/auth'
REACT_APP_GOOGLE_REST_API_KEY='878062679505-oh34mk7fm5mpipprk9o139i8if40b3qf.apps.googleusercontent.com'
REACT_APP_GOOGLE_REDIRECT_URL='https://today-space.com/oauth/google'
}
stages {
stage('Clone Repository') {
steps {
script {
// GitHub 저장소에서 코드 클론
git credentialsId: "${GIT_CREDENTIALS_ID}", branch: "${GIT_BRANCH}", url: "${GIT_URL}"
}
}
}
stage('Prepare .env') {
steps {
script {
sh """
touch .env
echo REACT_APP_API_URL=${REACT_APP_API_URL} >> .env
echo REACT_APP_KAKAO_AUTH_URL=${REACT_APP_KAKAO_AUTH_URL} >> .env
echo REACT_APP_KAKAO_REST_API_KEY=${REACT_APP_KAKAO_REST_API_KEY} >> .env
echo REACT_APP_KAKAO_REDIRECT_URL=${REACT_APP_KAKAO_REDIRECT_URL} >> .env
echo REACT_APP_NAVER_AUTH_URL=${REACT_APP_NAVER_AUTH_URL} >> .env
echo REACT_APP_NAVER_REST_API_KEY=${REACT_APP_NAVER_REST_API_KEY} >> .env
echo REACT_APP_NAVER_REDIRECT_URL=${REACT_APP_NAVER_REDIRECT_URL} >> .env
echo REACT_APP_NAVER_STATE=${REACT_APP_NAVER_STATE} >> .env
echo REACT_APP_GOOGLE_AUTH_URL=${REACT_APP_GOOGLE_AUTH_URL} >> .env
echo REACT_APP_GOOGLE_REST_API_KEY=${REACT_APP_GOOGLE_REST_API_KEY} >> .env
echo REACT_APP_GOOGLE_REDIRECT_URL=${REACT_APP_GOOGLE_REDIRECT_URL} >> .env
"""
}
}
}
stage('Build') {
steps {
script {
// Docker 이미지 생성
sh 'docker build -t ${DOCKER_HUB_REPO}:${DOCKER_IMAGE_TAG} .'
}
}
}
stage('Push Docker Image to Docker Hub') {
steps {
script {
// Docker Hub에 로그인
withCredentials([usernamePassword(credentialsId: DOCKER_HUB_CREDENTIALS, usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) {
sh 'echo $DOCKER_PASSWORD | docker login -u $DOCKER_USERNAME --password-stdin'
}
// Docker 이미지 push
sh "docker push ${DOCKER_HUB_REPO}:${DOCKER_IMAGE_TAG}"
}
}
}
stage('Deploy') {
steps {
script {
withCredentials([sshUserPrivateKey(credentialsId: "${SSH_CREDENTIALS_ID}", keyFileVariable: 'SSH_KEY')]) {
def sshKey = env.SSH_KEY
// 권한 변경
sh 'chmod 400 ' + sshKey
// docker-compose down
sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker-compose down"'
// docker image pull
sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker pull ${DOCKER_HUB_REPO}:${DOCKER_IMAGE_TAG}"' // 이미지 명시
// 새로운 docker-compose 시작
sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker-compose up -d"'
}
}
}
}
}
post {
always {
cleanWs()
}
success {
echo 'Deployment successful!'
}
failure {
echo 'Deployment failed!'
}
}
}
728x90
반응형