Skip to content

Commit 0cdecca

Browse files
committed
letsencrypt: post added
1 parent 298a0a6 commit 0cdecca

File tree

2 files changed

+179
-1
lines changed

2 files changed

+179
-1
lines changed

_posts/2025-07-03-duck_dns.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
layout: post
33
title: "Duck DNS로 DDNS 설정하기 - Mac Mini로 홈서버 구축하기 #1"
44
description: "Mac Mini로 홈서버를 구축할 때 필요한 DDNS 설정 방법을 안내합니다. DuckDNS를 사용하여 무료로 동적 DNS를 설정하고, cron을 통해 자동으로 IP 업데이트하는 방법을 단계별로 설명합니다."
5-
date: 2025-07-03
5+
date: 2025-07-03 10:00 +0900
66
categories: [Tips]
77
---
88

_posts/2025-07-03-lets_encrypt.md

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
---
2+
title: "Let's Encrypt로 SSL 인증서 발급받기 - Mac Mini로 홈서버 구축하기 #3"
3+
description: Let's Encrypt를 사용하여 무료 SSL 인증서를 발급받고 자동 갱신 설정하는 방법
4+
date: 2025-07-03 20:00 +0900
5+
categories:
6+
- Tips
7+
---
8+
9+
> 미리 알아야할 것:
10+
> - [Duck DNS로 DDNS 설정하기 - Mac Mini로 홈서버 구축하기 #1](/posts/duck_dns/)
11+
> - [nginx 서버 열기 - Mac Mini로 홈서버 구축하기 #2](/posts/nginx/)
12+
13+
14+
이전 글에 이어서 Let's Encrypt를 사용하여 무료 SSL 인증서를 발급받는 방법을 알아보겠습니다.
15+
16+
이 과정을 완료하면 HTTPS 보안 프로토콜을 사용하여 홈 서버에 안전하게 접근할 수 있게 됩니다.
17+
18+
## 프로젝트 디렉터리 구조
19+
20+
```
21+
nginx/
22+
├── conf/
23+
│ ├── nginx.conf
24+
│ └── sites-enabled/
25+
│ └── default.conf
26+
├── html/
27+
│ └── index.html
28+
├── logs/
29+
│ └── nginx/
30+
│ ├── access.log
31+
│ └── error.log
32+
├── certbot/ # ← 새로 추가
33+
│ ├── www/ # /.well-known/acme-challenge 파일 저장
34+
│ └── letsencrypt/ # /etc/letsencrypt 실제 인증서
35+
└── docker-compose.yml
36+
```
37+
38+
- **certbot/www**: 웹루트 플러그인용 챌린지 파일을 저장하는 디렉터리
39+
- **certbot/letsencrypt**: live/, archive/, renewal/ 하위 디렉터리를 포함한 Certbot 기본 구조를 보관하는 디렉터리
40+
41+
이렇게 독립된 폴더를 구성하면 컨테이너를 교체해도 인증서와 챌린지 파일이 보존됩니다.
42+
43+
## 수정된 docker-compose.yml
44+
45+
```yaml
46+
services:
47+
nginx:
48+
image: nginx:latest
49+
container_name: my-nginx
50+
ports:
51+
- "80:80"
52+
- "443:443"
53+
volumes:
54+
- ./html:/usr/share/nginx/html:ro
55+
- ./conf/nginx.conf:/etc/nginx/nginx.conf:ro
56+
- ./conf/sites-enabled:/etc/nginx/conf.d:ro
57+
- ./logs/nginx:/var/log/nginx
58+
- ./certbot/www:/var/www/certbot # 웹루트 공유
59+
- ./certbot/letsencrypt:/etc/letsencrypt # 인증서 공유
60+
restart: unless-stopped
61+
62+
certbot:
63+
image: certbot/certbot:latest
64+
container_name: certbot
65+
depends_on:
66+
- nginx
67+
volumes:
68+
- ./certbot/www:/var/www/certbot
69+
- ./certbot/letsencrypt:/etc/letsencrypt
70+
restart: "no"
71+
```
72+
73+
Nginx 설정에서 `/var/www/certbot`을 루트로 지정한 `location /.well-known/acme-challenge/` 블록을 반드시 포함해야 합니다.
74+
75+
Certbot 서비스는 상시 실행할 필요가 없으므로 `restart: "no"`로 설정하고, 인증서 발급 및 갱신 시에만 `docker compose run`으로 호출합니다.
76+
77+
## 최초 인증서 발급 절차
78+
79+
### 1단계: nginx 설정 파일 수정
80+
81+
`conf/sites-enabled/default.conf` 파일에 다음 내용을 추가해야 합니다:
82+
83+
```nginx
84+
server {
85+
listen 80; # 수신 포트 (HTTP 기본 80)
86+
server_name your-domain.duckdns.org;
87+
root /usr/share/nginx/html;
88+
index index.html index.htm; # 기본 문서
89+
90+
# ACME 챌린지용 경로
91+
location /.well-known/acme-challenge/ {
92+
root /var/www/certbot;
93+
}
94+
95+
# 기본 정적 파일 서빙
96+
location / {
97+
try_files $uri $uri/ =404;
98+
}
99+
}
100+
```
101+
102+
### 2단계: 인증서 발급
103+
104+
```bash
105+
# HTTP 모드로 Nginx만 우선 기동
106+
docker compose up -d nginx
107+
108+
# 인증서 최초 발급 (웹루트 방식)
109+
# ⚠️ docker-compose.yml의 certbot command를 제거하고 아래 명령어를 사용하세요
110+
docker compose run --rm certbot certonly \
111+
--webroot -w /var/www/certbot \
112+
-d your-domain.duckdns.org \
113+
--email [email protected] --agree-tos --no-eff-email
114+
```
115+
116+
발급이 완료되면 `certbot/letsencrypt/live/your-domain.duckdns.org/{fullchain.pem,privkey.pem}` 파일이 생성됩니다.
117+
118+
## HTTPS 설정 추가
119+
120+
인증서 발급이 완료되면 nginx 설정을 HTTPS로 업데이트해야 합니다:
121+
122+
```nginx
123+
server {
124+
listen 80;
125+
server_name your-domain.duckdns.org;
126+
127+
# ACME 챌린지용 경로
128+
location /.well-known/acme-challenge/ {
129+
root /var/www/certbot;
130+
}
131+
132+
# HTTP를 HTTPS로 리다이렉트
133+
location / {
134+
return 301 https://$host$request_uri;
135+
}
136+
}
137+
138+
server {
139+
listen 443 ssl;
140+
server_name your-domain.duckdns.org;
141+
142+
ssl_certificate /etc/letsencrypt/live/your-domain.duckdns.org/fullchain.pem;
143+
ssl_certificate_key /etc/letsencrypt/live/your-domain.duckdns.org/privkey.pem;
144+
145+
location / {
146+
root /usr/share/nginx/html;
147+
index index.html;
148+
}
149+
}
150+
```
151+
152+
설정 변경 후 nginx를 재시작합니다:
153+
154+
```bash
155+
docker compose restart nginx
156+
```
157+
158+
## crontab으로 자동 갱신
159+
160+
### 크론 항목 예시 (macOS 또는 Linux 호스트)
161+
162+
```bash
163+
# 매일 03:00에 갱신 시도
164+
# ⚠️ /path/to/nginx를 실제 nginx 프로젝트 경로로 변경하세요
165+
00 3 * * * cd /path/to/nginx && \
166+
docker compose run --rm certbot renew --webroot -w /var/www/certbot --quiet && \
167+
docker compose exec nginx nginx -s reload
168+
```
169+
170+
Let's Encrypt 커뮤니티와 Certbot 문서에서는 하루 1~2회 호출을 권장합니다. `renew` 명령은 30일 이하로 만료되는 인증서만 실제로 갱신하므로 서버 부담이 적습니다.
171+
172+
173+
## 주의사항
174+
175+
1. **도메인 이름 변경**: 위 예시의 `your-domain.duckdns.org`를 실제 사용하는 도메인으로 변경하세요.
176+
2. **이메일 주소 변경**: `[email protected]`을 실제 이메일 주소로 변경하세요.
177+
3. **경로 확인**: crontab의 `/path/to/nginx`를 실제 nginx 프로젝트 경로로 변경하세요.
178+
4. **포트 확인**: 방화벽에서 80번과 443번 포트가 열려있는지 확인하세요.

0 commit comments

Comments
 (0)