GitLab + Certbot Let's Encrypt SSL 인증서 적용

아이구·2025년 4월 10일
post-thumbnail

Docker Compose로 설치한 GitLab에 Let’s Encrypt를 이용해 무료 SSL 인증서를 발급하고 자동으로 갱신하는 방법을 정리합니다.

GitLab은 ECDSA 키를 지원하지 않고 RSA 방식의 인증서만 지원하기 때문에 꼭 --key-type rsa 옵션을 설정해야 합니다.


기본 환경 및 구성

  • GitLab EE (Docker Compose, Omnibus Nginx 사용)
  • Certbot Docker 공식 이미지 (certbot/certbot)
  • 인증서 위치: /etc/letsencrypt/live/your-domain.com

디렉터리 구성 및 docker-compose.yml

아래와 같은 디렉터리 구조를 사용합니다.

.
├── certbot
│   ├── conf
│   └── www
├── config
│   └── nginx
│       └── conf.d
│           └── certbot.conf
├── data
├── logs
└── docker-compose.yml

docker-compose.yml 설정

services:
  gitlab:
    image: 'gitlab/gitlab-ee:17.8.5-ee.0'
    container_name: gitlab
    ports:
      - '80:80'
      - '443:443'
      - '22:22'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        external_url 'https://your-domain.com'
        nginx['ssl_certificate'] = "/etc/letsencrypt/live/your-domain.com/fullchain.pem"
        nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/your-domain.com/privkey.pem"
        nginx['http2_enabled'] = true
        nginx['custom_nginx_config_location'] = "include /etc/gitlab/nginx/conf.d/*.conf;"
    volumes:
      - './config:/etc/gitlab'
      - './logs:/var/log/gitlab'
      - './data:/var/opt/gitlab'
      - './certbot/conf:/etc/letsencrypt'
      - './certbot/www:/var/www/certbot'

  certbot:
    image: certbot/certbot
    container_name: certbot
    volumes:
      - './certbot/conf:/etc/letsencrypt'
      - './certbot/www:/var/www/certbot'
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot; sleep 48h & wait $${!}; done;'"
    restart: unless-stopped

external_url, 이메일 등은 실제 도메인과 본인 정보로 변경합니다.


Nginx에 인증용 경로 추가

GitLab 내장 Nginx에 Certbot 인증 시 사용할 경로를 설정합니다.

config/nginx/conf.d/certbot.conf 파일을 생성합니다.

location ^~ /.well-known/acme-challenge/ {
  root /var/www/certbot;
  default_type "text/plain";
  try_files $uri =404;
}

Let’s Encrypt 인증서 최초 발급 (RSA 필수)

GitLab이 RSA만 지원하므로 아래와 같이 명령어에 꼭 --key-type rsa 옵션을 추가해야 합니다.

docker run --rm \
  -v "$(pwd)/certbot/conf:/etc/letsencrypt" \
  -v "$(pwd)/certbot/www:/var/www/certbot" \
  certbot/certbot certonly \
  --webroot \
  --key-type rsa \
  -w /var/www/certbot \
  --email your@email.com \
  --agree-tos \
  --no-eff-email \
  -d your-domain.com
  • 인증서 경로:
    • /etc/letsencrypt/live/your-domain.com/fullchain.pem
    • /etc/letsencrypt/live/your-domain.com/privkey.pem

인증서 자동 갱신 스크립트 작성 (20일 이하일 때만 갱신)

인증서의 남은 기간이 20일 이하일 때만 자동 갱신하도록 스크립트를 작성합니다.

renew-cert.sh 파일 생성:

#!/bin/bash

expiry_date=$(openssl x509 -enddate -noout -in ./certbot/conf/live/your-domain.com/fullchain.pem | cut -d= -f2)
expiry_seconds=$(date --date="$expiry_date" +%s)
current_seconds=$(date +%s)

diff_days=$(( (expiry_seconds - current_seconds) / 86400 ))

if [ "$diff_days" -le 20 ]; then
  echo "인증서 유효기간이 $diff_days일 남아 갱신을 진행합니다."
  docker run --rm \
    -v "$(pwd)/certbot/conf:/etc/letsencrypt" \
    -v "$(pwd)/certbot/www:/var/www/certbot" \
    certbot/certbot renew --webroot -w /var/www/certbot

  docker exec gitlab gitlab-ctl hup nginx
else
  echo "인증서가 아직 유효합니다. ($diff_days일 남음)"
fi

스크립트 권한 설정:

chmod +x renew-cert.sh

Cron 등으로 한 달에 한 번 정도 주기적으로 실행합니다.


트러블슈팅과 문제 원인

1. "No renewals were attempted"

기본적으로 만료일까지 30일 이상 남으면 갱신하지 않습니다.
강제로 갱신이 필요하면 --force-renewal 옵션을 사용합니다.

certbot renew --force-renewal

2. "Port 80 is already in use"

Certbot이 standalone 방식으로 실행되면 80포트를 직접 사용하므로 충돌합니다.
이때는 GitLab을 잠시 중단하거나, webroot 방식으로 인증을 진행하면 충돌을 피할 수 있습니다.

3. "incorrect pkey type: id-ecPublicKey"

GitLab이 RSA 키만 지원하기 때문에 발생하는 문제입니다.
반드시 --key-type rsa 옵션을 설정해야 합니다.

4. "웹 브라우저에서 인증서가 갱신되지 않은 것으로 보임"

설정 변경 후 Nginx가 설정을 다시 로드해야 합니다.

docker exec gitlab gitlab-ctl hup nginx

브라우저 캐시도 영향을 줄 수 있으므로 브라우저 캐시를 비우거나 강력 새로고침을 시도해 보세요.


인증서 유효기간 확인 명령어

  • GitLab 컨테이너 내부에서 확인:
docker exec -it gitlab openssl x509 -in /etc/letsencrypt/live/your-domain.com/fullchain.pem -noout -dates
  • 외부에서 HTTPS로 직접 확인:
echo | openssl s_client -connect your-domain.com:443 -servername your-domain.com | openssl x509 -noout -dates

정리 (요약)

  • GitLab은 RSA 인증서만 지원합니다. (--key-type rsa 필수)
  • webroot 방식을 사용하면 Certbot과 GitLab 간 포트 충돌 없이 갱신 가능합니다.
  • 설정 변경 후엔 반드시 gitlab-ctl hup nginx를 실행합니다.
  • 브라우저 캐시 때문에 갱신된 인증서가 바로 반영되지 않을 수 있습니다.
profile
정리하는 벨로그

0개의 댓글