ubuntu server部署nginx

github pages强制使用https访问,即使是硬编码http也不行。此时就需要部署nginx。

本文介绍如何使用docker部署一个nginx,并且配置SSL以支持https访问。

Nginx

涉及到的Docker相关命令参考《Linux常用命令实践》
graph LR
    Browser -->|HTTP 80| Nginx
    Browser -->|HTTPS 443| Nginx
    Nginx -->|HTTP 9003| Spring服务

拉取 Nginx 镜像

1
2
3
4
5
6
# 拉取官方最新版 Nginx 镜像
sudo docker pull nginx:latest
# 拉不下来换个源
docker pull anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:latest
# 查看已下载的镜像
sudo docker images

运行 Nginx 容器

  • -d: 后台运行容器
  • --name my-nginx: 指定容器名称
  • -p 80:80: 将宿主机的 80 端口映射到容器的 80 端口
1
2
# 运行容器(映射宿主机 80 端口到容器 80 端口)
sudo docker run -d --name my-nginx -p 80:80 nginx

验证运行状态

1
2
3
4
5
# 查看容器状态
sudo docker ps

# 访问测试(返回 Nginx 默认欢迎页)
curl http://localhost

挂载自定义配置和静态文件

1
2
3
4
5
6
7
8
9
mkdir -p ~/nginx/
├── nginx.conf # 主配置文件
├── conf.d/
│ └── spring-proxy.conf # 子配置文件
├── ssl/
│ ├── domain.crt # SSL证书
│ └── domain.key # 私钥
├── html/ # 静态文件目录
└── logs/ # 日志目录

创建本地目录

1
mkdir -p ~/nginx/{conf,conf.d,html,logs,ssl}

文件放在宿主机,然后挂载到容器中。

宿主机 容器内
配置文件 conf/nginx.conf /etc/nginx/nginx.conf
目录 conf.d/ /etc/nginx/conf.d
日志位置 logs/ /var/log/nginx/
项目位置 /usr/share/nginx/html

conf/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
26
user  nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
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;
keepalive_timeout 65;

# 包含子配置
include /etc/nginx/conf.d/*.conf;
}

conf.d/default.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
26
27
28
29
30
31
32
33
34
35
36
37
38
# HTTP 服务配置
server {
listen 80;
# server_name localhost;

# 可选:HTTP自动跳转HTTPS(如需同时保留两种协议则不要配置此项)
# return 301 https://$host$request_uri;

location / {
proxy_pass http://localhost:9003; # 指向本地Spring服务
proxy_set_header Host $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;
}
}

# HTTPS 服务配置
server {
listen 443 ssl;
# server_name localhost;

# 自签名证书路径
ssl_certificate /etc/nginx/ssl/self_signed.crt;
ssl_certificate_key /etc/nginx/ssl/self_signed.key;

# 禁用过时的加密协议
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

location / {
proxy_pass http://localhost:9003;
proxy_set_header Host $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; # 传递实际协议类型
}
}

html/index.html

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<!DOCTYPE html>
<html>
<head><h4>Take it Easy!Please playing Game</h4></head>
<body>
<div></div>
<!-- 4个board -->
<div id="board1" style="position: absolute; width:80px; height:10px; left:420px;
top:555px; background-color: cadetblue;"></div>
<div id="board2" style="position: absolute; width:80px; height:10px; left:520px;
top:555px; background-color: cadetblue;"></div>
<div id="board3" style="position: absolute; width:80px; height:10px; left:620px;
top:555px; background-color: cadetblue;"></div>
<div id="board4" style="position: absolute; width:80px; height:10px; left:720px;
top:555px; background-color: cadetblue;"></div>
<!-- 小球 -->
<div id="ball" class="circle" style="width:20px;
height:20px; background-color:crimson; border-radius: 50%; position:absolute;
left:600px; top:100px"></div>
<!-- 框 -->
<div id="box" style="border: 5px solid #555555; width:400px; height:550px; display=hide"></div>
<!-- 分数 过的board越多,分数越高 -->
<div id="score" style="width:200px; height:10px; position:absolute; left:900px;
font-family:'隶书'; font-size: 30px;">score: 0</div>
<!-- 游戏结束 -->
<div id="gg" style="width:200px; height:10px; position:absolute; left:550px; top:200px;
font-family:'隶书'; font-size: 30px; display: none;">Game Over</div>
<script>
// 设置box的样式
var box = document.getElementById("box");
box.style.position = "absolute";
box.style.left = "400px";
// 设置board的样式
var board1 = document.getElementById("board1");
var board2 = document.getElementById("board2");
var board3 = document.getElementById("board3");
var board4 = document.getElementById("board4");
// 声音
var shengyin = new Audio();
shengyin.src = "声音2.mp3";
shengyinFlag = 0; // 用来表示小球在第几块board上
// 键盘事件函数
var ball = document.getElementById("ball");
document.onkeydown = f;
function f(e){
var e = e || window.event;
switch(e.keyCode){
case 37:
// 按下左键,小球左移,但不要超过左边框
if(ball.offsetLeft>=box.offsetLeft + 10)
ball.style.left = ball.offsetLeft - 8 + "px";
break;
case 39:
// 按下右键,小球右移,但不要超过由边框
if(ball.offsetLeft<=box.offsetLeft+box.offsetWidth-ball.offsetWidth-10)
ball.style.left = ball.offsetLeft + 8 + "px";
break;
case 32:

}
}
// 定义一个分数变量
var fenshu = 0;
// 定义一个函数,移动给定的一个board
function moveBoard(board)
{
var t1 = board.offsetTop;
if(t1<=0)
{
// 如果board移到最上面了,就随机换个水平位置,再移到最下面
t2 = Math.floor(Math.random() * (720- 420) + 420);
board.style.left = t2 + "px";
board.style.top = "555px";
fenshu += 1; //分数增加1
document.getElementById("score").innerHTML = "score " + fenshu;
}
//
else
board.style.top = board.offsetTop - 1 + "px";
}
// 定义小球的速度变量
var startSpeed = 1;
var ballSpeed =startSpeed;
// step函数是游戏界面的单位变化函数
function step()
{
// board直接上下隔得太近,就逐个移动,否则,同时移动
var t1 = Math.abs(board1.offsetTop - board2.offsetTop);
var t2 = Math.abs(board2.offsetTop - board3.offsetTop);
var t3 = Math.abs(board3.offsetTop - board4.offsetTop);
// 定义一个board之间的间隔距离
var t4 = 140;
if(t1<t4)
{
moveBoard(board1);
}
else if(t2<t4)
{
moveBoard(board1);
moveBoard(board2);
}
else if(t3<t4)
{
moveBoard(board1);
moveBoard(board2);
moveBoard(board3);
}
else
{
moveBoard(board1);
moveBoard(board2);
moveBoard(board3);
moveBoard(board4);
}
// 定义小球的垂直移动规则,1、向下匀加速运动,2、如果碰到board就被board持续抬上去,
// 直到按左右键离开了该board

// 如果小球的纵坐标等于某个board的纵坐标,就被抬起
var t5 = Math.abs(ball.offsetTop - board1.offsetTop);
var t6 = Math.abs(ball.offsetTop - board2.offsetTop);
var t7 = Math.abs(ball.offsetTop - board3.offsetTop);
var t8 = Math.abs(ball.offsetTop - board4.offsetTop);
if(t5<=ball.offsetHeight && t5>0 && ball.offsetLeft>=board1.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board1.offsetLeft+board1.offsetWidth)
{
ball.style.top = board1.offsetTop - ball.offsetHeight + "px";
ballSpeed = startSpeed;
if(shengyinFlag != 1)
{
shengyin.play();
shengyinFlag = 1;
}
}
else if(t6<=ball.offsetHeight && t6>0 && ball.offsetLeft>=board2.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board2.offsetLeft+board2.offsetWidth)
{
ball.style.top = board2.offsetTop - ball.offsetHeight + "px";
ballSpeed = startSpeed;
if(shengyinFlag != 2)
{
shengyin.play();
shengyinFlag = 2;
}
}
else if(t7<=ball.offsetHeight && t7>0 && ball.offsetLeft>=board3.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board3.offsetLeft+board3.offsetWidth)
{
ball.style.top = board3.offsetTop - ball.offsetHeight + "px";
ballSpeed = startSpeed;
if(shengyinFlag != 3)
{
shengyin.play();
shengyinFlag = 3;
}
}
else if(t8<=ball.offsetHeight && t8>0 && ball.offsetLeft>=board4.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board4.offsetLeft+board4.offsetWidth)
{
ball.style.top = board4.offsetTop - ball.offsetHeight + "px";
ballSpeed = startSpeed;
if(shengyinFlag != 4)
{
shengyin.play();
shengyinFlag = 4;
}
}
else
{
ballSpeed = ballSpeed + 0.01; // 数字相当于加速度
ball.style.top = ball.offsetTop + ballSpeed + "px";
}
// ballSpeed = ballSpeed + 0.01; // 数字相当于加速度
// ball.style.top = ball.offsetTop + ballSpeed + "px";

// 如果小球跑出来box,就结束游戏
if(ball.offsetTop==0 || ball.offsetTop>=box.offsetTop+box.offsetHeight)
{
clearInterval(gameover);
ball.style.display = 'none';
board1.style.display = 'none';
board2.style.display = 'none';
board3.style.display = 'none';
board4.style.display = 'none';
var gg = document.getElementById("gg"); //显示游戏结束
gg.style.display = 'block';
}
}

var gameover = setInterval("step();", 8);
</script>
</body>
</html>

复制默认配置文件(可选)

1
2
3
4
5
6
# 临时启动容器并复制配置文件
sudo docker run --name my-nginx -d nginx
sudo docker cp temp-nginx:/etc/nginx/nginx.conf ~/nginx/conf/
sudo docker cp temp-nginx:/etc/nginx/conf.d ~/nginx/conf/
sudo docker cp temp-nginx:/usr/share/nginx/html ~/nginx/
sudo docker rm -f temp-nginx

配置 SSL(HTTPS)

生成自签名证书(测试用)

1
2
3
4
5
6
7
8
# 创建证书存放目录
mkdir -p ~/nginx/ssl

# 生成自签名证书(有效期365天)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ~/nginx/ssl/self_signed.key \
-out ~/nginx/ssl/self_signed.crt \
-subj "/CN=localhost"

运行容器并挂载目录

  • -v: 挂载宿主机目录到容器内路径
  • :ro指read-only,默认是rw
1
2
3
4
5
6
7
8
9
docker run -d --name my-nginx \
-p 9005:80 \
-p 9004:443 \
-v ~/nginx/html:/usr/share/nginx/html \
-v ~/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v ~/nginx/conf/conf.d:/etc/nginx/conf.d \
-v ~/nginx/logs:/var/log/nginx \
-v ~/nginx/ssl:/etc/nginx/ssl:ro \
nginx

验证

1