본문에서는 젠킨스 실제 구현한 내용과 순서에 대해 자세히 다루고, 파이프라인에 대해서는 아래 포스트에서 다루겠다.
👉 [CI/CD] Jenkins Pipeline 정리
https://velog.io/@kku64r/nginx
sudo docker pull jenkins/jenkins:lts
mkdir jenkins_build
cd jenkins_build
cat > Dockerfile
Dockerfile
FROM jenkins/jenkins:lts
USER root
# install docker
RUN apt-get update && \
apt-get -y install apt-transport-https \
ca-certificates \
curl \
gnupg2 \
zip \
unzip \
software-properties-common && \
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
$(lsb_release -cs) \
stable" && \
apt-get update && \
apt-get -y install docker-ce
cat > docker-compose.yml
version: '3.7'
services:
jenkins:
build:
context: .
container_name: jenkins
user: root
privileged: true
ports:
- 젠킨스포트:8080
- 50000:50000
volumes:
- ./jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
sudo docker-compose up
*** 사이에 있는 비밀번호 ctrl+c
gui를 사용한다면 해당 EC2 인스턴스에서 젠킨스 접속
http://juso.p.ssafy.io:젠킨스포트
계정명: 프로젝트이름 (임의)
암호: 비밀번호 (임의)
암호확인: 비밀번호 (임의)
이름 : 프로젝트이름 (임의)
이메일주소: 이메일주소
Jenkins 관리
> 플러그인 관리 > 설치 가능 > gitlab, nodejs(프론트 젠킨스 배포가 없으면 nodejs패스)를 설치한다.docker exec -it 컨테이너ID /bin/sh
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
pipeline {
agent any
tools {gradle "gradle7.5"}
stages {
stage('Prepare') {
steps {
echo 'Clonning Repository'
git url: '깃랩주소',//깃랩주소
branch: 'backend/dev',//브런치이름
credentialsId: '크레덴셜아이디'//credentialsId
}
post {
success {
echo 'Successfully Cloned Repository'
}
failure {
error 'This pipeline stops here...'
}
}
}
stage('Copy Properties') {
steps {
echo 'Copy Properties'
sh 'cp ./properties/application-db.yml garden-be/src/main/resources'//gitIgnore파일(properties)를 서버 실행할 때마다 자동으로 옮겨줌. 더 있으면 추가로 작성
}
post {
success {
echo 'Successfully Copied'
}
failure {
error 'This pipeline stops here...'
}
}
}
stage('Build Gradle') {
steps {
echo 'Build Gradle'
dir ('./프로젝트-be') {//디렉토리 프로젝트에 맞춰서 변경
sh """
gradle clean build --exclude-task test
"""
}
}
post {
success {
echo 'Successfully Builded'
}
failure {
error 'This pipeline stops here...'
}
}
}
stage('Copy Jar') {
steps {
echo 'Copy Jar'
sh 'rm back/backend-0.0.1-SNAPSHOT.jar || true'//디렉토리 프로젝트에 맞춰서 변경
sh 'mv ./garden-be/build/libs/프로젝트-0.0.1-SNAPSHOT.jar ./back'//디렉토리 프로젝트에 맞춰서 변경
}
post {
success {
echo 'Successfully Copied'
}
failure {
error 'This pipeline stops here...'
}
}
}
stage('Compose Down') {
steps {
echo 'Down Docker'
sh 'docker-compose -f docker-compose-back.yml down -v'
echo 'docker rmi start...'
// sh 'docker stop -f $(docker ps -a -q -f name=nginx)'
// sh 'docker rm -f $(docker ps -a -q -f name=nginx)'
sh 'docker rmi -f com_backend'//실행 전 backend 도커 이미지 및 컨테이너 삭제
sh 'docker rmi -f com_nginx'//실행 전 nginx 도커 이미지 및 컨테이너 삭제
}
post {
success {
echo 'Successfully Build Down'
}
failure {
error 'This pipeline stops here...'
}
}
}
stage('Compose Up') {
steps {
echo 'Push Docker'
sh 'docker-compose -f docker-compose-back.yml up -d'
}
post {
success {
echo 'Successfully Up'
}
failure {
error 'This pipeline stops here...'
}
}
}
}
}
version: '3.7'
services:
db:
image: mysql:8.0.28
expose:
- "MYSQL포트"
container_name: db
volumes:
- /home/ubuntu/deploy/db/conf.d:/etc/mysql/conf.d
- /home/ubuntu/deploy/db/db/data:/var/lib/mysql
- /home/ubuntu/deploy/db/db/initdb.d:/docker-entrypoint-initdb.d
environment:
MYSQL_DATABASE: 프로젝트DB이름
MYSQL_ROOT_PASSWORD: "비밀번호"
nginx:
container_name: nginx
build:
dockerfile: Dockerfile
context: ./nginx
image: com_nginx
expose:
- "80"
- "443"
ports:
- "80:80"
- "443:443"
volumes:
- /home/ubuntu/jenkins_build/jenkins_home/workspace/프로젝트-Back/back:/back
- /home/ubuntu/deploy/certbot:/certbot
backend:
container_name: backend
restart: on-failure
build:
dockerfile: Dockerfile
context: ./back
image: com_backend
expose:
- "8080"
#ports:
# - "8080:8080"
environment:
SERVER_PORT: 8080
SPRING_DATASOURCE_URL: jdbc:mysql://db:MYSQL포트/프로젝트DB이름?serverTimezone=Asia/Seoul&useLegacyDatetimeCode=false&useUnicode=true&characterEncoding=utf8
SPRING_DATASOURCE_USERNAME: 유저이름
SPRING_DATASOURCE_PASSWORD: "비밀번호"
SPRING_REDIS_HOST: redis_boot
SPRING_REDIS_PORT: 레디스포트
depends_on:
- db
- redis_boot
redis_boot:
image: redis:alpine
command: redis-server --port 레디스포트
container_name: redis_boot
hostname: redis_boot
labels:
- "name=redis"
- "mode=standalone"
expose:
- "레디스포트"
volumes:
- /home/ubuntu/deploy/redis:/data
networks:
default:
name: com_net
external: true
FROM nginx:stable-alpine
COPY ./default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
upstream backend {
server backend:8080;
}
server{
listen 80;
listen [::]:80;
server_name juso.p.ssafy.io; (서버URL)
location / {
return 301 https://$host$request_uri;
}
location /.well-known/acme-challenge/ {
root /certbot;
}
}
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name juso.p.ssafy.io; (서버URL)
access_log /var/log/nginx/nginx.vhost.access.log;
error_log /var/log/nginx/nginx.vhost.error.log;
ssl on;
ssl_certificate /certbot/etc/live/juso.p.ssafy.io(서버URL)/fullchain.pem;
ssl_certificate_key /certbot/etc/live/juso.p.ssafy.io(서버URL)/privkey.pem;
location /api {
proxy_pass http://backend;
proxy_set_header Host $http_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;
}
}
FROM openjdk:11-jdk
ARG JAR_FILE=./*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
version: "3.3"
services:
nginx:
image: nginx:latest
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
- ./nginx/log:/var/log/nginx
- ./www:/var/www/html
ports:
- 80:80
certbot:
restart: "no"
depends_on:
- nginx
image: certbot/certbot
container_name: certbot
volumes:
- ./certbot/etc:/etc/letsencrypt
- ./certbot/var:/var/lib/letsencrypt
- ./www:/var/www/html
command: certonly --webroot --webroot-path=/var/www/html --email 이메일주소 --agree-tos --no-eff-email --force-renewal -d juso.p.ssafy.io(사용할/서버URL)
docker-compose up
- /home/ubuntu
└─ /deploy/certbot/... (CertBot 키)
└─ /jenkins_build
└─ docker-compose.yml (jenkins)
└─ /jenkins_home/workspace/프로젝트-Back
└─ /프로젝트-be ( 깃랩 클론 파일)
└─ docker-compose-back.yml (backend)
└─ /back
└─ Dockerfile
└─ 프로젝트-0.0.1-SNAPSHOT.jar
└─ /nginx
└─ default.conf
└─ Dockerfile
└─ /properties
└─ application-db.yml와 같은 gitignore파일
https://seongwon.dev/DevOps/20220717-CICD구축기2/
yoongh97@gmail.com('컴설턴트' 팀원)의 작성글 참고
The referee awarded a penalty to Real Madrid. Captain Sergio Ramos, who was the executor, sent a powerful shot. Sportiello was able to read the direction, but could not prevent the aggregate from increasing to 3-0.
https://www.nobartv.co.id/indeks-topik , https://en.nobartv.co.id/indeks-topik , https://ko.nobartv.co.id/indeks-topik , https://ja.nobartv.co.id/indeks-topik , https://ar.nobartv.co.id/indeks-topik , https://hi.nobartv.co.id/indeks-topik
Atalanta managed to reduce the score in the 83rd minute. Luis Muriel sent a precise free kick that broke through Thibaut Courtois' goal. However, Madrid ensured that they remained 2 goals ahead after Marcos Asensio met Lucas Vazquez's pass to score.
https://ru.nobartv.co.id/indeks-topik , https://es.nobartv.co.id/indeks-topik , https://th.nobartv.co.id/indeks-topik , https://fr.nobartv.co.id/indeks-topik
The final score was 3-1, Real Madrid overall won 4-1 on aggregate over Atalanta. Los Blancos became the first Spanish team to reach the last 8 of the UCL this season, considering Barcelona were eliminated by PSG with an aggregate of 2-5.