Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 스파르타내일배움캠프
- 개발자블로그
- 99일지
- java
- 컴퓨터구조론 5판
- 99클럽
- MySQL
- 부트캠프
- 내일배움캠프
- AWS
- 항해
- 스파르타내일배움캠프TIL
- 소프트웨어
- 컴퓨터개론
- 스파르타내일배움캠프WIL
- Flutter
- 중심사회
- Spring
- 스파르타코딩클럽
- wil
- Python
- 국비
- 프로그래머스
- 개인공부
- 코딩테스트
- 개발자스터디
- til
- 백준
- 운영체제
- 자바
Archives
- Today
- Total
컴공생의 발자취
EC2 분리하기: Front / Back / PostgreSQL / MongoDB / redis 본문
728x90
반응형
Keyword
- 서브 도메인
- docker-compose restart
- docker network
- docker exec -it
- psql
- mongosh
- redis
EC2 생성하기(공통)
EC2 인스턴스 생성
보안그룹:
- 기존의 보안 그룹에서 추가
- 프론트: 3000(그냥 나는 3000으로 하고 싶었음)
- 백엔드: 8080(기존 보안 그룹에 존재)
- DB - PostgreSQL : 5432
- MongoDB : 27017
- Redis : 6379
EC2 인스턴스 초기 세팅
시스템 업데이트 및 업그레이드:
sudo apt update -y
sudo apt upgrade -y
Docker 및 Docker Compose 설치:
- Docker 설치
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
- Docker Compose 설치
sudo apt install -y curl
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
- Docker 및 Docker Compose 설치 확인
docker --version
docker-compose --version
- EC2 재시작
서브 도메인에 생성한 EC2 연결
서브 도메인에 생성한 EC2의 private IP 연결
- ex) 서브도메인 : mongo.today-space.com
- ex) private IP : 172. -
프론트 분리하기
프론트 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_CONTAINER = 'front-today-space-container'
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 container down
sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker stop ${DOCKER_CONTAINER}"'
// docker container remove
sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker rm ${DOCKER_CONTAINER}"'
// 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!'
}
}
}
docker-compose 업데이트 및 생성
처음 만들었던 EC2(back + front + nginx + certbot)에서 수정
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"
nginx:
image: nginx:latest
container_name: today-space-nginx
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:
새로 만든 front EC2에서 docker-compose.yml 생성
version: '3.8'
services:
nginx:
image: ysy561356/today-space-front:latest
restart: unless-stopped
container_name: front-today-space-container
ports:
- "3000:3000"
volumes:
- ./data/nginx/app.conf:/etc/nginx/conf.d/default.conf
volumes:
db_data:
app.conf(nginx.conf) 업데이트 및 생성
처음 만들었던 EC2(back + front + nginx + certbot)에서 수정
server {
listen 80;
server_name today-space.com;
server_tokens off;
location /.well-known/acme-challenge/ {
allow all;
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name today-space.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/today-space.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/today-space.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass http://front.today-space.com;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
#root /usr/share/nginx/html;
#try_files $uri /index.html;
#index index.html index.htm;
}
location /v1 {
proxy_pass http://today-space.com:8080; # 혹은 다른 내부 네트워크 서비스로 설정
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
새로 만든 front EC2에서 ./data/nginx/app.conf 생성
server {
listen 3000;
server_name front.today-space.com;
server_tokens off;
location / {
root /usr/share/nginx/html;
try_files $uri /index.html;
index index.html;
}
}
백엔드 분리하기
백엔드 Jenkins Script 업데이트
pipeline {
agent any
environment {
// Docker Hub credentials
DOCKER_HUB_CREDENTIALS = 'docker-hub-credentials'
DOCKER_HUB_REPO = 'ysy561356/today-space-back'
DOCKER_CONTAINER = 'back-today-space-container'
// Github credentials
GIT_CREDENTIALS_ID = 'github-token'
GIT_BRANCH = 'release'
GIT_URL = 'https://github.com/today-space/today-space-back.git'
// EC2
SSH_CREDENTIALS_ID = 'ec2-ssh-key'
EC2_USER = 'ubuntu'
EC2_DOMAIN = 'back.today-space.com'
DOCKER_IMAGE_TAG = 'latest'
// DB
DB_URL = 'jdbc:postgresql://postgresql.today-space.com:5432/space'
DB_USERNAME = 'youngju'
DB_PASSWORD = '4564'
// JWT
JWT_SECRET_KEY = '7Iqk7YyM66W07YOA7L2U65Sp7YG065+9c3ByaW5n7Ius7ZmU7KO87LCo7JWE7JuD7IaM7Iux7ZSE66Gc7KCd7Yq47YyM7J2067iM66CI7KCE65Oc7YyAand0c2VjcmV0a2V5'
JWT_ACCESS_TOKEN_EXPIRATION = 1800000
JWT_REFRESH_TOKEN_EXPIRATION = 1209600000
// S3
BUCKET_NAME = 'today-space'
ACCESS_KEY_ID = 'AKIATCKAMVLZ5NQSKIEX'
SECRET_ACCESS_KEY = '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'
// Social Login
KAKAO_REST_API_KEY = '6cd61cbdb917a1046bf437980b1e2ac9'
NAVER_REST_API_KEY = 'mgvICujU1zvQrtz_IQOA'
NAVER_REST_API_SECRET_KEY = 'drUb2lRtGb'
GOOGLE_REST_API_KEY = '878062679505-oh34mk7fm5mpipprk9o139i8if40b3qf.apps.googleusercontent.com'
GOOGLE_REST_API_SECRET_KEY = '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'
}
stages {
stage('Clone Git Repository') {
steps {
script {
// GitHub 저장소에서 코드 클론
git credentialsId: "${GIT_CREDENTIALS_ID}", branch: "${GIT_BRANCH}", url: "${GIT_URL}"
// gradlew 파일에 실행 권한 부여
sh 'chmod +x gradlew'
// Gradle 빌드
sh './gradlew build'
// destination 디렉토리 생성
sh 'mkdir -p ../destination'
sh 'mkdir -p ../destination/build/libs'
// JAR 파일과 Dockerfile을 특정 경로로 이동
sh 'cp build/libs/*.jar ../destination/build/libs'
sh 'cp Dockerfile ../destination/'
}
}
}
stage('Prepare .env') {
steps {
script {
sh '''
touch ../destination/back.env
echo DB_URL=$DB_URL >> ../destination/back.env
echo DB_USERNAME=$DB_USERNAME >> ../destination/back.env
echo DB_PASSWORD=$DB_PASSWORD >> ../destination/back.env
echo JWT_SECRET_KEY=$JWT_SECRET_KEY >> ../destination/back.env
echo JWT_ACCESS_TOKEN_EXPIRATION=$JWT_ACCESS_TOKEN_EXPIRATION >> ../destination/back.env
echo JWT_REFRESH_TOKEN_EXPIRATION=$JWT_REFRESH_TOKEN_EXPIRATION >> ../destination/back.env
echo BUCKET_NAME=$BUCKET_NAME >> ../destination/back.env
echo ACCESS_KEY_ID=$ACCESS_KEY_ID >> ../destination/back.env
echo SECRET_ACCESS_KEY=$SECRET_ACCESS_KEY >> ../destination/back.env
echo KAKAO_REST_API_KEY=$KAKAO_REST_API_KEY >> ../destination/back.env
echo NAVER_REST_API_KEY=$NAVER_REST_API_KEY >> ../destination/back.env
echo NAVER_REST_API_SECRET_KEY=$NAVER_REST_API_SECRET_KEY >> ../destination/back.env
echo GOOGLE_REST_API_KEY=$GOOGLE_REST_API_KEY >> ../destination/back.env
echo GOOGLE_REST_API_SECRET_KEY=$GOOGLE_REST_API_SECRET_KEY >> ../destination/back.env
'''
}
}
}
stage('Build and Push Docker Image') {
steps {
script {
dir('../destination') { // 특정 경로로 이동
// Git 태그를 이용해 버전 설정
def gitTag = sh(returnStdout: true, script: 'git describe --tags --always').trim()
def dockerImage = docker.build("${DOCKER_HUB_REPO}:${gitTag}", "./")
// 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
dockerImage.push("${gitTag}")
dockerImage.push("latest") }
}
}
}
stage('Deploy') {
steps {
script {
withCredentials([sshUserPrivateKey(credentialsId: "${SSH_CREDENTIALS_ID}", keyFileVariable: 'SSH_KEY')]) {
def sshKey = env.SSH_KEY
// 권한 변경
sh 'chmod 400 ' + sshKey
// docker container down
sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker stop ${DOCKER_CONTAINER}"'
// docker container remove
sh 'ssh -v -o StrictHostKeyChecking=no -i ' + sshKey + ' ${EC2_USER}@${EC2_DOMAIN} "docker rm ${DOCKER_CONTAINER}"'
// 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!'
}
}
}
docker-compose 업데이트 및 생성
처음 만들었던 EC2(back + front + nginx + certbot)에서 수정
version: '3.8'
services:
nginx:
image: nginx:latest
container_name: today-space-nginx
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:
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:
새로 만든 back EC2에서 docker-compose.yml 생성
version: '3.8'
services:
nginx:
image: ysy561356/today-space-back:latest
restart: unless-stopped
container_name: back-today-space-container
env_file: ./config/back.env
ports:
- "8080:8080"
volumes:
db_data:
환경변수 파일 만들기
config 디렉토리 생성
- 젠킨스에서 만든 환경변수 파일을 위치시킬 디렉토리 생성
- 동작 확인을 위해서는 back.env 파일 직접 EC2에서 만들어서 실행시켜보기
DB 분리하기
docker-compose.yml 생성
version: '3.8'
services:
db:
image: postgres:14
container_name: postgres-today-space-container
env_file: ./config/postgres.env
volumes:
- ./db_data:/var/lib/postgresql/data
ports:
- "5432:5432"
volumes:
db_data:
환경변수 파일 만들기
config 디렉토리 생성 및 이동
postgres.env 파일 생성 및 작성:
POSTGRES_DB=space
POSTGRES_USER=youngju
POSTGRES_PASSWORD=4564
MongoDB 추가하기
docker-compose.yml 생성
version: '3.8'
services:
mongo:
image: mongo:latest
restart: unless-stopped
container_name: mongo-today-space-container
env_file: ./config/mongo.env
ports:
- "27017:27017"
volumes:
db_data:
환경변수 파일 만들기
config 디렉토리 생성 및 이동
postgres.env 파일 생성 및 작성:
MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=todayspace4321!
back - Jenkins 환경변수 추가
// enviroment
MONGO_DB_URI = 'mongodb://root:todayspace4321!@mongo.today-space.com:27017/today_space?authSource=admin&authMechanism=SCRAM-SHA-1'
// mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=writeapp&w=1;
// Prepare .env
echo MONGO_DB_URI=$MONGO_DB_URI >> ../destination/back.env
컬렉션 추가하기
mongosh 들어가기:
docker exec -it [mongodb 컨테이너명] mongosh
// ex: docker exec -it mongo-today-space-container mongosh
admin으로 변경:
use admin
유저 추가:
db.auth(”root”, “todayspace4321!”)
컬렉션 추가:
db.createCollection("myNewCollection")
db.myNewCollection.insertOne({ name: "example", value: 123 })
// 값을 하나 추가해야 컬렉션 생성을 확인할 수 있음
Redis 추가하기
docker-compose.yml 생성
version: '3.8'
services:
redis:
image: redis
container_name: redis-today_space_container
ports:
- "6379:6379"
command: redis-server --requirepass todayspace4321!
restart: unless-stopped
volumes:
db_data:
back - Jenkins 환경변수 추가
// enviroment
REDIS_DB_URL = 'redis://default:todayspace4321!@redis.todayspace.com:6379'
// Prepare .env
echo REDIS_DB_URL=$REDIS_DB_URL >> ../destination/back.env
참고 자료
- docker network
728x90
반응형
'🧡 AWS' 카테고리의 다른 글
AWS ECS로 컨테이너 관리하기: NLB와 Auto Scaling (feat. DockerHub) (4) | 2024.11.05 |
---|---|
AWS 아키텍처 설계 전략 (feat. Auto Scaling, ECS) (2) | 2024.10.22 |
AWS S3 보안 설정 및 정책 관리 (feat. IAM) (2) | 2024.10.14 |
AWS EC2에 HTTPS 적용하기 (feat. Nginx, Certbot) (0) | 2024.10.04 |
ECS 컨테이너 시작 실패 (feat.troubleshooting) (0) | 2024.09.25 |