SpringBoot | MariaDB | Spring Data JPA | Jenkins | Kubernetes | Docker | ngrok |
---|---|---|---|---|---|---|
Python | JavaScript | Vue | HTML | CSS |
---|---|---|---|---|
IntelliJ IDEA | Visual Studio Code | HeidiSQL | Visily | Miro | Github | AWS S3 |
---|---|---|---|---|---|---|
- ํ ์ํฉ:
๋ง๋์๋ฅผ ์ํ ์ํ ์ปค๋ฎค๋ํฐ์ ๋ถ์ฌ.
๋ํ ํ๋ซํผ์ ์ํ ์นดํ๋ ๋๋ถ๋ถ ํ์๋์๊ณ , ๊ธฐ์กด ์ฌ์ดํธ๋ค์ ํ๋ฉด์ด ๋ณต์กํ๊ณ ๋ค์ํ ์ฃผ์ ๋ฅผ ์์ฐ๋ฅด๊ณ ์์ด ์ํ๋ง์ ์ ๋ฌธ์ผ๋ก ๋ค๋ฃจ๋ ๊ณต๊ฐ์ด ํ์. - ํ์์ฑ:
์ํ ๋ง๋์๋ค์ด ์์ ์ ์ํ ์ทจํฅ์ ๊ณต์ ํ๊ณ , ์ฌ๋ ๊น์ ํ ๋ก ์ ํ ์ ์๋ ์ ๋ฌธ ์ปค๋ฎค๋ํฐ์ ํ์์ฑ์ด ๋๋๋จ.
- ์ ๋ฌธ์ฑ๊ณผ ํธ์ํจ:
์ํ๋ง์ ์ ๋ฌธ์ผ๋ก ๋ค๋ฃจ๋ ์ปค๋ฎค๋ํฐ ์ ๊ณต์ผ๋ก ์ฌ์ฉ์๋ค์ด ๋ณด๋ค ์ฝ๊ฒ ์ ๋ณด๋ฅผ ์ป๊ณ ๊ณต์ ํ ์ ์๋ ํ๋ซํผ ๋ง๋ จ. - ์์ ํ ์ด์ฉ ํ๊ฒฝ:
์๋ฒ์ ์ํํ ์ ๋ณด๋ฅผ ์ ์ฅํ์ง ์๊ณ , ์ด์ฉ์์ ๊ฐ์ธ์ ๋ณด ๋ณดํธ๋ฅผ ์ต์ฐ์ ์ผ๋ก ํจ(์: ์ฟ ํค์ ํ์๋ค์ ๊ฐ์ธ์ ๋ณด๋ฅผ ๋ด์ง ์์). - ํ๋ฐํ ์ํต ๊ณต๊ฐ:
์ฌ์ฉ์๋ค์ด ์์ ๋กญ๊ฒ ์ ๋ณด๋ฅผ ๊ณต์ ํ๊ณ , ์ํ์ ๋ํ ๋ฆฌ๋ทฐ๋ ๋นํ์ ์์ ๋กญ๊ฒ ํํํ ์ ์๋ ์คํํ ์ปค๋ฎค๋ํฐ.
- ํฌ์ธํธ ์์คํ
:
์ํ ํด์ฆ ์ฐธ์ฌ๋ฅผ ํตํด ํฌ์ธํธ๋ฅผ ํ๋ํ๊ณ , ์ด ํฌ์ธํธ๋ฅผ ์ฌ์ฉํ์ฌ ๋ค์ํ ๋ฑ์ง(์: ๋ง๋ธ, DC ์ฝ๋ฏน์ค ๋ฑ์ง)๋ฅผ ๊ตฌ๋งคํ ์ ์์. - ๋ฑ์ง ํ์ฉ:
๊ตฌ๋งคํ ๋ฑ์ง๋ ์ฌ์ฉ์์ ํ๋กํ ๋๋ ๋๋ค์ ์์ ํ์๋์ด, ์ฌ์ฉ์์ ๊ด์ฌ์ฌ์ ์ ๋ฌธ์ฑ์ ๋ํ๋ผ ์ ์์. ์ด๋ ์ฌ์ฉ์๊ฐ์ ์์๊ฐ์ ํ์ฑํ๊ณ , ์ปค๋ฎค๋ํฐ ๋ด์์์ ์ ๋ขฐ๋๋ฅผ ์ฆ๊ฐ์ํค๋ ์ญํ ์ ํจ.
- ์ ๋ฌธํ๋ ํ๋ซํผ:
์ํ๋ง์ ์ฃผ์ ๋ก ํ๋ ์ ๋ฌธํ๋ ์ปค๋ฎค๋ํฐ๋ก์์ ์๋ฆฌ๋งค๊น. - ์ฌ์ฉ์ ์ฐธ์ฌ ์ ๋:
ํฌ์ธํธ ๋ฐ ๋ฑ์ง ์์คํ ์ ํตํ ๊ฒ์ํ ์์๋ ์ฌ์ฉ์์ ์ง์์ ์ธ ์ฐธ์ฌ๋ฅผ ์ ๋. - ์ปค๋ฎค๋ํฐ ํ์ฑํ:
ํน์ ์ฃผ์ ์ ์ง์คํจ์ผ๋ก์จ ์ฌ์ฉ์๊ฐ์ ๋ ๊น์ ์ฐ๊ฒฐ๊ณผ ์ํธ ์์ฉ์ ์ด์ง.
์ด๋ฌํ ์ฌ์ดํธ๋ ์ํ ๋ง๋์๋ค์๊ฒ ๋ง์ถคํ๋ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ฉฐ, ์์ ํ๊ณ ํธ์ํ ํ๊ฒฝ์์ ์ํ์ ๋ํ ์ด์ ์ ๊ณต์ ํ ์ ์๋ ์ต์ ์ ๊ณต๊ฐ์ด ๋ ๊ฒ์ ๋๋ค.
์์ธ๋ณด๊ธฐ
์ด ํ๋ก์ ํธ๋ฅผ ์์ํ๊ธฐ ์ ์ ๋ค์ ์ํํธ์จ์ด์ ๋๊ตฌ๊ฐ ์ค์น๋์ด ์์ด์ผ ํฉ๋๋ค.
- IntelliJ: JDK 17 ์ค์น ํ์
- Docker: ๋ฒ์ 4.28
- Jenkins: ๋ฒ์ 2.452
- Kubernetes: ๋ฒ์ 1.92.2
- Ngrok
- Webhook: GitHub์ ์ฐ๋ ์ค์
์์ ํ ๊ฐ๋ฐ์ ์ํด ๋ค์ ํฌ๋ฆฌ๋ด์ ์ ์ค์ ํฉ๋๋ค.
- MY-GITHUB-KEY: RSA ํค
- DOCKERHUB-PASSWORD: Docker Hub ์ ๋ก๋๋ฅผ ์ํ ๊ณ์ ์ ๋ณด
- SECRET-ID: GitHub์ ์
๋ก๋๋๋ฉด ์ ๋๋
application.yml
- ๋ณ๊ฒฝ์ฌํญ ๊ฐ์ง ํ Jenkins๊ฐ ์๋์ผ๋ก ๋น๋๋ฅผ ์์ํฉ๋๋ค.
- Jenkins๊ฐ Webhook์ ํตํด ๋ณ๊ฒฝ๋ ์์ค ์ฝ๋๋ฅผ ๊ฐ์งํ๊ณ , SSH์ ์ฌ์ฉ๋ RSA ํค๋ฅผ ์์ฑํฉ๋๋ค.
- Jenkins Tools์์
Java (OpenJDK 17)
๋ฐGradle (ver 8.7)
์ค์
Publish Over SSH
๋ฐPipeline: Stage View
์ค์น
pipeline {
agent any
tools {
gradle 'gradle'
jdk 'openJDK17'
}
environment {
DOCKERHUB_USERNAME = 'angelajsb'
GITHUB_URL = 'https://github.com/beyond-sw-camp/be04-4th-6team-CINE-VERSE-CICD.git'
}
stages {
stage('Preparation') {
steps {
script {
sh 'docker --version' // Docker๊ฐ ์ค์น๋์ด ์๋์ง ํ์ธ
}
}
}
stage('Source Build') {
steps {
git branch: 'main', url: 'https://github.com/beyond-sw-camp/be04-4th-6team-CINE-VERSE-CICD.git'
withCredentials([file(credentialsId: 'secret-id', variable: 'applicationYml')]) {
script {
if (fileExists('src/main/resources/application.yml')) {
sh 'rm src/main/resources/application.yml' // ํ์ผ์ด ์กด์ฌํ๋ฉด ์ญ์
}
sh "cp $applicationYml src/main/resources/application.yml"
}
}
sh "chmod +x ./gradlew"
sh "./gradlew clean build"
}
}
stage('Container Build') {
steps {
sh "cp ./build/libs/*.jar ."
sh "docker build -t ${DOCKERHUB_USERNAME}/cine-verse:latest ."
withCredentials([usernamePassword(credentialsId: 'DOCKERHUB_PASSWORD', usernameVariable: 'DOCKERHUB_USER', passwordVariable: 'DOCKERHUB_PASS')]) {
sh "echo $DOCKERHUB_PASS | docker login --username $DOCKERHUB_USER --password-stdin"
sh "docker push ${DOCKERHUB_USERNAME}/cine-verse:latest"
}
}
}
}
}
- ๋ณ๊ฒฝ ์ฝ๋ GitHub์ ์ ๋ก๋
- Webhook ํตํด ๋ณํ ๊ฐ์ง
- ๊ฐ์ง๋ ์ฝ๋๋ฅผ SSH๋ฅผ ํตํด ๋ณด์ ์ํ๋ก Jenkins์์ ํด๋ก
- ์ฌ์ ์ Credential์ ๋ฑ๋กํ
application.yml
์ Pipeline ์คํฌ๋ฆฝํธ์ ์์ฑ๋ Groovy ๋ฌธ๋ฒ์ ํตํด ๋ค์ด๋ก๋ - ๋น๋ ๋ฐ ํ ์คํธ ์คํ(์๋ํ ๊ณผ์ )
- ๋น๋๋ JAR ํ์ผ์ ํตํด ์ด๋ฏธ์ง ์์ฑ ํ Docker Hub์ ํธ์
apiVersion: apps/v1
kind: Deployment
metadata:
name: boot002dep
spec:
selector:
matchLabels:
app: boot002kube
replicas: 3
template:
metadata:
labels:
app: boot002kube
spec:
containers:
- name: boot-container
image: angelajsb/cine-verse:latest # DockerHub์ ํธ์ฌ๋ ๊ฐ์ฅ ์ต๊ทผ image ์ฌ์ฉ
imagePullPolicy: Always
ports:
- containerPort: 8081 # ํ์ฌ boot project ํฌํธ๋ฒํธ
apiVersion: v1
kind: Service
metadata:
name: boot002ser
spec:
type: NodePort
ports:
- port: 8081 # container ๋ด๋ถ ํต์ ํฌํธ๋ฒํธ
targetPort: 8081 # ํ์ฌ service ์ค์ธ ํฌํธ๋ฒํธ
protocol: TCP
nodePort: 30007 # ์ธ๋ถ ์ ์ ํฌํธ๋ฒํธ
selector:
app: boot002kube
- deployment.yml -> pod๋ฅผ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ ์ ๋ณด ์ ์
- replicas -> ์ค์ ํ ๊ฐฏ์์ ๋ฐ๋ผ pod instance ์ ์ง, ๊ณผ๋ถํ๊ฐ ๊ฑธ๋ฆฌ๊ฑฐ๋ ์คํจํ pod๋ฅผ ์๋ ์ฌ์์ ํด ํญ์ n๊ฐ์ pods ์ ์ง
- service.yml -> pod์ ๋ํ ๋จ์ผ ์ ์ ์ ๊ณต ๋ฐ ๋ด๋ถ์ ์ผ๋ก ๋ก๋ ๋ฐธ๋ฐ์ฑ ์ํ
- deployment.yml ๋ฐ service.yml ์ ์ฉ kubectl apply -f boot002dep.yml kubectl apply -f boot002ser.yml
- ์์ค์ฝ๋ ๋ณ๊ฒฝ ์ Kubernetes ์ฌ์์ kubectl rollout restart deployment/boot002dep
-
์ ์ ์กฐ๊ฑด ๋ฐ ์ค์น ํ๊ฒฝ
- VS CODE ์ค์น
- VUE3 ์ค์น
- Docker Desktop ์ค์น
-
vue project ๊ฒฝ๋ก ํฐ๋ฏธ๋์์ ํด๋น project image ์์ฑ
docker build -t angelajsb/cine-verse-front .
- DockerHub์ ํด๋น image ํธ์ฌ
docker push angelajsb/cine-verse-front
-
deployment.yml ์์ฑ
-
service.yml ์์ฑ
-
deployment.yml ๋ฐ service.yml ์ ์ฉ (๋ช ๋ น์ด ์ ๋ ฅ)
kubectl apply -f vue002dep.yml
kubectl apply -f vue002ser.yml
- ์์ค์ฝ๋ ๋ณ๊ฒฝ ์ ์ด๋ฏธ์ง ์ฌ์์ฑ ํ DockerHub ํธ์ฌ
docker build -t angelajsb/cine-verse-front:latest .
docker push angelajsb/cine-verse-front:latest
- Kubernetes ์ฌ์์
kubectl rollout restart deployment/vue002dep
Python์ ์ฌ์ฉํ์ฌ requests์ BeautifulSoup ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก CGV์์ ์ํ ๋ฐ์ดํฐ(์ค์๊ฐ ์ธ๊ธฐ ์ํ ์์ 10)๋ฅผ ํฌ๋กค๋งํ๊ณ json์ผ๋ก ์ ์ฅ ๋ฉ์ธ ํ๋ฉด์ ๋ค์ด๊ฐ๋ฉด ์ฌ์ฉ์๋ ์ค์๊ฐ ์ํ ์ ๋ณด๋ฅผ ํตํด ์ต์ ํธ๋ ๋๋ฅผ ํ์ ๊ฐ๋ฅ
์ค์์ฝ๋
url = 'http://www.cgv.co.kr/movies/'
res = requests.get(url)
soup = BeautifulSoup(res.text, 'html.parser')
JavaScript๋ฅผ ์ฌ์ฉํ์ฌ OpenAI์ API๋ก๋ถํฐ ์ฑ๋ด์ ์๋ต์ ๋ฐ์ ์ฒ๋ฆฌํ๋ ๊ธฐ๋ฅ ๊ตฌํ api ํค๋ .env ํ๊ฒฝ๋ณ์ ์ฒ๋ฆฌ๋ฅผ ํตํด ์ธ๋ถ์ ๋ ธ์ถ๋์ง ์๋๋ก ๋ณด์ ์ฒ๋ฆฌ ์ํ ์ถ์ฒ ๋ฑ ๋ค์ํ ์ฃผ์ ์ ๋ํ ๋น ๋ฅด๊ณ ํจ์จ์ ์ธ ๋ํ ๊ฐ๋ฅ https://platform.openai.com/usage์์ API request ์กฐํ ๊ฐ๋ฅ
์ค์์ฝ๋
async function sendMessage() {
const message = userMessage.value.trim();
if (message.length === 0) return;
Java์ Spring Boot๋ฅผ ์ฌ์ฉํ์ฌ AWS S3์ ์ด๋ฏธ์ง ํ์ผ์ ์ ๋ก๋ํ๊ณ ๊ด๋ฆฌํ๋ ๊ธฐ๋ฅ ๊ตฌํ ์์ ์ ์ธ AWS S3๋ฅผ ์ฌ์ฉํจ์ผ๋ก์จ ๋์ฉ๋ ์ด๋ฏธ์ง ์ ์ฅ ๋ฐ ๊ด๋ฆฌ ์ฉ์ดํ๊ณ , ๋ฐ์ดํฐ ๋ณด์ ๊ฐํ
์ค์์ฝ๋
@Bean
public AmazonS3Client amazonS3Client() {
BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
return (AmazonS3Client) AmazonS3ClientBuilder.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(region)
.build();
}
try {
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(multipartFile.getContentType());
objectMetadata.setContentLength(multipartFile.getInputStream().available());
amazonS3Client.putObject(bucketName, storedName, multipartFile.getInputStream(), objectMetadata);
String accessUrl = amazonS3Client.getUrl(bucketName, storedName).toString();
image.setAccessUrl(accessUrl);
imageRepository.save(image);
}
SMTP๋ฅผ ํตํด ์ฌ์ฉ์์ ์ด๋ฉ์ผ๋ก ๋น๋ฐ๋ฒํธ ์ฌ์ค์ ์ธ์ฆ์ฉ ๋์๋ฅผ ๋ณด๋ด๊ณ ๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ ๊ธฐ๋ฅ ๊ตฌํ ์ด๋ฉ์ผ์ ํตํด ์ฌ์ฉ์๊ฐ ์์ ํ๊ฒ ์์ ์ ๊ณ์ ์ ๊ด๋ฆฌํ ์ ์์ผ๋ฉฐ, ์๋น์ค์ ๋ํ ์ ๋ขฐ์ฑ์ด ํฅ์
์ค์์ฝ๋
public EmailMessage sendMail(EmailMessage emailMessage) {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8");
String newPwd = createRandom();
mimeMessageHelper.setTo(emailMessage.getTo());
mimeMessageHelper.setSubject("๋น๋ฐ๋ฒํธ ์ฌ์ค์ ");
mimeMessageHelper.setText("์ฌ์ค์ ๋ ๋น๋ฐ๋ฒํธ: " + newPwd);
mimeMessageHelper.setFrom(new InternetAddress(from));
javaMailSender.send(mimeMessage);
memberService.changePwd(newPwd, emailMessage.getTo());
emailMessage.setMessage("์ฌ์ค์ ๋ ๋น๋ฐ๋ฒํธ: " + newPwd);
emailMessage.setSubject("๋น๋ฐ๋ฒํธ ์ฌ์ค์ ");
return emailMessage;
} catch (MessagingException e) {
throw new RuntimeException(e);
}
}
1๏ธโฃ ๋ฉ์ธํ์ด์ง etc
3๏ธโฃ ํ์ etc
5๏ธโฃ ์ ๋ณด ๊ฒ์ํ etc
6๏ธโฃ ์์ ๊ฒ์ํ etc
7๏ธโฃ ์ด๋ฒคํธ ๊ฒ์ํ etc
- ์ด๋ฒคํธ ๊ฒ์ํ ํฌํ ๊ตฌํ
- spring security ์ ์ฉ
- redis๋ฅผ ํตํ ์ด๋ฉ์ผ ์ธ์ฆ
- ๋๊ธ ์ด๋ชจํฐ์ฝ ๊ตฌํ
- ์คํฌ์ผ๋ฌ ๋ฐฉ์ง ๊ตฌํ
- ๊ฒ์๊ธ ์์ (ํ๋ก ํธ)
- ํ์์ ๊ณ
- qna
์ด๋ฆ | ๋ด์ฉ |
---|---|
์ก๋์ค | ์ด๋ฒ ํ๋ก์ ํธ์์ ์ง๊ธ๊น์ง ๋ฐฐ์ ๋ ์ง์๋ค์ ๋ฐํ์ผ๋ก DDD๋ก ๊ฒ์ํ ์๋น์ค ๊ตฌ์กฐ ๋ฑ์ ๊ธฐํํ๊ณ DB ๋ชจ๋ธ๋ง ์์ด์ด ํ๋ ์ ๋ฑ์ผ๋ก ๋ฐ์ดํฐ ๋ฒ ์ด์ค ๊ตฌ์กฐ ์ธํฐํ์ด์ค ๋์์ธ์ ์ค๊ณํ ํ ๋ฐฑ ์ค๋์์ ๋น์ฆ๋์ค ๋ก์ง์ ๊ตฌํํ๋ฉด ํ๋ฐํธ์๋์์ ์ฌ์ฉ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ ๋ค CI/CD๋ก ๋ฐฐํฌ๊น์ง ํ๋ ๊ณผ์ ์ ์ํํ์๋ค ์ฒ์๋ถํฐ ๋๊น์ง ์งง์ ์๊ฐ ๋ด์ ๊ฒ์๋ฌผ์ ๊ตฌํํด์ผ ํ๊ธฐ์ ์๊ฐ์ ๋ถ๋ด๊ฐ๋ ์์์ผ๋ ์ค๋๋ผ์ ์ต์์ง ์์ ๋ถ๋ถ์ ๋ณต์ตํ ์ ์์ด ๊ท์คํ ๊ฒฝํ์ด ๋์๋ค ์ด๋ฒ ํ๋ก์ ํธ๋ฅผ ํ๋ฉด์ ๋ง์ด ๋ถ์กฑํจ์ ๋๊ผ์ผ๋ ๋ ์ํ ์ ์๋ค๋ ์์ ๊ฐ์ด ์๊ธฐ๊ณ ๋ง์ ๊ฒ์ ์ป์ด ๊ฐ ํ๋ก์ ํธ์๋ค ๋ค์ ํ๋ก์ ํธ๋ ๋ถ์กฑํ ๋ถ๋ถ์ ๋ณด์ํ๊ณ ๋ฐฑ์๋์ ํ๋ฐํธ์๋์ ์ํํ ์์ฌ์ํต์ ํตํด ๋ ํจ์จ์ ์ด๊ณ ์ ํํ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค์ด์ผ๊ฒ ๋ค. |
์์งํ | ์ฌ์ฉ์ ์ค์ฌ ์ค๊ณ(UCD)์ ์ค์์ฑ์ ๊ณ ๋ คํ๋ฉด์, ์ฌ์ฉ์์ ๋ง์กฑ์ ์ฐ์ ์ผ๋ก ์๊ฐํ๋ ์๋น์ค ๊ฐ๋ฐ์ ํ์์ฑ์ ๋์ฑ ๊น์ด ์ดํดํ๊ฒ ๋์์ต๋๋ค. ๊ธฐํ - ์์ด์ดํ๋ ์ - ํ๋ก ํธ์๋ ๋จ๊ณ๋ฅผ ๊ฑฐ์น๋ฉฐ ์ฌ๋ฌ ํ ์คํธ๋ฅผ ํด๋ณธ ๊ฒฐ๊ณผ ์ฌ์ฉ์ ๊ฒฝํ ๋ฐ์ดํฐ๊ฐ ์์ด๊ณ , ์ฌ์ฉ์์ ํธ์๋ฅผ ๊ณ ๋ คํ์ฌ ๊ธฐํ ๋ฐ ๊ตฌ์ํ๋ ๋จ๊ณ๊ฐ ์ฆ๊ฒ๊ฒ ๋ค๊ฐ์์ต๋๋ค. ์งง์ ๊ธฐ๊ฐ ๋์ ๋ง์ ์์ ์ ํด์ผ ํ๋ ์ด๋ฒ ํ๋ก์ ํธ์์ ํ์๋ค๊ณผ ๋งค์ผ ์งํํ ๊ฐ๋ฐ ์ง์ฒ๋ ์ฒดํฌ๋ฅผ ํตํด ํ๋ก์ ํธ์ ์ผ์ ์ ๊ด๋ฆฌํ๊ณ , ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ฆ์ ํด๊ฒฐ์ฑ ์ ๋ชจ์ํ์ต๋๋ค. ์ด ํ๋ก์ ํธ๋ฅผ ํตํด ์ป์ ๋ค์ํ ํผ๋๋ฐฑ ๊ฒฝํ์ ์์ผ๋ก ๋ค๋ฅธ ์๋น์ค๋ฅผ ๊ธฐํํ๊ณ ๊ฐ๋ฐํ ๋ ํฐ ๋์์ด ๋ ๊ฒ์ ๋๋ค. ๋ํ, ์ฒ์์ผ๋ก ํ๋ฐํธ์ ๋ฐฑ์๋์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ ๋ฐ์ดํฐ๋ฅผ ๋ค์ํ ๋ฐฉ๋ฒ์ผ๋ก ์ฒ๋ฆฌํ์๊ณ , ํ๋ฐํธ์ ๋ ์ด์์ ๋ฐ ๋ฐ์ํ ์ฒ๋ฆฌ์ ์ฑ๊ณตํ์ ๋ ๋๊ตฌ๋ณด๋ค ๋ฟ๋ฏํจ์ ๋๊ผ์ต๋๋ค. ์์ผ๋ก๋ ์ฌ์ฉ์์ ํธ์์ฑ์ ๊ณ ๋ คํ์ฌ ์ข ๋ ์ฑ์คํ๊ฒ ์๋น์ค๋ฅผ ๊ธฐํ ๋ฐ ๊ตฌํํ๊ณ ์ถ์ต๋๋ค. |
์ค์ฌ์ | ์ด๋ฒ ํ๋ก์ ํธ์์ ์ ํฌ ํ์ ์ฃผ๋ ๋ชฉํ๋ ๋ฐฑ์๋ ์๋ฒ๋ฅผ ๊ตฌ์ถํ ํ Jenkins, Kubernetes, ๊ทธ๋ฆฌ๊ณ Ngrok์ ์ด์ฉํด CI/CD ํ๊ฒฝ์ ์กฐ์ฑํ์ฌ ์๋์ ์ธ ๋น๋์ ๋ฐฐํฌ๊ฐ ์ด๋ฃจ์ด์ง๊ฒ ํ๋ ๊ฒ์ด์์ต๋๋ค. ๊ฐ์ธ์ ์ผ๋ก๋ ์ด์ ํ๋ก์ ํธ์์ ์๋ํ์ง ๋ชปํ๋ S3 ๋ฒํท์ ํตํ ํ์ผ ์
๋ก๋์ ๋ฐฑ์๋ ์๋ฒ์ ํ๋ก ํธ ์๋ฒ ๊ฐ์ ํต์ ์ ๊ตฌํํ๋ ๊ฒ์ด ๋ชฉํ์์ต๋๋ค. ํ๋ก์ ํธ ๊ธฐ๊ฐ ๋์ ๋งค์ผ ์์นจ ์คํฌ๋ผ ํ์๋ฅผ ํตํด ํ์๋ค๊ณผ ๊ฐ์ ๋งก์ ๋ถ๋ถ์ ๋ํ ํ์ฌ ์งํ ์ํฉ์ ๊ณต์ ํ๊ณ , ์์ผ๋ก์ ๊ณํ๊ณผ ๋ฐฉํฅ์ฑ์ ๋ํด ๋ ผ์ํ๋ฉฐ ์ผ์ ์ ์กฐ์จํ์ต๋๋ค. ๋น๋ก ๊ฐ์ธ์ ์งํ ์ํฉ์ ๋ฐ๋ฅธ ์ด๋ ค์๋ ์์์ง๋ง, ์ง์์ ์ธ ๋ํ๋ฅผ ํตํด ๋ฌธ์ ๋ค์ ํด๊ฒฐํด ๋๊ฐ ์ ์์๊ณ , ์ด ๊ณผ์ ์์ ์ํต์ ์ค์์ฑ์ ๋ค์ ํ๋ฒ ๊นจ๋ซ๊ฒ ๋์์ต๋๋ค. ๋ฐฑ์๋์ ์ ๋ฐ์ ์ธ ๊ตฌํ์ ๋งก์ผ๋ฉด์, ์ด์ ์ ์๋ํด๋ณด์ง ๋ชปํ๋ SMTP๋ฅผ ์ฌ์ฉํ ๋ฉ์ผ ๋ฐ์ก, S3 ๋ฒํท์ ์ด์ฉํ ํ์ผ ์ ๋ก๋ ๋ฑ์ ํ๋์ฉ ํด๊ฒฐํด ๋๊ฐ์ต๋๋ค. ๋ค๋ฅธ ๊ธฐ๋ฅ๋ค์ ํ ์คํธ ์ฝ๋๋ฅผ ์์ฑํ์ฌ ํ๋์ฉ ํ ์คํธํด๋ณด๋ฉฐ ํฐ ์ฑ์ทจ๊ฐ์ ์ป์ ์ ์์์ต๋๋ค. ๋ฐฑ์๋์์ ๋ง๋ค์ด์ง ๊ธฐ๋ฅ๋ค์ ํ๋ก ํธ์ ์ ์ฉํ์ง ๋ชปํ ๋ถ๋ถ๊ณผ Redis๋ฅผ ์ฌ์ฉํ ์ด๋ฉ์ผ ์ธ์ฆ์ ๊ตฌํํ์ง ๋ชปํจ์์ ์์ฌ์์ด ๋จ์ง๋ง ์ด๋ฏธ ๊ตฌํ๋ ๊ธฐ๋ฅ๋ค์ ํฅํ ๊ณ ๋ํ ๊ณผ์ ์์ ์ฝ๊ฒ ์ ์ฉ๋ ์ ์์๊บผ๋ผ๊ณ ์๊ฐํ๊ณ Redis๋ฅผ ํ์ฉํ ์ด๋ฉ์ผ ์ธ์ฆ์ ์ถํ ๊ณ ๋ํ ๊ณผ์ ์์์ ์๋ก์ด ๋ชฉํ๊ฐ ๋ ์ ์๋ค๋ ์ ์์ ํฌ๋ง์ ๋๋๋๋ค. ํ๋ก์ ํธ๋ฅผ ํตํด ์ํคํ ์ฒ๋ฅผ MSA๋ก ๋๋์ง ์๊ณ ๋ชจ๋๋ฆฌ์ ๋ฐฉ์์ผ๋ก ๊ฐ๋ฐ์ ์งํํ๋ฉด์ JPA๋ง์ ์ฌ์ฉํด ๋ณธ ํ ์ด ๊ฒฝํ์ ํตํด Spring bootํ๊ฒฝ์ ์ ๋ฐ์ ์ธ ๋ฐฑ์๋ ๊ฐ๋ฐ์ ๋ณต์ตํ ์ ์์์ผ๋ฉฐ, MyBatis์ JPA์ ์ฅ๋จ์ , ๋ชจ๋๋ฆฌ์ ์๋น์ค์ MSA์ ์ฅ๋จ์ ์ ์ง์ ๋น๊ตํด ๋ณผ ์ ์์์ต๋๋ค. |
์กฐ์๋น | 1. ๊ธฐ๋ณธ ๊ฒ์ํ ๊ธฐ๋ฅ: ์ด์ ํ๋ก์ ํธ์์์ ๊ฒฝํ์ ๋ฐํ์ผ๋ก ๊ธฐ๋ณธ ๊ฒ์ํ ๊ธฐ๋ฅ์ ํจ์จ์ ์ผ๋ก ๊ตฌํํ๋ ค ๋
ธ๋ ฅํ์ต๋๋ค. ์ด ๊ธฐ๋ฅ์ ํ๋ก์ ํธ์ ๊ธฐ๋ฐ์ ๋ง๋ จํ๋ ๋ฐ ์ค์ํ ์ญํ ์ ํ์์ผ๋ฉฐ, ๊ณผ๊ฑฐ์ ๋ฐฐ์ด ๋ด์ฉ์ ์์ฐ์ค๋ฝ๊ฒ ๋ณต์ตํ ์ ์๋ ๊ธฐํ๊ฐ ๋์์ต๋๋ค. 2. ์๋ก์ด ์ฃผ๋ ฅ ๊ธฐ๋ฅ: ์ด๋ฒคํธ ๊ฒ์ํ์ ํด์ฆ ๊ธฐ๋ฅ ์ด๋ฒคํธ ๊ฒ์ํ ๋ด์ ์ฌ์ฉ์๊ฐ ์ง์ ํด์ฆ๋ฅผ ๋ง๋ค๊ณ ๋ค๋ฅธ ์ฌ์ฉ์๊ฐ ํ ์ ์๋ ํด์ฆ ๊ธฐ๋ฅ์ ๊ฐ๋ฐํ์ต๋๋ค. ๊ฐ ํด์ฆ๋ ๋จ ํ ๋ฒ๋ง ์์ํ ์ ์์ผ๋ฉฐ, ์ ๋ต๋ฅ ์ ํ์ธํ ์ ์์ต๋๋ค. ์์ง ์์ฑํ์ง ๋ชปํ ํฌํ ๊ธฐ๋ฅ๋ ์ถํ ๊ณ ๋ํ๋ฅผ ํตํด ์์ฑํ ๊ณํ์ ๋๋ค. Postman์ ํ์ฉํด ๊ฐ๋ฐ ๊ณผ์ ์ค ๋ฐ์ํ๋ ์ธ๋ถ์ ์ธ ์ค๋ฅ๋ฅผ ์ ์ํ๊ฒ ํ์ธํ๊ณ ์์ ํ๋ ์์ ์ ์ํํ์ต๋๋ค. 3. DevOps ํ์ฉ ๋ฐ ํ์ต ๊ฒฝํ Docker, DockerHub, Kubernetes, Jenkins๋ฅผ ์ด์ฉํ์ฌ CI/CD ํ์ดํ๋ผ์ธ์ ๊ตฌ์ถํ๋ ๊ณผ์ ์ ๋ด๋นํ์ต๋๋ค. ์ด๊ธฐ์๋ ์ด๋ฌํ ๊ธฐ์ ๋ค์ ๊ฐ๋ ์ ์ดํดํ๋ ๋ฐ ์ด๋ ค์์ ๊ฒช์์ง๋ง, ๋ค์ํ ์ค๋ฅ์ ์ง๋ฉดํ๋ฉฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๊ณผ์ ์ ํตํด ์ ์ฐจ ์ดํด๋๋ฅผ ๋์ผ ์ ์์์ต๋๋ค. ์ ํจ์ค ์คํฌ๋ฆฝํธ์ ์ค๋ฅ๋ถํฐ ํ๋์จ์ด ์ฉ๋ ๋ถ์กฑ์ ์ด๋ฅด๊ธฐ๊น์ง ๋ค์ํ ๋ฌธ์ ๋ฅผ ๋ค๊ฐ๋์์ ๋ฐ๋ผ๋ณด๊ณ ์ ๊ทผํ๋ฉด์, ์์ธ ์ฒ๋ฆฌ์ ์ค๋ฅ ํด๊ฒฐ ๊ธฐ์ ์ ๋ํด ๊น์ด ์๊ฒ ๋ฐฐ์ฐ๊ฒ ๋์์ต๋๋ค. 4. ํ๋ก์ ํธ ๊ด๋ฆฌ์ ๊ธฐํ์ ์ค์์ฑ ์ด๋ฒ ํ๋ก์ ํธ๋ ์งง์ ์๊ฐ ๋ด์ ๋ค์ํ ๊ธฐ๋ฅ๊ณผ ํํธ๋ฅผ ๊ตฌํํ๋ ๊ฒ์ ๋ชฉํ๋ก ์ผ์์ต๋๋ค. ์ด ๊ณผ์ ์์ ๋ช ํํ ๋ชฉํ ์ค์ ๊ณผ ์ฐ์ ์์ ์กฐ์ ์ ์ค์์ฑ์ ๊น์ด ๋๊ผ์ต๋๋ค. ๋ด๋น ๊ธฐ๋ฅ๋ฟ๋ง ์๋๋ผ ํ์๋ค๊ณผ์ ์ํํ ํ์ ๊ณผ ์กฐ์ ๋ฅ๋ ฅ์ด ํ๋ก์ ํธ ์ฑ๊ณต์ ํ์์ ์์ ์ธ์ํ์ต๋๋ค. ์์ผ๋ก๋ ํ์๋ค๊ณผ ํ๋ ฅํ์ฌ ์์ง ์์ฑํ์ง ๋ชปํ ๊ธฐ๋ฅ๊ณผ ์ถ๊ฐ์ ์ธ ๊ฐ์ ์๊ฒฌ์ ๋ฐ์ํ์ฌ ํ๋ก์ ํธ๋ฅผ ์ ๊ทธ๋ ์ด๋ํ ๊ณํ์ ๋๋ค. |