DevOps

Docker 기반 Jenkins 설치 및 Letsencrypt 인증서 설정

nineDeveloper 2021. 7. 12. 00:48
728x90

회사에서 Jenkins 서버가 필요한데 AWS LightSail 에 가볍게 띄우기 위해서 Docker 기반으로 Jenkins 서버를 띄우고
인증서 설정을 위해 Letsencrypt 인증서 설정까지 한 내용에 대해 기록해본다

크게 1번 인증서 발급 과정과 2번 Jenkins 설치후 인증서 셋팅 두 과정으로 나누어 진다

먼저 1. 인증서 발급 부분부터 순서대로 진행해야 한다

최초에 인스턴스를 생성하고 home에서 jenkins 디렉토리를 생성하고 진행한다

1. 인증서 발급

참고1의 git을 pull 받아서 설정내용을 수정한다(별도의 git에 수정된 설정내용을 생성해놓아도 된다)

git clone https://github.com/hibuz/nginx-certbot.git

init-letsencrypt.sh 파일과 data/nginx/app.conf 파일을 자신의 도메인에 맞게 변경

init-letsencrypt.sh 변경항목

domains=(example.org www.example.org)
email="" # Adding a valid address is strongly recommended

data/nginx/app.conf 변경내용 (app_prifix.conf 내용 참조)

인증서를 발급을 위해 data/nginx 디렉토리를 생성하고 app.conf 파일 내용 입력

server {
    listen 80;
    server_name jenkins.test.com; #<- 여기
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name jenkins.test.com; #<- 여기
    server_tokens off;

    ssl_certificate /etc/letsencrypt/live/jenkins.test.com/fullchain.pem; #<- 여기
    ssl_certificate_key /etc/letsencrypt/live/jenkins.test.com/privkey.pem; #<- 여기
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass  http://jenkins.test.com;
        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;
    }
}

letsencrypt 인증서 설치를 위한 docker-compose.yml 파일 작성

단순히 letsencrypt 인증서 설치를 위한 docker-compose.yml 스크립트 이다

version: '3'

services:
  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: always
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
  certbot:
    image: certbot/certbot
    container_name: certbot
    restart: always
    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;'"

./init-letsencrypt.sh 실행 후 인증서 설치가 완료되면 해당 도메인으로 https 접속이 가능한지 확인해 본다

2. Jenkins 설치

기존에 인증서 발급을 위해 구동했던 컨테이너 삭제

docker-compose down

Jenkins 빌드를 위한 Dockerfile 작성

사전에 설치해야하는 패키지 설치와 설정을 위한 Dockerfile 을 작성한다

FROM jenkins/jenkins:jdk11
## 현재 유저권한으로
USER $USER
## docker 설치
RUN curl -s https://get.docker.com/ | sh
## docker-compose 설치
RUN 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 && \
    ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
## dcs 툴 설치
RUN curl -sL bit.ly/ralf_dcs -o ./dcs && \
    chmod 755 dcs && \
    mv dcs /usr/local/bin/dcs
## zulu jdk 11 설치
RUN apt-get update && apt upgrade -y && apt-get -y install software-properties-common && \
    apt-add-repository 'deb http://repos.azulsystems.com/ubuntu stable main' && \
    apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 0xB1998361219BD9C9 && \
    apt-get update && apt-get -y install git zulu-11
## CronJob 설정을 위한 패키지 설치 및 설정
#RUN apt install vim -y && \
#    apt install cron -y && \
#    service cron start && \
#    systemctl enable cron.service && \
#    systemctl list-unit-files | grep cron
## AWS CLI2 설치
RUN cd /var/jenkins_home
    apt-get install unzip -y && \
    curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
    unzip awscliv2.zip && \
    ./aws/install
## docker group 에 jenkins 추가
RUN usermod -aG docker jenkins
## aws configure 셋팅 후 docker login
RUN aws configure set aws_access_key_id AWS_ACCESS_KEY_ID && \
    aws configure set aws_secret_access_key AWS_SECRET_ACCESS_KEY && \
    aws configure set region ap-northeast-2 && \
    aws configure set output json && \
    aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 6XXXXXXXXXX0.dkr.ecr.ap-northeast-2.amazonaws.com

docker-compose.yml 내용 수정 및 jenkins 컨테이너 추가

기존에 인증서 발급을 위해 작성했던 docker-compose.yml 내용을 아래와 같이 수정한다

version: '3'

services:
  jenkins:
    privileged: true
    build: .
    #image: jenkins/jenkins:latest
    container_name: jenkins
    #user: root
    restart: always
    network_mode: "bridge"
    volumes:
      - ./data/jenkins/jenkins_home:/var/jenkins_home
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      TZ: "Asia/Seoul"
  nginx:
    image: nginx:alpine
    container_name: nginx
    restart: always
    network_mode: "bridge"
    links:
      - jenkins
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    ports:
      - 80:80
      - 443:443
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
  certbot:
    image: certbot/certbot
    container_name: certbot
    restart: always
    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;'"
  • network_mode: "bridge"
    • docker-compose 는 기본적으로 별도의 bridge 네트워크를 생성해서 각 컨테이너에 생성한 네트워크 대역의 ip를 할당합니다
    • network_mode를 bridge 로 설정하면 docker run 으로 실행 시킨 컨테이너와 같은 대역의 ip로 서로 통신이 가능하므로 편의상 설정
  • restart: always
    • 컨테이너가 비정상적으로 종료되거나 서버가 재부팅 되어도 컨테이너를 자동으로 시작되므로 블로그 운영이 편리함
  • container_name: nginx
    • 자동 생성되는 이름을 사용해도 되지만 docker restart nginxapp.conf 를 변경하고 재시작을 편하게 하거나 docker exec -it nginx sh 로 컨테이너에 접속하기도 좋음
  • volumes
    • 버전을 증가 시키거나 데이터를 쉽게 백업이 가능하도록 host 디렉토리를 mount 해서 파일db(sqlite) 및컨텐츠등을 기록합니다 (컨테이너가 삭제되어도 데이터는 유지)
  • links: jenkins
    • nginx 에서 host 이름으로 통신이 가능하도록 설정합니다. 만약 ip로 설정한다면 생략 가능 (외부 컨테이너를 reverse proxing 하려면 external_links 로도 지정 가능)data/nginx/app.conf 에 Reverse proxy 설정 추가 (내용중 domain 주소는 본인에 맞게 수정 필요)

data/nginx/app.conf 수정

nginx 의 app.conf 파일 내용을 아래와 같이 수정하고 docker-compose up -d 로 도커 컨테이너를 실행 및 확인 한다

server {
    listen 80;
    listen [::]:80;
    server_name jenkins.test.com; #<- 여기
    server_tokens off;

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name jenkins.test.com; #<- 여기
    server_tokens off;

    ssl_certificate /etc/letsencrypt/live/jenkins.test.com/fullchain.pem; #<- 여기
    ssl_certificate_key /etc/letsencrypt/live/jenkins.test.com/privkey.pem; #<- 여기
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass  http://jenkins.test.com;
        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;
        proxy_redirect off;
        proxy_request_buffering off;
        proxy_buffering off; # Required for HTTP-based CLI to work over SSL
        client_max_body_size 0;
    }
}
728x90