前端后端都稍微写过,也有一个基于 hugo 的静态博客,不过在部署网站方面都是靠别人或者工具自动化,真要自己从头部署一个网站还真是两眼一抹黑,抓瞎。所以记录一下部署一个 https 网站的折腾过程,给有需要的人。
- 在 ubuntu 系统上启动 nginx 容器
- 通过 Let's encrypt 得到 HTTPS 功能
- 按照文档,安装 Docker
- 按照文档, 安装 Docker Compose
先准备好对应的文件,文件结构如下
1
2
3
4
5
6
7
8
9
10
11
12
13
|
└── example
├── html
│ └── index.html # 主页
├── nginx
│ ├── default.conf # 网站相关配置
│ ├── nginx.conf # nginx配置
│ ├── Dockerfile # 制作nginx容器的文件
│ ├── letsencrypt # let's encrypt相关的文件放在这
│ └── logs
│ ├── access.log
│ ├── certbot.log # 证书更新的log
│ └── error.log
└── docker-compose.yml # 一键启动nginx的脚本
|
Dockerfile
中的内容为
1
2
3
4
5
6
|
FROM nginx:latest
RUN apt-get update && \
apt-get install -y certbot python-certbot-nginx && \ # 安装certbot
apt-get clean
ADD nginx.conf /etc/nginx/ # 将我们定义好的配置加入nginx容器中
ADD default.conf /etc/nginx/conf.d/
|
nginx.conf
中的内容为
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
|
# nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
|
default.conf
中的内容为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# default.conf
server {
server_name localhost;
listen 80;
listen [::]:80; # ipv6对应
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
|
docker-compose.yml
中的内容为
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
services:
proxy:
build: ./nginx
tty: true
container_name: proxy
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
ports: # 映射80和443端口
- "80:80"
- "443:443"
volumes: # 将本地的文件映射到容器中, 注意左边为相对路径
- './nginx/logs:/var/log/nginx'
- './nginx/letsencrypt:/etc/letsencrypt'
- './html:/usr/share/nginx/html'
|
最后在example
文件夹下运行sudo docker-compose up -d
,nginx容器就搭起来了。浏览器访问http://<hostname>
就能够看到index.html
里面的内容了。也可以通过docker ps
确认现在在运行的容器。
1
2
3
|
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9bbc29f18441 cool_proxy "/docker-entrypoint.…" 43 hours ago Up 8 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp proxy
|
通过上面的流程,我们的网站已经可以 HTTP 访问了。如果想要开启 HTTPS 访问,就必须要有私钥和证书。Let's Encrypt 提供免费的证书,但是有效期为 3 个月,需要定期更新。这个并不是太大的问题,只要通过 cron 加个定时任务就行。
运行sudo docker exec -it proxy bash
进入到我们刚刚建立的 nginx 容器中,运行certbot
获得证书(中间会让你填写域名相关信息)。证书会保存在/etc/letsencrypt/live/<hostname>
文件夹下。
接下来修改default.conf
,加入 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
28
29
30
31
32
|
server {
server_name localhost;
listen 80;
listen [::]:80;
return 301 https://$host$request_uri;
}
server {
server_name localhost;
listen 443 ssl http2;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384";
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/<hostname>/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/<hostname>/privkey.pem;
# Improve HTTPS performance with session resumption
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
|
然后example
文件夹下运行docker-compose restart
将刚刚的更改重载,浏览器访问https://<hostname>
,如果能打开就代表 HTTPS 已经开启。
因为 let's encrypt 证书是 3 个月一过期,所以我们需要在 cron 里面加一个定时任务,比如每个月更新一次证书。
运行sudo crontab -e
打开定时任务配置文件,在最后一行添加以下代码。
@monthly { date; docker exec proxy certbot renew; } >> /home/<user>/example/nginx/logs/certbot.log 2>&1
为了确定命令是否可以被正确运行,在命令行运行
1
|
$ { date; sudo docker exec proxy certbot renew; } >> /home/<user>/example/nginx/logs/certbot.log 2>&1
|
然后运行cat ~/example/nginx/logs/certbot.log
查看 certbot 证书更新日志,有以下 log 代表可以运行。
Thu 16 Sep 2021 05:48:59 PM UTC
Saving debug log to /var/log/letsencrypt/letsencrypt.log
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/<hostname>.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certs are not due for renewal yet:
/etc/letsencrypt/live/<hostname>/fullchain.pem expires on 2021-12-15 (skipped)
No renewals were attempted.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
接下来可以将目前的文件备份到 github 上,以后只要安装完 Docker 环境,即使换服务器,也可以一键搞定。
如果本文对您有帮助,欢迎打赏。