๐ณ Docker ยท Jenkins ๋์ ์ ํตํ CI ยท CD Pipeline ๊ตฌ์ถ
๐ณ Docker ยท Jenkins ๋์
์ ํตํ CI ยท CD Pipeline ๊ตฌ์ถ
CI
ยท CD
Pipeline
๊ตฌ์ถ์ ์ ํ๋?
- ํ๋ก์ ํธ ๊ฐ๋ฐ์ ๋ง์น๊ณ ์๋ก์ด
Release
๊ฐ ์๊ธธ ๋๋ง๋ค ๋ฐฐํฌ๋ฅผ ํ๋ ๊ฒ์ ํจ์จ์ ์ด์ง ๋ชปํ๋ค. - ์ฒ์์ผ๋ก ์งํํ ํ๋ก์ ํธ์์ ๊ทธ๋ ๊ฒ ํ์๋๋ฐ, ์ด๋ฒ์๋ ํ๋ก์ ํธ ๋ฐฐํฌ์ ์์ด ํจ์จ์ฑ ๋ฐ ์ผ๊ด์ฑ์ ๊ฐ์ ธ๊ฐ๊ธฐ ์ํด ์๋ํ๋ฅผ ํด๋ณด๊ณ ์ ํ๋ค.
Infrastructure
๊ตฌ์กฐ
- ์ ๊ตฌ์กฐ๋ก ๋ฌด์ค๋จ ๋ฐฐํฌ๋ฅผ ์ํด
CI
/CD
Pipeline
์ ๊ตฌ์ถํ๋ค.
CI
ยท CD
Pipeline
๊ตฌ์ถ ๊ณผ์
Docker
์ค์นDocker-compose
์ค์นJenkins
์ค์นSSH Key
๋ฑ๋กGitHub Webhook
์ค์ Dockerfile
,Docker-compose.yml
,Jenkins
Pipeline
Script
ํ์ผ ์์ฑapplication.yml
ํ์ผ ์์ฑ
โ
Docker
์ค์น
1
2
3
4
5
# Docker ์ค์น
sudo apt update
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl enable docker
โ
Docker-compose
์ค์น
1
2
3
4
# ๋์ปค ์ปดํฌ์ฆ ์ค์น
sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
โ
Jenkins
์ค์น
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Jenkins ์ ์ฅ์ ํค ๋ฐ ์ ์ฅ์ ์ถ๊ฐ
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo tee /usr/share/keyrings/jenkins-keyring.asc > /dev/null
echo deb [signed-by=/usr/share/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list > /dev/null
# ํจํค์ง ๋ชฉ๋ก ๊ฐฑ์ ๋ฐ Jenkins ์ค์น
sudo apt update && sudo apt install jenkins -y
# Jenkins ์๋น์ค ์์ ๋ฐ ๋ถํ
์ ์๋ ์์ ์ค์
sudo systemctl start jenkins
sudo systemctl enable jenkins
# UFW ๋ฐฉํ๋ฒฝ์์ ํฌํธ 8080 ํ์ฉ
sudo ufw allow 8080 && sudo ufw reload
# ์ด๊ธฐ ๊ด๋ฆฌ์ ๋น๋ฐ๋ฒํธ ์ถ๋ ฅ (์น ์ฌ์ดํธ์ ์
๋ ฅ)
sudo cat /var/lib/jenkins/secrets/initialAdminPassword
Jenkins
๋Java
๊ธฐ๋ฐ์ด๊ธฐ ๋๋ฌธ์JDK
๊ฐ ์ค์น๋์ด ์์ด์ผ ํ๋ค.http://์๋ฒ_IP:8080
์ ์ด๊ธฐ ๊ด๋ฆฌ์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ๋ฉด ๋๋ค.
โ
SSH Key
๋ฑ๋ก
1
2
3
4
5
# SSH Key ์์ฑ
ssh-keygen -t rsa -b 4096
# authorized_keys ํ์ผ์ ๊ณต๊ฐํค ๋ฑ๋ก
echo id_rsa.pub_๋ด์ฉ >> ~/.ssh/authorized_keys
SSH Key
๋ฅผ ์์ฑํ๋ฉด~/.ssh/id_rsa
๋น๋ฐํค ํ์ผ๊ณผ~/.ssh/id_rsa.pub
๊ณต๊ฐํค ํ์ผ์ด ๋ง๋ค์ด ์ง๋ค.authorized_keys
ํ์ผ์ ๊ณต๊ฐํค ๋ฑ๋ก์ ํ๊ณ ์, ๋น๋ฐํค๋Jenkins Pipeline
์ด๋job
์์SSH
์ ์ํ ๋์ ์ธ์ฆ์ ์ํดJenkins
์๊ฒฉ ์ฆ๋ช ์ ์ถ๊ฐํด์ผ ํ๋ค.
โ
GitHub
Webhook
์ค์
GitHub
ํ๋ก์ ํธRepository
Settings
>Webhooks
>Add Webhook
Payload URL
(Ubuntu
์๋ฒURL
),Content type
์ ๋ ฅEnable SSL verification
์ฒดํฌJust theย pushย event
์ฒดํฌ
โ
Dockerfile
์์ฑ
spring-app
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
FROM gradle:8.8-jdk17 as build
WORKDIR /app
COPY . .
RUN gradle clean build --no-daemon
FROM openjdk:17-jdk-slim
WORKDIR /usr/local/app
COPY --from=build /app/build/libs/ํ๋ก์ ํธ_jar_ํ์ผ๋ช
/usr/local/app/ํ๋ก์ ํธ_JAR_ํ์ผ๋ช
.jar
ENTRYPOINT ["java", "-jar", "/usr/local/app/ํ๋ก์ ํธ_jar_ํ์ผ๋ช
.jar"]
EXPOSE 18080
JAR
ํ์ผ์ ๋น๋ํ ๋๋Daemon
์ ์ค์ ํ์ง ์๋ ๊ฒ ์ข๋ค๊ณ ํ๋ค.- ์ปจํ
์ด๋๋ ์๋ช
์ฃผ๊ธฐ๊ฐ ์งง๊ธฐ ๋๋ฌธ์ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ๋ง๊ฐ์ง๋ ๊ฒ ๋น์ฐํ
Resource
์ด๊ณ , ๊ทธ๋๋ง๋ค ์ปจํ ์ด๋ ์์์ ํด์ ํ๊ณ ์ฌ์์ฑ ํด์ผ ํ๋ค. - ๊ทธ๋ฐ๋ฐ
Daemon
์ด ์ค์ ๋์ด ์๋ค๋ฉด ํด์ ๋์ง ์๋ ์์์ด ์๊ธธ ์๊ฐ ์๋ค๊ณ ํ๋ค.react-app
Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
FROM node:18-alpine AS build
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
โ
Docker-compose.yml
์์ฑ
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
services:
oracle-db:
container_name: oracle-db
image: gvenzl/oracle-xe:11-slim
ports:
- "1521:1521"
environment:
ORACLE_PASSWORD: ํจ์ค์๋
volumes:
- oracle-data:/opt/oracle/oradata
networks:
- app-network
spring-app:
container_name: spring-app
image: spring-app
build: ./spring-app
ports:
- "18080:18080"
volumes:
- ./logs:/usr/local/app/logs
depends_on:
- oracle-db
restart: on-failure
networks:
- app-network
react-app:
container_name: react-app
build: ./react-app
image: react-app
ports:
- "3000:80"
volumes:
- ./react-app:/app
networks:
- app-network
networks:
app-network:
name: app-network
driver: bridge
volumes:
oracle-data:
driver: local
โ
Jenkins
Pipeline
Script
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
31
32
pipeline {
agent any
stages {
stage('Checkout') {
steps {
git branch: '๋ธ๋์น๋ช
', url: '๊นํ๋ธ_ํ๋ก์ ํธ_์ฃผ์'
}
}
stage('Prepare') {
steps {
sshagent(['์ ํจ์ค_์๊ฒฉ์ฆ๋ช
_ํค']) {
sh 'mkdir -p ${WORKSPACE}/ํ๋ก์ ํธ/src/main/resources'
sh 'scp -o StrictHostKeyChecking=no ์ฌ์ฉ์๋ช
@์๋ฒ๋๋ฉ์ธ:/home/ubuntu/application.yml ${WORKSPACE}/ํ๋ก์ ํธ/src/main/resources/application.yml'
}
}
}
stage('Build and Deploy with Docker Compose') {
steps {
sh 'docker-compose -f ${WORKSPACE}/docker-compose.yml up --build -d'
}
}
}
post {
failure {
echo 'Deployment failed.'
}
}
}
GitHub
Webhook
์ ํตํดPush Event
๋ฅผ ๊ฐ์งํด์ ์์ค ์ฝ๋๋ฅผ${WORKSPACE}
๋ก ๊ฐ์ ธ์จ๋ค.ย- ์๋ฒ์์ ์ง์ ์์ค ์ฝ๋์
resources
๊ฒฝ๋ก๋ก ์ฃผ์ ํด ์ค๋ค. Docker-compose.yml
ํ์ผ์ ๋น๋ํ๋ฉด ๋คํธ์ํฌ๊ฐ ์์ฑ๋๊ณ , ๊ทธ ์์์Docker
Container
๋ค์ด ์์ฑ๋๊ณ ์คํ๋๋ค.
โ
application.yml
ํ์ผ ์์ฑ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
spring:
datasource:
url: jdbc:oracle:thin:@oracle-db:1521:xe?oracle.jdbc.timezoneAsRegion=false
username: ์ฌ์ฉ์๋ช
password: ๋น๋ฐ๋ฒํธ
driver-class-name: oracle.jdbc.OracleDriver
jpa:
database-platform: org.hibernate.dialect.OracleDialect
hibernate:
ddl-auto: update
logging:
level:
org.hibernate.SQL: debug
org.hibernate.orm.jdbc.bind: trace
์ต์์_๋๋ฉ์ธ.2์ฐจ_๋๋ฉ์ธ.ํ๋ก์ ํธ๋ช
: debug
file:
name: /usr/local/app/logs/app.log
jwt:
secret-key: ๋ฌธ์์ด
server:
port: 18080
ํ๋ก์ ํธ ๋น๋
GitHub
์ ๋ณ๊ฒฝ ์ฌํญ์Push
ํ๊ฑฐ๋,Jenkins Console
์์ โ์ง๊ธ ๋น๋โ ๋ฒํผ์ ๋๋ฅด๋ฉด ๋๋ค.Pipeline
์คํ์ด ์ฑ๊ณตํ๋ฉด ์ ์ด๋ฏธ์ง์ฒ๋ผDocker
Container
๊ฐ ๋ชจ๋ ์ฌ๋ผ์ ์์ด์ผ ํ๋ค.ย
ํ๊ณ
Jenkins
Pipeline
Script
๋ฅผ101
๋ฒ์ด๋ ์ฝ์งํ๋ฉด์ ๋ช ๊ฐ์ง ๋๋ ์ ์ด ์๋ค.- ์ด๊ธฐ
Pipeline
๊ตฌ์ถ ์ ํ ์คํธ ์ฝ๋๋ ๋๋ฌด ์ค๋ ์๊ฐ์ด ์์๋๋ฏ๋ก ์ ์ธํ๊ณ ๋น๋ ํ๋ ๊ฒ์ด ์ข๋ค. application.yml
ํ์ผ์ ํ๋ก์ ํธ ๋ด์ ํฌํจํ๋, ์์ ๋ด์ฉ์.env
๋ฅผ ํตํด ์ธ๋ถ์์ ๊ด๋ฆฌํ๊ณ ์ฃผ์ ํ๋ ๊ฒ์ด ์ข๋ค.
- ์ด๊ธฐ
- ํน์๋ ์๋ฒฝํ๊ฒ ์ดํดํ๊ณ ์ ์ ํ์๋ฅผ ์๋ํด์ ์ฑ๊ณตํ๋ ๊ฒ์ด ์ข๋ค๊ณ ์๊ฐ ํ ์ ์๊ณ , ๊ทธ๊ฒ ๋ง์ ์๋ ์๋ค.
- ๊ทธ๋ฐ๋ฐ ํ์๋ ๋ง์ ์๋์์ ๊ฒช๋
Trouble-shooting
๊ณผ์ ์์๋ ์ป์ ๊ฒ ๋ง๋ค๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์101
๋ฒ์ ์๋๊ฐ ์๋ฏธ๊ฐ ์์๋ค๊ณ ์๊ฐํ๋ค.
This post is licensed under CC BY 4.0 by the author.