Skip to content

Commit c9485f0

Browse files
committed
doc(deploy): update doc
1 parent ff0f33e commit c9485f0

File tree

2 files changed

+111
-13
lines changed

2 files changed

+111
-13
lines changed

post/deploy/docker-env-install.md

Lines changed: 109 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Docker 下安装多种环境
33
date: 2025-01-26
44
---
55

6-
Docker 环境搭建可参考 [docker.md](/post/deploy/docker)
6+
Docker 环境搭建可参考 [Docker 学习](/post/deploy/docker)
77

88
# Minio
99

@@ -69,7 +69,9 @@ dcoker 只支持挂载文件夹,所以 `/etc/nginx/nginx.conf` 无法映射本
6969
docker cp 容器id或名称:/etc/nginx/nginx.conf ./nginx.conf
7070
```
7171

72-
docker 默认安装的 nginx 是没有配置 80 服务的,所以我们需要去 `default.d` 文件夹下新建 `xxx.conf` 文件,这个 xxx 随便什么名字都行
72+
## 新建 test.conf 配置文件
73+
74+
docker 默认安装的 nginx 是没有配置 80 服务的,所以我们需要去本机的 `conf.d` 文件夹(映射的就是容器 `/etc/nginx/conf.d`)下新建 `test.conf` 文件,这个 test 随便什么名字都行,写入以下内容,只要是 `.conf` 结尾能让 nginx 识别到就行。
7375

7476
```bash
7577
server {
@@ -84,14 +86,14 @@ server {
8486
}
8587
```
8688

87-
由于我们将本地的 `./html` 和容器的 `/usr/share/nginx/html` 做映射,所以直接在 `html` 文件夹下新建 `index.html`,写入点东西,保存,`docker restart 容器id或名字`,访问 ip 地址即可看到 html 内容。
89+
由于我们将本地的 `./html` 和容器的 `/usr/share/nginx/html` 做映射,所以直接在 `html` 文件夹下新建 `index.html`,写入点东西,保存,`docker restart [容器id或名字]`,访问 ip 地址即可看到 html 内容。
8890

8991
# acme
9092

9193
- docker pull neilpang/acme.sh
9294
- cd /data/container && mkdir acme
9395

94-
新建 `docker-compose.yml`,去阿里云申请一个子账户,勾选权限策略 `AliyunDNSFullAccess - 管理云解析(DNS)的权限`,会生成 `id` 和 `Secret`,**一定要保存好,仅有一次查看机会**
96+
新建 `docker-compose.yml`,去阿里云 [申请一个子账户](https://ram.console.aliyun.com/users),勾选权限策略 `AliyunDNSFullAccess - 管理云解析(DNS)的权限`,会生成 `id` 和 `Secret`,**一定要保存好,仅有一次查看机会**
9597

9698
```yaml
9799
services:
@@ -108,7 +110,7 @@ services:
108110
network_mode: host
109111
```
110112

111-
- 需要注册邮箱: `docker exec acme --register-account -m [email protected]`
113+
- 注册邮箱(感觉没什么用): `docker exec acme --register-account -m [email protected]`
112114
- 注册证书: `docker exec acme --issue --dns dns_ali -d jsonq.top -d *.jsonq.top`
113115
- 如果网络执行较慢,第二步可以添加 `--server https://acme-v02.api.letsencrypt.org/directory`
114116

@@ -125,7 +127,7 @@ services:
125127

126128
## 注意事项
127129

128-
不同的运营商的 `DNS API` 不一样,这里使用 阿里云,则是 `dns_ali`,如果是其它运营商,请参考 [How to use DNS API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi)
130+
不同的运营商的 `DNS API` 不一样,这里使用 阿里云,则是 `dns_ali`,如果是其它运营商,请参考 [How to use DNS API](https://github.com/acmesh-official/acme.sh/wiki/dnsapi) 来配置 key
129131

130132
- `*.jsonq.top` 这里的 `*` 就代表泛域名
131133

@@ -149,6 +151,8 @@ crontab -e
149151
10 1 * * * docker restart nginx
150152
```
151153

154+
每天零点十分,会检查 acme 证书是否快要过期,若符合,则会自动更新证书,并在 一点十分 重启 nginx 容器
155+
152156
然后 `:wq` 保存退出
153157

154158
使用 `crontab -l` 查看定时任务是否添加成功
@@ -164,7 +168,7 @@ services:
164168
- /data/container/acme/acme:/etc/nginx/ssl
165169
```
166170

167-
然后停止 nginx 容器,重新启动,**注意,由于更改是 docker compose,所以必须停止,然后再使用 docker compose up -d 启动**
171+
然后停止 nginx 容器,重新启动,**注意,由于更改是 docker compose,所以必须停止 nginx 容器,然后再使用 docker compose up -d 启动**
168172

169173
## 修改 nginx 配置文件
170174

@@ -178,7 +182,7 @@ server {
178182
server {
179183
listen 443 ssl;
180184
http2 on;
181-
server_name xxx.com www.xxx.com;
185+
server_name jsonq.com www.jsonq.com;
182186
# root /usr/share/nginx/html;
183187
ssl_certificate "/etc/nginx/ssl/jsonq.top_ecc/jsonq.top.cer";
184188
ssl_certificate_key "/etc/nginx/ssl/jsonq.top_ecc/jsonq.top.key";
@@ -204,9 +208,9 @@ server {
204208

205209
# nginx 和 minio 网络桥接
206210

207-
现在 minio 的容器和 nginx 的容器是互不干涉的,但是我有域名之后,想让 nginx 的域名代理到 minio。所以需要将两个容器的网络桥接起来,让两个容器共享网络
211+
现在 minio 的容器和 nginx 的容器是互不干涉的,但是我有(泛)域名之后,想让 nginx 把这个域名代理到 minio。所以需要将两个容器的网络桥接起来,让两个容器共享网络
208212

209-
创建自定义网络桥接
213+
创建自定义网络桥接,个人不推荐让容器自动创建网络桥接,会导致管理混乱。
210214

211215
```bash
212216
docker network create nginx-network
@@ -309,14 +313,15 @@ RUN apk add --no-cache libc6-compat
309313
# Node v16.13 开始支持 corepack 用于管理第三方包管理器
310314
# 锁定包管理器版本,确保 CI 每次构建都是幂等的
311315
# RUN corepack enable && corepack prepare pnpm@latest --activate
316+
# 这里指定了 pnpm 和本地开发的 pnpm 版本一致,防止出现跨版本的 break change
312317
RUN corepack enable && corepack prepare [email protected] --activate
313318
314319
WORKDIR /app
315320
316321
# pnpm fetch does require only lockfile
317322
# 注意还需要复制 `.npmrc`,因为里面可能包含 npm registry 等配置,下载依赖需要用到
318-
COPY pnpm-lock.yaml ./
319-
COPY patches ./patches
323+
# !!! 不存在的文件不要写入 COPY 命令中,不然镜像会构建失败
324+
COPY package.json pnpm-lock.yaml ./
320325

321326
# 推荐使用 pnpm fetch 命令下载依赖到 virtual store,专为 docker 构建优化
322327
# 参考:https://pnpm.io/cli/fetch
@@ -393,7 +398,7 @@ CMD ["node", "server.js"]
393398

394399
Dockerfile 注意事项: **执行 COPY 命令时,COPY 的文件必须存在,否则 COPY 失败会导致镜像构建失败**
395400

396-
> 使用 `docker build -t nextjs .` 来构建镜像,其中 `nextjs` 就是镜像名,名字随便起,只要使用镜像时使用这个镜像名即可
401+
> 使用 `docker build -t nextjs .` 来构建镜像,其中 `nextjs` 就是镜像名,名字随便起只要能和项目的 `docker-compose` 使用的镜像名称保持一致即可。
397402
398403
## 编写 docker-compose 启动容器
399404

@@ -452,3 +457,94 @@ server {
452457
```
453458

454459
配置完之后,直接重启 nginx 容器即可。
460+
461+
## Github Action 实现 CI CD 自动化部署
462+
463+
此部分可以查看 [Github Action CICD 自动部署](/post/deploy/github-action-cicd.md),编写的 workflow 再往下看
464+
465+
### 编写 Github Action
466+
467+
在项目根目录新建 `.github/workflows/deploy.yml` 工作流文件
468+
469+
指定 main 分支发生 commit 变动时,会触发 workflow
470+
471+
```yml
472+
on:
473+
push:
474+
branches: main
475+
476+
jobs:
477+
deploy:
478+
runs-on: ubuntu-latest
479+
steps:
480+
- name: Checkout code
481+
uses: actions/checkout@v4
482+
483+
- name: Connect Server Deploy
484+
uses: appleboy/ssh-action@master
485+
with:
486+
host: ${{ secrets.SSH_HOST }}
487+
username: ${{ secrets.SSH_USER }}
488+
key: ${{ secrets.SSH_PRIVATE_KEY }}
489+
command_timeout: 20m
490+
script: |
491+
cd ${{ secrets.PATH_REMOTE }}
492+
MAX_RETRIES=8
493+
RETRY_COUNT=0
494+
495+
while [ $RETRY_COUNT -lt $MAX_RETRIES ]; do
496+
echo "▶️ Attempt $((RETRY_COUNT+1))/$MAX_RETRIES: Pulling code..."
497+
if git pull origin main; then
498+
echo "✅ Git pull succeeded"
499+
docker stop blog || true
500+
docker rm blog || true
501+
docker rmi nextjs || true
502+
docker build -t nextjs .
503+
docker compose up -d
504+
exit 0
505+
else
506+
echo "❌ Git pull failed (attempt $((RETRY_COUNT+1))/$MAX_RETRIES)"
507+
((RETRY_COUNT++))
508+
sleep 5
509+
fi
510+
done
511+
512+
echo "🛑 Error: Failed to pull code after $MAX_RETRIES attempts"
513+
exit 1
514+
```
515+
516+
使用 `appleboy/ssh-action` 连接远程服务器,连接成功后,执行脚本,即 `script` 部分。
517+
518+
`command_timeout` 修改为了 20 分钟,默认是 10 分钟,因为有 git pull 的错误重试机制,很容易超过 10 分钟,纯 Docker 构建都要 5 分钟左右
519+
520+
这部分内容其实很少,简单来说就是以下步骤:
521+
522+
- 拉取 GitHub 仓库的最新代码
523+
- 停止容器,删除容器
524+
- 停止镜像,删除镜像
525+
526+
为什么写了一大堆呢?其实就是 `git pull` 拉取代码失败后的重试机制,因为众所周知的问题,拉取 github 的代码经常失败(当时傻Ⅹ买了台国内服务器,结果自讨苦吃)
527+
528+
## Nextjs 开发中的踩坑
529+
530+
### 本地 http 访问 https 图片
531+
532+
http 没法访问 https,目前这里有两种方法
533+
534+
- 在项目的 `env` 中设置 `NODE_TLS_REJECT_UNAUTHORIZED=0` 绕过证书问题
535+
- 使用 next cli,`next dev --experimental-https`,这个命令在启动项目时生成一份证书临时使用
536+
537+
### 使用 next-auth 生成环境第三方授权出现 Server Error
538+
539+
环境变量设置 `AUTH_TRUST_HOST=true`,具体可查看 [next-auth issues](https://github.com/nextauthjs/next-auth/issues/3770#issuecomment-2145575926)
540+
541+
### 容器部署的 Next 项目 next-auth 无法正确推断 redirect_uri
542+
543+
虽然 next-auth 官方说可以自动推断 redirect_uri,本地确实没问题,但是 Docker 部署后的 Next 项目推断失败(笑死)
544+
545+
![image](https://img.jsonq.top/blog/2025/2/26/1740559560949-6nlv08er.png)
546+
547+
出现问题的时候,推断出来的 `redirect_uri` 是 `https//: 容器id:容器端口`,但是这种显然是无法公网访问的,而且和 Github 里配置的路径不一致,所以会出错,那就没办法了,就去 `env` 里明确一下呗
548+
549+
- `.env.development`:`AUTH_URL=http://localhost:3000/api/auth`
550+
- `.env.production`: `AUTH_URL=https://example.com/api/auth`

post/deploy/github-action-cicd.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ title: Github Action CICD 自动部署
33
date: 2024-11-14
44
---
55

6+
> 该文章的 Shell 脚本部分过于冗余,若需要看更简约更直观的,可查看 [Github Action 实现 CI CD 自动化部署](/post/deploy/docker-env-install#github-action-实现-ci-cd-自动化部署)
7+
68
使用 Github Action 的原因是,jenkins 占用的服务器资源较多,低配置服务器 jenkins 很容易资源打满。
79

810
# 了解 Github Action

0 commit comments

Comments
 (0)