Let's Encrypt로 SSL 인증서 발급받기 - Mac Mini로 홈서버 구축하기 #3
미리 알아야할 것:
이전 글에 이어서 Let’s Encrypt를 사용하여 무료 SSL 인증서를 발급받는 방법을 알아보겠습니다.
이 과정을 완료하면 HTTPS 보안 프로토콜을 사용하여 홈 서버에 안전하게 접근할 수 있게 됩니다.
프로젝트 디렉터리 구조
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
nginx/
├── conf/
│ ├── nginx.conf
│ └── sites-enabled/
│ └── default.conf
├── html/
│ └── index.html
├── logs/
│ └── nginx/
│ ├── access.log
│ └── error.log
├── certbot/ # ← 새로 추가
│ ├── www/ # /.well-known/acme-challenge 파일 저장
│ └── letsencrypt/ # /etc/letsencrypt 실제 인증서
└── docker-compose.yml
- certbot/www: 웹루트 플러그인용 챌린지 파일을 저장하는 디렉터리
- certbot/letsencrypt: live/, archive/, renewal/ 하위 디렉터리를 포함한 Certbot 기본 구조를 보관하는 디렉터리
이렇게 독립된 폴더를 구성하면 컨테이너를 교체해도 인증서와 챌린지 파일이 보존됩니다.
수정된 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
services:
nginx:
image: nginx:latest
container_name: my-nginx
ports:
- "80:80"
- "443:443"
volumes:
- ./html:/usr/share/nginx/html:ro
- ./conf/nginx.conf:/etc/nginx/nginx.conf:ro
- ./conf/sites-enabled:/etc/nginx/conf.d:ro
- ./logs/nginx:/var/log/nginx
- ./certbot/www:/var/www/certbot # 웹루트 공유
- ./certbot/letsencrypt:/etc/letsencrypt # 인증서 공유
restart: unless-stopped
certbot:
image: certbot/certbot:latest
container_name: certbot
depends_on:
- nginx
volumes:
- ./certbot/www:/var/www/certbot
- ./certbot/letsencrypt:/etc/letsencrypt
restart: "no"
Nginx 설정에서 /var/www/certbot
을 루트로 지정한 location /.well-known/acme-challenge/
블록을 반드시 포함해야 합니다.
Certbot 서비스는 상시 실행할 필요가 없으므로 restart: "no"
로 설정하고, 인증서 발급 및 갱신 시에만 docker compose run
으로 호출합니다.
최초 인증서 발급 절차
1단계: nginx 설정 파일 수정
conf/sites-enabled/default.conf
파일에 다음 내용을 추가해야 합니다:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
server {
listen 80; # 수신 포트 (HTTP 기본 80)
server_name your-domain.duckdns.org;
root /usr/share/nginx/html;
index index.html index.htm; # 기본 문서
# ACME 챌린지용 경로
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# 기본 정적 파일 서빙
location / {
try_files $uri $uri/ =404;
}
}
2단계: 인증서 발급
1
2
3
4
5
6
7
8
# HTTP 모드로 Nginx만 우선 기동
docker compose up -d nginx
# 인증서 최초 발급 (웹루트 방식)
docker compose run --rm certbot certonly \
--webroot -w /var/www/certbot \
-d your-domain.duckdns.org \
--email your-email@example.com --agree-tos --no-eff-email
발급이 완료되면 certbot/letsencrypt/live/your-domain.duckdns.org/{fullchain.pem,privkey.pem}
파일이 생성됩니다.
HTTPS 설정 추가
인증서 발급이 완료되면 nginx 설정을 HTTPS로 업데이트해야 합니다:
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
server {
listen 80;
server_name your-domain.duckdns.org;
# ACME 챌린지용 경로
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# HTTP를 HTTPS로 리다이렉트
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name your-domain.duckdns.org;
ssl_certificate /etc/letsencrypt/live/your-domain.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.duckdns.org/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
설정 변경 후 nginx를 재시작합니다:
1
docker compose restart nginx
crontab으로 자동 갱신
크론 항목 예시 (macOS 또는 Linux 호스트)
1
2
3
4
5
# 매일 03:00에 갱신 시도
# ⚠️ /path/to/nginx를 실제 nginx 프로젝트 경로로 변경하세요
00 3 * * * cd /path/to/nginx && \
docker compose run --rm certbot renew --webroot -w /var/www/certbot --quiet && \
docker compose exec nginx nginx -s reload
Let’s Encrypt 커뮤니티와 Certbot 문서에서는 하루 1~2회 호출을 권장합니다. renew
명령은 30일 이하로 만료되는 인증서만 실제로 갱신하므로 서버 부담이 적습니다.
주의사항
- 도메인 이름 변경: 위 예시의
your-domain.duckdns.org
를 실제 사용하는 도메인으로 변경하세요. - 이메일 주소 변경:
your-email@example.com
을 실제 이메일 주소로 변경하세요. - 경로 확인: crontab의
/path/to/nginx
를 실제 nginx 프로젝트 경로로 변경하세요. - 포트 확인: 방화벽에서 80번과 443번 포트가 열려있는지 확인하세요.
This post is licensed under CC BY 4.0 by the author.