Compare commits
12 Commits
99afdbd82e
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3332c6c940 | ||
|
|
a9ec40a289 | ||
|
|
fb87be680d | ||
|
|
58d65188a1 | ||
|
|
b028e6dd73 | ||
|
|
b93e85b428 | ||
|
|
8fa08f4b98 | ||
|
|
42d14a19e6 | ||
|
|
9a2defc0ee | ||
|
|
538dc1339d | ||
|
|
774cae3c02 | ||
|
|
1e5c48ffdd |
37
.codebuddy/skills/docker-build/SKILL.md
Normal file
37
.codebuddy/skills/docker-build/SKILL.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: docker-build
|
||||
description: 根据dockerfile构建镜像
|
||||
---
|
||||
|
||||
# Docker Build
|
||||
|
||||
## Overview
|
||||
|
||||
此技能用于协助完成 Docker 镜像的构建
|
||||
|
||||
## When to Use
|
||||
|
||||
根据docker file 构建镜像
|
||||
|
||||
## Core Workflow
|
||||
|
||||
### 1. 清理node1 服务器 ~/dockerbuild/ 目录下,对应项目的文件
|
||||
|
||||
|
||||
|
||||
### 2. 同步代码到node1 服务器 ~/dockerbuild/ 目录下,对应项目的文件
|
||||
|
||||
|
||||
|
||||
### 3. 执行docker build 构建镜像
|
||||
|
||||
### 4. 导出镜像,并下载到当前项目对应的把目录下
|
||||
|
||||
## node1服务器信息
|
||||
ip 10.0.3.5
|
||||
用户名 awei
|
||||
已做ssh 互信
|
||||
## 镜像命名
|
||||
- 名字保持和对应目录名称一致
|
||||
- 版本采用月日时分格式,如 04192334(4月19日23时34分)
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,8 +1,10 @@
|
||||
# Docker images
|
||||
docker-images/*.tar
|
||||
nginx/*.tar
|
||||
|
||||
# frp binary (large file)
|
||||
frpc-client/frp_*.tar.gz
|
||||
frpc-client/frp.tar.gz.b64
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
# MEMORY.md
|
||||
|
||||
## 服务器信息
|
||||
|
||||
### node1
|
||||
- **IP**: 10.0.3.5
|
||||
- **用户名**: awei
|
||||
- **SSH 互信**: 已配置
|
||||
|
||||
## Docker 镜像构建流程
|
||||
|
||||
### 关键步骤
|
||||
|
||||
1. **清理服务端目录**(避免文件残留导致问题)
|
||||
```bash
|
||||
ssh awei@10.0.3.5 "rm -rf /tmp/<目录名> && mkdir -p /tmp/<目录名>"
|
||||
```
|
||||
|
||||
2. **上传源码文件**
|
||||
```bash
|
||||
scp <本地文件> awei@10.0.3.5:/tmp/<目录名>/
|
||||
```
|
||||
|
||||
3. **构建镜像**(带版本号)
|
||||
```bash
|
||||
ssh awei@10.0.3.5 "cd /tmp/<目录名> && docker build -t stonelan/<镜像名>:YYYYMMDD -t stonelan/<镜像名>:latest ."
|
||||
```
|
||||
|
||||
4. **导出镜像**
|
||||
```bash
|
||||
ssh awei@10.0.3.5 "docker save -o /tmp/<镜像名>-YYYYMMDD.tar stonelan/<镜像名>:YYYYMMDD"
|
||||
```
|
||||
|
||||
5. **下载到本地**
|
||||
```bash
|
||||
scp awei@10.0.3.5:/tmp/<镜像名>-YYYYMMDD.tar <本地路径>/
|
||||
```
|
||||
|
||||
### 现有镜像
|
||||
|
||||
| 镜像名称 | 版本号 | 基础镜像 | 说明 |
|
||||
|---------|--------|---------|------|
|
||||
| stonelan/nginx | 1.0.1 | nginx:alpine | 反向代理,含自定义配置 |
|
||||
| stonelan/frpc | 1.0.1 | alpine:3.19 | FRP 客户端 v0.61.1 |
|
||||
|
||||
### 注意事项
|
||||
|
||||
- **版本号格式**:语义化版本 `X.Y.Z`(如 1.0.0、1.0.1、1.1.0)
|
||||
- **每次构建必须递增版本号**,避免重复
|
||||
- 构建前先清理服务端临时目录,避免旧文件干扰
|
||||
- 本地 tar.gz 等二进制文件通过 scp 传输正常,无需特殊处理
|
||||
|
||||
### 已知问题
|
||||
|
||||
- **scp 传输速度慢**:Windows OpenSSH 客户端传输速度约 0.76 MB/s(12MB 文件需 2-3 分钟),暂无解决方案
|
||||
@@ -1,47 +0,0 @@
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
navidrome:
|
||||
container_name: navidrome
|
||||
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/deluan/navidrome:pr-4181
|
||||
ports:
|
||||
- "4533:4533"
|
||||
restart: always
|
||||
environment:
|
||||
# 扫描音乐库的计划
|
||||
ND_SCANSCHEDULE: "@every 1h"
|
||||
# 日志级别
|
||||
ND_LOGLEVEL: "info"
|
||||
# 默认语言
|
||||
ND_DEFAULTLANGUAGE: "zh"
|
||||
# 会话超时时间
|
||||
ND_SESSIONTIMEOUT: "24h"
|
||||
# 启用下载功能
|
||||
ND_ENABLEDOWNLOADS: "true"
|
||||
# 启用收藏夹
|
||||
ND_ENABLEFAVOURITES: "true"
|
||||
# 启用共享功能
|
||||
ND_ENABLESHARING: "false"
|
||||
# 在 UI 中启用5星评级
|
||||
ND_ENABLESTARRATING: "true"
|
||||
# 启用转码配置
|
||||
ND_ENABLETRANSCODINGCONFIG: "true"
|
||||
# 转码缓存大小
|
||||
ND_TRANSCODINGCACHESIZE: "2000M"
|
||||
# 图片缓存大小
|
||||
ND_IMAGECACHESIZE: "1000M"
|
||||
# 音乐文件路径
|
||||
ND_MUSICFOLDER: "/music"
|
||||
# 数据路径
|
||||
ND_DATAFOLDER: "/data"
|
||||
volumes:
|
||||
# 将宿主机的数据目录挂载到容器的数据目录,用于数据持久化
|
||||
- "./data:/data"
|
||||
# 将宿主机的音乐目录挂载到容器的音乐目录,只读模式
|
||||
- "./music:/music:ro"
|
||||
networks:
|
||||
- navidrome-net
|
||||
|
||||
networks:
|
||||
navidrome-net:
|
||||
driver: bridge
|
||||
98
acme/README.md
Normal file
98
acme/README.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# 证书管理服务(acme.sh)
|
||||
|
||||
用宿主机上的 [acme.sh](https://github.com/acmesh-official/acme.sh) 管理 Let's Encrypt 证书:
|
||||
纯 Shell 实现,不依赖 Python / snap / Docker 容器。
|
||||
|
||||
## 为什么换成 acme.sh
|
||||
|
||||
之前用 certbot 容器时有个绕不开的别扭点:certbot 的 `--deploy-hook` 在**容器内**执行,
|
||||
而我们要 reload 的 nginx 是**宿主机上的容器**,只能在容器里挂 `docker.sock`(等于把宿主机
|
||||
root 交给容器),或者退而求其次每天无条件发一次 HUP。
|
||||
|
||||
acme.sh 直接跑在宿主机,`--reloadcmd` 天然在宿主机执行,**只在证书真正更新时才 reload**,
|
||||
顺带把 certbot 容器、Dockerfile、docker.sock、compose PATH 问题全部消掉。
|
||||
|
||||
## 架构
|
||||
|
||||
```
|
||||
宿主机 容器
|
||||
───────────────────────────────────── ──────────────────────────
|
||||
acme.sh(~/.acme.sh,自带 cron)
|
||||
├─ 写挑战文件 ──▶ /var/www/certbot ──bind mount(ro)──▶ nginx-proxy
|
||||
├─ 写证书 ──▶ /etc/letsencrypt ──bind mount(ro)──▶ nginx-proxy
|
||||
└─ 续签后执行 reloadcmd: docker kill -s HUP nginx-proxy
|
||||
|
||||
用户 ─▶ frps(80/443) ─▶ frpc ─▶ nginx-proxy(80/8443)
|
||||
```
|
||||
|
||||
## 目录约定
|
||||
|
||||
| 宿主机路径 | 用途 |
|
||||
|---|---|
|
||||
| `/var/www/certbot` | ACME HTTP-01 挑战文件 |
|
||||
| `/etc/letsencrypt/live/<CERT_NAME>/` | 证书(默认 CERT_NAME=stonelan.cn) |
|
||||
| `nginx/ssl.d/` | HTTPS server 块,证书就绪后由 `enable-ssl.sh` 写入 |
|
||||
|
||||
5 个域名合成**一张 SAN 证书**,放在同一个目录,nginx 的 5 个 server 块都引用它。
|
||||
|
||||
## 使用方法
|
||||
|
||||
### 1. 安装
|
||||
|
||||
```bash
|
||||
cd common-server-public/acme
|
||||
chmod +x install.sh issue.sh renew.sh check-cert.sh
|
||||
./install.sh
|
||||
```
|
||||
|
||||
### 2. 申请证书(一键引导)
|
||||
|
||||
```bash
|
||||
sudo ./issue.sh
|
||||
```
|
||||
|
||||
依次完成:建目录 → 起 nginx(此时无 HTTPS 配置)→ 申请证书 → 安装证书 →
|
||||
写入 `ssl.d/` 并重载 nginx。
|
||||
|
||||
可用环境变量覆盖:
|
||||
|
||||
```bash
|
||||
EMAIL=you@example.com \
|
||||
CERT_NAME=stonelan.cn \
|
||||
DOMAINS="fastgpt.stonelan.cn gitea.stonelan.cn image.stonelan.cn registry.stonelan.cn www.stonelan.cn" \
|
||||
sudo -E ./issue.sh
|
||||
```
|
||||
|
||||
### 3. 自动续签
|
||||
|
||||
`install.sh` 已让 acme.sh 自己写入 cron,**无需额外配置**。
|
||||
|
||||
建议再加一条兜底告警(`crontab.example`):
|
||||
|
||||
```cron
|
||||
0 8 * * * bash <绝对路径>/check-cert.sh >> /var/log/acme-check.log 2>&1
|
||||
```
|
||||
|
||||
## 故障排查
|
||||
|
||||
```bash
|
||||
acme.sh --list # 已申请的证书
|
||||
acme.sh --cron --debug 2 # 带调试跑一次续签
|
||||
./check-cert.sh # 剩余天数
|
||||
|
||||
# 确认 nginx 只加载了 HTTP 配置(冷启动时属正常)
|
||||
docker exec nginx-proxy nginx -T | grep -c "listen 8443"
|
||||
|
||||
# ACME 路径可达性
|
||||
echo probe | sudo tee /var/www/certbot/.well-known/acme-challenge/test
|
||||
curl -i http://fastgpt.stonelan.cn/.well-known/acme-challenge/test
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 需要 root(或 sudo)运行:要写 `/etc/letsencrypt` 和 `/var/www`
|
||||
2. nginx 容器 bind mount 的是**宿主机路径**,宿主机上这两个目录必须存在,
|
||||
否则 docker 会自动创建成 root 所有的空目录
|
||||
3. 挑战文件需要让容器内 nginx 可读,目录保持 755(`issue.sh` 已处理)
|
||||
4. CA 已显式固定为 Let's Encrypt(acme.sh 3.x 默认是 ZeroSSL)
|
||||
5. 证书有效期 90 天,acme.sh 默认在剩余 30 天内续签
|
||||
32
acme/check-cert.sh
Normal file
32
acme/check-cert.sh
Normal file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# 检查证书剩余有效期,低于阈值时以非 0 退出,便于接入告警。
|
||||
# 自动续签有可能静默失败,必须有一个独立的检查点。
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
CERT_NAME="${CERT_NAME:-stonelan.cn}"
|
||||
CERT="${CERT:-/etc/letsencrypt/live/$CERT_NAME/cert.pem}"
|
||||
WARN_DAYS="${WARN_DAYS:-20}"
|
||||
|
||||
if [ ! -f "$CERT" ]; then
|
||||
echo "证书不存在:$CERT" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
end="$(openssl x509 -enddate -noout -in "$CERT" | cut -d= -f2)"
|
||||
end_ts="$(date -d "$end" +%s)"
|
||||
days=$(( (end_ts - $(date +%s)) / 86400 ))
|
||||
|
||||
echo "证书文件:$CERT"
|
||||
echo "到期时间:$end(剩余 $days 天)"
|
||||
openssl x509 -subject -issuer -noout -in "$CERT" | sed 's/^/ /'
|
||||
openssl x509 -text -noout -in "$CERT" \
|
||||
| grep -A1 "Subject Alternative Name" | sed 's/^/ /'
|
||||
|
||||
if [ "$days" -lt "$WARN_DAYS" ]; then
|
||||
echo "警告:剩余 $days 天,低于阈值 $WARN_DAYS 天" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "证书状态正常"
|
||||
10
acme/crontab.example
Normal file
10
acme/crontab.example
Normal file
@@ -0,0 +1,10 @@
|
||||
# acme.sh 安装时会自动写入一条 cron(每天执行 ~/.acme.sh/acme.sh --cron),
|
||||
# 续签成功后自动执行 --reloadcmd,所以续签本身不需要再配 cron。
|
||||
#
|
||||
# 这里只需要一个"有效期检查"作为兜底告警:
|
||||
# 自动续签可能静默失败,剩余天数低于 20 天时脚本以非 0 退出。
|
||||
|
||||
0 8 * * * bash /home/awei/workspace/common-server-public/acme/check-cert.sh >> /var/log/acme-check.log 2>&1
|
||||
|
||||
# 如需强制每天显式跑一次续签(一般不必),可加:
|
||||
# 0 3 * * * bash /home/awei/workspace/common-server-public/acme/renew.sh >> /var/log/acme-renew.log 2>&1
|
||||
25
acme/install.sh
Normal file
25
acme/install.sh
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# 安装 acme.sh(纯 Shell ACME 客户端,不依赖 Python / 容器 / snap)
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
EMAIL="${EMAIL:-admin@stonelan.cn}"
|
||||
ACME="${ACME:-$HOME/.acme.sh/acme.sh}"
|
||||
|
||||
if [ -s "$ACME" ]; then
|
||||
echo "acme.sh 已安装:$ACME"
|
||||
else
|
||||
echo "==> 安装 acme.sh"
|
||||
curl https://get.acme.sh | sh -s email="$EMAIL"
|
||||
fi
|
||||
|
||||
# acme.sh 3.x 默认 CA 是 ZeroSSL,这里显式固定为 Let's Encrypt
|
||||
"$ACME" --set-default-ca --server letsencrypt
|
||||
|
||||
echo "==> acme.sh 就绪"
|
||||
"$ACME" --version
|
||||
|
||||
# 安装脚本会自动写入一条 cron(每天执行 acme.sh --cron),无需再手配续签
|
||||
echo "==> 已注册的 cron:"
|
||||
crontab -l 2>/dev/null | grep acme.sh || echo " (未找到,请手动添加,参考 crontab.example)"
|
||||
61
acme/issue.sh
Normal file
61
acme/issue.sh
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# 首次申请证书并启用 HTTPS(完整引导)。
|
||||
#
|
||||
# 1. 准备宿主机目录:acme.sh 写挑战文件,nginx 容器 bind mount 只读
|
||||
# 2. 启动 nginx —— 此时 ssl.d/ 为空,只加载 80 端口配置,不依赖证书
|
||||
# 3. 申请 SAN 证书(webroot 验证,挑战文件由 nginx 直接对外提供)
|
||||
# 4. 把证书安装到 /etc/letsencrypt/live/<CERT_NAME>/
|
||||
# --reloadcmd 会被 acme.sh 记住,之后每次自动续签都执行
|
||||
# 5. 启用 HTTPS server 块并重载 nginx
|
||||
#
|
||||
# 需要 root 权限(要写 /etc/letsencrypt 与 /var/www):sudo bash issue.sh
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
NGINX_DIR="$SCRIPT_DIR/../nginx"
|
||||
|
||||
EMAIL="${EMAIL:-admin@stonelan.cn}"
|
||||
CERT_NAME="${CERT_NAME:-stonelan.cn}"
|
||||
WEBROOT="${WEBROOT:-/var/www/certbot}"
|
||||
CERT_HOME="${CERT_HOME:-/etc/letsencrypt/live/$CERT_NAME}"
|
||||
DOMAINS="${DOMAINS:-fastgpt.stonelan.cn gitea.stonelan.cn image.stonelan.cn registry.stonelan.cn www.stonelan.cn}"
|
||||
ACME="${ACME:-$HOME/.acme.sh/acme.sh}"
|
||||
|
||||
# acme.sh 的 Main_Domain 就是 -d 列表的第一个,--install-cert 要用它
|
||||
PRIMARY="${DOMAINS%% *}"
|
||||
|
||||
if [ ! -s "$ACME" ]; then
|
||||
echo "未找到 acme.sh,请先执行:$SCRIPT_DIR/install.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 1. 目录
|
||||
mkdir -p "$WEBROOT/.well-known/acme-challenge" "$CERT_HOME"
|
||||
chmod 755 "$WEBROOT" "$WEBROOT/.well-known" "$WEBROOT/.well-known/acme-challenge"
|
||||
|
||||
# 2. nginx(无证书也能起来)
|
||||
echo "==> 启动 nginx"
|
||||
docker compose -f "$NGINX_DIR/docker-compose.yml" up -d
|
||||
|
||||
# 3. 申请
|
||||
args=()
|
||||
for d in $DOMAINS; do
|
||||
args+=(-d "$d")
|
||||
done
|
||||
|
||||
echo "==> 申请证书(主域 $PRIMARY,共 $(echo $DOMAINS | wc -w) 个域名):$DOMAINS"
|
||||
"$ACME" --issue --webroot "$WEBROOT" --server letsencrypt "${args[@]}"
|
||||
|
||||
# 4. 安装证书
|
||||
echo "==> 安装证书到 $CERT_HOME"
|
||||
"$ACME" --install-cert -d "$PRIMARY" \
|
||||
--cert-file "$CERT_HOME/cert.pem" \
|
||||
--key-file "$CERT_HOME/privkey.pem" \
|
||||
--fullchain-file "$CERT_HOME/fullchain.pem" \
|
||||
--reloadcmd "docker kill -s HUP nginx-proxy"
|
||||
|
||||
# 5. 启用 HTTPS
|
||||
echo "==> 启用 HTTPS 配置"
|
||||
exec bash "$NGINX_DIR/enable-ssl.sh"
|
||||
20
acme/renew.sh
Normal file
20
acme/renew.sh
Normal file
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# 手动触发一次续签检查。
|
||||
#
|
||||
# acme.sh 安装时已经自动写入了 cron(每天 ~/.acme.sh/acme.sh --cron),
|
||||
# 正常情况下不需要手动执行,这个脚本只是方便排查和立即验证。
|
||||
# 续签成功时 acme.sh 会自动执行 issue.sh 里登记的 --reloadcmd。
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
ACME="${ACME:-$HOME/.acme.sh/acme.sh}"
|
||||
|
||||
if [ ! -s "$ACME" ]; then
|
||||
echo "未找到 acme.sh,请先执行本目录下的 install.sh" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 开始续签检查"
|
||||
"$ACME" --cron
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 续签检查完成"
|
||||
@@ -1,39 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 定义变量
|
||||
DOMAIN="registry.deepseak.icu" # 主域名
|
||||
ADDITIONAL_DOMAINS=("active.deepseak.icu" "bbs.deepseak.icu" "image.deepseak.icu" "gitea.deepseak.icu") # 额外域名
|
||||
EMAIL="hpuzhagnwei@163.com" # 请替换为你的邮箱地址
|
||||
|
||||
# 检查 Certbot 是否安装
|
||||
if ! command -v certbot &> /dev/null
|
||||
then
|
||||
echo "Certbot 未安装,开始安装..."
|
||||
sudo apt update
|
||||
sudo apt install -y certbot python3-certbot-nginx
|
||||
fi
|
||||
|
||||
# 申请证书
|
||||
echo "开始申请证书..."
|
||||
|
||||
# 构建域名参数
|
||||
DOMAIN_ARGS="-d $DOMAIN"
|
||||
for domain in "${ADDITIONAL_DOMAINS[@]}"; do
|
||||
DOMAIN_ARGS="$DOMAIN_ARGS -d $domain"
|
||||
done
|
||||
|
||||
sudo certbot certonly --nginx $DOMAIN_ARGS --email $EMAIL --agree-tos --no-eff-email
|
||||
|
||||
# 检查证书是否申请成功
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "证书申请成功!"
|
||||
else
|
||||
echo "证书申请失败,请检查错误信息。"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# 安装自动续期任务
|
||||
# echo "安装自动续期任务..."
|
||||
# (crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/certbot renew --quiet") | crontab -
|
||||
|
||||
# echo "自动续期任务安装成功!"
|
||||
3
csp-task.md
Normal file
3
csp-task.md
Normal file
@@ -0,0 +1,3 @@
|
||||
|
||||
1. nginx配置有更改,构建新的镜像 ,
|
||||
2. scp部署到100.66.1.5 这个机器上 用户名admin 密码 admin123
|
||||
@@ -1,151 +0,0 @@
|
||||
# Dolibarr ERP/CRM Docker部署指南
|
||||
|
||||
本指南将帮助您使用Docker Compose快速部署Dolibarr ERP/CRM系统。
|
||||
|
||||
## 功能特点
|
||||
|
||||
- 使用官方Dolibarr Docker镜像
|
||||
- 集成MariaDB数据库
|
||||
- 数据持久化存储
|
||||
- 可自定义配置
|
||||
|
||||
## 系统要求
|
||||
|
||||
- Docker 18.06.0+
|
||||
- Docker Compose 1.22.0+
|
||||
|
||||
## 部署步骤
|
||||
|
||||
### 1. 克隆或下载配置文件
|
||||
|
||||
确保您已经在`dolibarr`目录下有`docker-compose.yml`文件。
|
||||
|
||||
### 2. 启动服务
|
||||
|
||||
在`dolibarr`目录下执行以下命令:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
这将启动两个容器:
|
||||
- `dolibarr`:Dolibarr ERP/CRM应用
|
||||
- `dolibarr_db`:MariaDB数据库
|
||||
|
||||
### 3. 访问Dolibarr
|
||||
|
||||
启动完成后,通过以下地址访问Dolibarr:
|
||||
|
||||
```
|
||||
http://localhost:8080
|
||||
```
|
||||
|
||||
### 4. 完成安装
|
||||
|
||||
首次访问时,您需要完成Dolibarr的安装配置:
|
||||
|
||||
1. 选择您的语言并点击"开始安装"
|
||||
2. 检查系统需求(应该都是绿色的)
|
||||
3. 数据库配置:
|
||||
- 数据库类型:MySQL
|
||||
- 数据库服务器:db
|
||||
- 数据库名称:dolibarr
|
||||
- 数据库用户:dolibarr
|
||||
- 数据库密码:dolibarr_password
|
||||
4. 点击"测试连接"并确认连接成功
|
||||
5. 完成剩余的安装步骤
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 环境变量
|
||||
|
||||
在`docker-compose.yml`文件中,您可以修改以下环境变量:
|
||||
|
||||
- `DOLI_ADMIN_LOGIN`:Dolibarr管理员用户名(默认:admin)
|
||||
- `DOLI_ADMIN_PASSWORD`:Dolibarr管理员密码(默认:admin_password)
|
||||
- `DOLI_URL_ROOT`:Dolibarr访问URL(默认:http://localhost:8080)
|
||||
- `MYSQL_ROOT_PASSWORD`:MariaDB root用户密码(默认:root_password)
|
||||
- `MYSQL_DATABASE`:数据库名称(默认:dolibarr)
|
||||
- `MYSQL_USER`:数据库用户名(默认:dolibarr)
|
||||
- `MYSQL_PASSWORD`:数据库密码(默认:dolibarr_password)
|
||||
|
||||
### 端口映射
|
||||
|
||||
默认将Dolibarr的80端口映射到主机的8080端口。您可以通过修改`ports`部分来更改:
|
||||
|
||||
```yaml
|
||||
ports:
|
||||
- "您选择的端口:80"
|
||||
```
|
||||
|
||||
### 数据持久化
|
||||
|
||||
使用Docker卷来持久化存储数据:
|
||||
- `dolibarr_html`:存储Dolibarr应用文件
|
||||
- `dolibarr_documents`:存储Dolibarr文档和上传文件
|
||||
- `dolibarr_db`:存储MariaDB数据库数据
|
||||
|
||||
## 管理命令
|
||||
|
||||
### 查看日志
|
||||
|
||||
```bash
|
||||
# 查看Dolibarr日志
|
||||
docker-compose logs dolibarr
|
||||
|
||||
# 查看数据库日志
|
||||
docker-compose logs db
|
||||
|
||||
# 查看所有日志
|
||||
docker-compose logs
|
||||
```
|
||||
|
||||
### 停止服务
|
||||
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
### 重启服务
|
||||
|
||||
```bash
|
||||
docker-compose restart
|
||||
```
|
||||
|
||||
### 更新服务
|
||||
|
||||
```bash
|
||||
# 拉取最新镜像
|
||||
docker-compose pull
|
||||
|
||||
# 重新启动服务
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
## 安全建议
|
||||
|
||||
1. 生产环境中请修改默认密码
|
||||
2. 考虑使用HTTPS协议访问
|
||||
3. 定期备份数据卷
|
||||
4. 限制容器的网络访问
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q: 无法访问Dolibarr?
|
||||
A: 检查容器是否正在运行,端口是否正确映射,以及防火墙设置。
|
||||
|
||||
### Q: 忘记管理员密码?
|
||||
A: 您可以通过修改数据库中的`llx_user`表来重置密码,或者在环境变量中重新设置`DOLI_ADMIN_PASSWORD`并重启容器。
|
||||
|
||||
### Q: 如何备份数据?
|
||||
A: 您可以使用`docker cp`命令将数据卷中的内容复制到本地:
|
||||
|
||||
```bash
|
||||
docker cp dolibarr:/var/www/html ./backup/html
|
||||
docker cp dolibarr:/var/www/documents ./backup/documents
|
||||
docker exec dolibarr_db mysqldump -u root -proot_password dolibarr > ./backup/dolibarr.sql
|
||||
```
|
||||
|
||||
## 联系方式
|
||||
|
||||
如有问题,请参考[Dolibarr官方文档](https://wiki.dolibarr.org/index.php/Main_Page)或[Docker Hub页面](https://hub.docker.com/r/dolibarr/dolibarr/)。
|
||||
@@ -1,42 +0,0 @@
|
||||
version: '3.7'
|
||||
|
||||
services:
|
||||
# Dolibarr ERP/CRM
|
||||
dolibarr:
|
||||
image: dolibarr/dolibarr:latest
|
||||
container_name: dolibarr
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "8080:80"
|
||||
depends_on:
|
||||
- db
|
||||
environment:
|
||||
- DOLI_DB_HOST=db
|
||||
- DOLI_DB_USER=dolibarr
|
||||
- DOLI_DB_PASSWORD=dolibarr_password
|
||||
- DOLI_DB_NAME=dolibarr
|
||||
- DOLI_ADMIN_LOGIN=admin
|
||||
- DOLI_ADMIN_PASSWORD=admin_password
|
||||
- DOLI_URL_ROOT=http://localhost:8080
|
||||
volumes:
|
||||
- dolibarr_html:/var/www/html
|
||||
- dolibarr_documents:/var/www/documents
|
||||
|
||||
# MariaDB Database
|
||||
db:
|
||||
image: mariadb:10.6
|
||||
container_name: dolibarr_db
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- MYSQL_ROOT_PASSWORD=root_password
|
||||
- MYSQL_DATABASE=dolibarr
|
||||
- MYSQL_USER=dolibarr
|
||||
- MYSQL_PASSWORD=dolibarr_password
|
||||
volumes:
|
||||
- dolibarr_db:/var/lib/mysql
|
||||
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
|
||||
|
||||
volumes:
|
||||
dolibarr_html:
|
||||
dolibarr_documents:
|
||||
dolibarr_db:
|
||||
@@ -1,6 +1,6 @@
|
||||
services:
|
||||
frpc:
|
||||
image: frpc-client:latest
|
||||
image: frpc-client:09051708
|
||||
container_name: frpc-client
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
|
||||
265663
frpc-client/frp.tar.gz.b64
265663
frpc-client/frp.tar.gz.b64
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -1,47 +1,19 @@
|
||||
# frpc 基础配置
|
||||
serverAddr = "47.239.121.24"
|
||||
serverPort = 7000
|
||||
auth.method = "token"
|
||||
auth.token = "8f3c9b7d5e2a4f6h1i0j"
|
||||
|
||||
[[proxies]]
|
||||
name = "http"
|
||||
type = "tcp"
|
||||
localIP = "nginx-proxy"
|
||||
localPort = 80
|
||||
remotePort = 80
|
||||
|
||||
[[proxies]]
|
||||
name = "https"
|
||||
type = "tcp"
|
||||
localIP = "10.0.3.148"
|
||||
localPort = 4430
|
||||
remotePort = 443
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# frpc 基础配置
|
||||
serverAddr = "47.113.230.48"
|
||||
serverPort = 7000
|
||||
auth.method = "token"
|
||||
auth.token = "8f3c9b7d5e2a4f6h1i0j"
|
||||
|
||||
[[proxies]]
|
||||
name = "http"
|
||||
type = "tcp"
|
||||
localIP = "nginx-proxy"
|
||||
localPort = 80
|
||||
remotePort = 80
|
||||
|
||||
[[proxies]]
|
||||
name = "https"
|
||||
type = "tcp"
|
||||
localIP = "nginx-proxy"
|
||||
localPort = 8443
|
||||
remotePort = 443
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
# Nginx Docker image
|
||||
# 包含自定义配置的反向代理
|
||||
# 使用官方 Nginx 镜像
|
||||
FROM nginx:09051708
|
||||
|
||||
FROM nginx:alpine
|
||||
# 维护者信息
|
||||
LABEL maintainer="awei"
|
||||
LABEL description="HTTP server with SSL support"
|
||||
|
||||
LABEL maintainer="StoneLan"
|
||||
LABEL description="Nginx reverse proxy container"
|
||||
|
||||
# 复制 nginx 配置
|
||||
# 复制配置文件
|
||||
# 先清理基础镜像中可能残留的旧配置,再写入新配置
|
||||
# conf.d 只放不依赖证书的常驻配置(80 端口:ACME 验证 + HTTPS 跳转)
|
||||
COPY nginx.conf /etc/nginx/nginx.conf
|
||||
RUN rm -rf /etc/nginx/conf.d/*
|
||||
COPY conf.d /etc/nginx/conf.d
|
||||
COPY verification.html /usr/share/nginx/html/verification.html
|
||||
|
||||
# 创建必要的目录
|
||||
RUN mkdir -p /var/log/nginx && \
|
||||
mkdir -p /etc/nginx/ssl && \
|
||||
chown -R nginx:nginx /var/log/nginx && \
|
||||
chown -R nginx:nginx /etc/nginx
|
||||
# 创建日志目录与 HTTPS 配置目录
|
||||
# ssl.d 必须存在:nginx.conf 里的 wildcard include 在目录不存在时会报 emerg
|
||||
RUN mkdir -p /var/log/nginx /etc/nginx/ssl.d
|
||||
|
||||
EXPOSE 80 443
|
||||
# 暴露端口
|
||||
EXPOSE 80
|
||||
EXPOSE 8443
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://localhost/health || exit 1
|
||||
# 健康检查:/healthz 固定返回 200,不跟随 301,冷启动阶段也不会误判
|
||||
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
||||
CMD wget --quiet --tries=1 -O /dev/null http://127.0.0.1/healthz || exit 1
|
||||
|
||||
# 启动 Nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
30
nginx/conf.d/00-http.conf
Normal file
30
nginx/conf.d/00-http.conf
Normal file
@@ -0,0 +1,30 @@
|
||||
# HTTP 入口:ACME 验证 + HTTPS 跳转
|
||||
#
|
||||
# 【关键】这个文件必须常驻,且不能引用任何证书文件。
|
||||
# 首次部署时证书尚不存在,如果 nginx 加载了带 ssl_certificate 的 server 块,
|
||||
# 会直接 [emerg] cannot load certificate 退出;而申请证书又必须要有 80 端口可用
|
||||
# —— 形成死锁。因此所有 HTTPS server 块统一放到 /etc/nginx/ssl.d/,
|
||||
# 由 nginx/enable-ssl.sh 在证书就绪后再启用。
|
||||
server {
|
||||
listen 80 default_server;
|
||||
server_name _;
|
||||
|
||||
# 健康检查探针(容器 HEALTHCHECK 使用),不跟随 301
|
||||
location = /healthz {
|
||||
access_log off;
|
||||
default_type text/plain;
|
||||
return 200 "ok\n";
|
||||
}
|
||||
|
||||
# ACME HTTP-01 验证
|
||||
# acme.sh 通过 webroot 写入 /var/www/certbot/.well-known/acme-challenge/<token>
|
||||
# 这是宿主机目录,nginx 容器以只读方式 bind mount
|
||||
location /.well-known/acme-challenge/ {
|
||||
root /var/www/certbot;
|
||||
default_type text/plain;
|
||||
}
|
||||
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name gitea.membank.xyz;
|
||||
client_max_body_size 200m;
|
||||
location / {
|
||||
proxy_pass http://gitea:3000;
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name image.membank.xyz;
|
||||
|
||||
location / {
|
||||
proxy_pass http://10.0.3.14:3004;
|
||||
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;
|
||||
|
||||
# 添加代理超时配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name membank.membank.xyz;
|
||||
|
||||
location / {
|
||||
proxy_pass http://10.0.3.148:3000;
|
||||
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;
|
||||
|
||||
# 添加代理超时配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
location /bbs-go {
|
||||
proxy_pass http://10.0.3.148:9000;
|
||||
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;
|
||||
|
||||
# 添加代理超时配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name navidrome.membank.xyz;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:4533;
|
||||
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;
|
||||
|
||||
# 添加代理超时配置
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
|
||||
# 针对Navidrome的特殊配置
|
||||
# 支持大文件上传和流媒体传输
|
||||
client_max_body_size 100M;
|
||||
proxy_buffering off;
|
||||
|
||||
# 启用gzip压缩
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
gzip_proxied any;
|
||||
gzip_comp_level 6;
|
||||
gzip_types
|
||||
text/plain
|
||||
text/css
|
||||
text/xml
|
||||
text/javascript
|
||||
application/json
|
||||
application/javascript
|
||||
application/xml+rss
|
||||
application/atom+xml
|
||||
image/svg+xml;
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name registry.membank.xyz;
|
||||
client_max_body_size 500m;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3005;
|
||||
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;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,21 @@
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
image: nginx:09051708
|
||||
container_name: nginx-proxy
|
||||
ports:
|
||||
- "8081:80"
|
||||
- "4430:443"
|
||||
- "8443:8443"
|
||||
volumes:
|
||||
- ./conf.d:/etc/nginx/conf.d:ro
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
# 证书:宿主机 acme.sh 写入,nginx 只读
|
||||
- /etc/letsencrypt:/etc/letsencrypt:ro
|
||||
# ACME HTTP-01 挑战文件:宿主机 acme.sh 写入,nginx 只读
|
||||
- /var/www/certbot:/var/www/certbot:ro
|
||||
# HTTPS server 块:默认为空,证书就绪后由 enable-ssl.sh 写入
|
||||
- ./ssl.d:/etc/nginx/ssl.d:ro
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- trim-default
|
||||
|
||||
networks:
|
||||
trim-default:
|
||||
external: true
|
||||
|
||||
59
nginx/enable-ssl.sh
Normal file
59
nginx/enable-ssl.sh
Normal file
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# 启用 HTTPS 配置:证书就绪后,把 ssl.d.available/ 下的 server 块
|
||||
# 复制进 ssl.d/(nginx 容器 bind mount 并 include 的目录),校验后优雅重载 nginx。
|
||||
#
|
||||
# 冷启动时 ssl.d/ 为空,nginx 只加载 conf.d/00-http.conf(不引用证书),
|
||||
# 因此可以在没有证书的情况下启动并提供 80 端口 —— 这是打破
|
||||
# "先有证书还是先有 nginx" 死锁的关键。
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
AVAILABLE="$SCRIPT_DIR/ssl.d.available"
|
||||
ENABLED="$SCRIPT_DIR/ssl.d"
|
||||
|
||||
CERT_NAME="${CERT_NAME:-stonelan.cn}"
|
||||
CERT_FULL="/etc/letsencrypt/live/$CERT_NAME/fullchain.pem"
|
||||
DOMAINS="${DOMAINS:-fastgpt.stonelan.cn gitea.stonelan.cn image.stonelan.cn registry.stonelan.cn www.stonelan.cn}"
|
||||
|
||||
# 证书在宿主机上,直接判断即可(不再需要进容器)
|
||||
if [ ! -f "$CERT_FULL" ]; then
|
||||
echo "证书尚未生成:$CERT_FULL"
|
||||
echo "请先执行 acme/issue.sh,成功后再运行本脚本"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
mkdir -p "$ENABLED"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
copied=()
|
||||
for d in $DOMAINS; do
|
||||
conf="$AVAILABLE/$d.conf"
|
||||
if [ ! -f "$conf" ]; then
|
||||
echo "跳过 $d:缺少 $conf"
|
||||
continue
|
||||
fi
|
||||
|
||||
if ! cmp -s "$conf" "$ENABLED/$d.conf" 2>/dev/null; then
|
||||
cp "$conf" "$ENABLED/$d.conf"
|
||||
copied+=("$ENABLED/$d.conf")
|
||||
echo "已启用 $d"
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "${#copied[@]}" -eq 0 ]; then
|
||||
echo "HTTPS 配置已是最新,无需变更"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if out=$(docker compose exec -T nginx-proxy nginx -t 2>&1); then
|
||||
echo "$out" | sed 's/^/ /'
|
||||
docker kill -s HUP nginx-proxy
|
||||
echo "nginx 已重载,HTTPS 配置生效"
|
||||
else
|
||||
echo "$out" | sed 's/^/ /'
|
||||
echo "nginx 配置校验失败,回滚本次变更" >&2
|
||||
rm -f "${copied[@]}"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,29 +1,34 @@
|
||||
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;
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
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;
|
||||
|
||||
|
||||
}
|
||||
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;
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
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;
|
||||
|
||||
# HTTPS server 块按需加载:
|
||||
# 该目录默认为空(nginx 的 wildcard include 匹配 0 个文件时不报错),
|
||||
# 证书申请成功后由 enable-ssl.sh 写入配置,从而避免冷启动时
|
||||
# 因证书文件不存在导致 nginx 拒绝启动。
|
||||
include /etc/nginx/ssl.d/*.conf;
|
||||
|
||||
}
|
||||
|
||||
@@ -1,24 +1,35 @@
|
||||
# HTTPS 配置 —— fastgpt.stonelan.cn
|
||||
# 5 个域名共用一张 SAN 证书,统一放在 /etc/letsencrypt/live/stonelan.cn/。
|
||||
# 由 nginx/enable-ssl.sh 在证书就绪后复制到 ssl.d/ 才会被 nginx 加载。
|
||||
server {
|
||||
listen 80;
|
||||
server_name fastgpt.membank.xyz;
|
||||
|
||||
listen 8443 ssl;
|
||||
server_name fastgpt.stonelan.cn;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/stonelan.cn/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/stonelan.cn/privkey.pem;
|
||||
|
||||
# SSL 优化配置
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_tickets off;
|
||||
|
||||
location / {
|
||||
proxy_pass http://10.0.3.14:3000;
|
||||
proxy_pass http://10.0.3.173:3000;
|
||||
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;
|
||||
|
||||
# 添加代理超时配置
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
|
||||
# 支持大文件上传和API请求
|
||||
|
||||
client_max_body_size 100M;
|
||||
proxy_buffering off;
|
||||
|
||||
# 启用gzip压缩
|
||||
|
||||
gzip on;
|
||||
gzip_vary on;
|
||||
gzip_min_length 1024;
|
||||
@@ -35,4 +46,4 @@ server {
|
||||
application/atom+xml
|
||||
image/svg+xml;
|
||||
}
|
||||
}
|
||||
}
|
||||
30
nginx/ssl.d.available/gitea.conf
Normal file
30
nginx/ssl.d.available/gitea.conf
Normal file
@@ -0,0 +1,30 @@
|
||||
# HTTPS 配置 —— gitea.stonelan.cn
|
||||
# 5 个域名共用一张 SAN 证书,统一放在 /etc/letsencrypt/live/stonelan.cn/。
|
||||
# 由 nginx/enable-ssl.sh 在证书就绪后复制到 ssl.d/ 才会生效。
|
||||
server {
|
||||
listen 8443 ssl;
|
||||
server_name gitea.stonelan.cn;
|
||||
client_max_body_size 200m;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/stonelan.cn/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/stonelan.cn/privkey.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_tickets off;
|
||||
|
||||
location / {
|
||||
proxy_pass http://gitea:3000;
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
29
nginx/ssl.d.available/image.conf
Normal file
29
nginx/ssl.d.available/image.conf
Normal file
@@ -0,0 +1,29 @@
|
||||
# HTTPS 配置 —— image.stonelan.cn
|
||||
# 5 个域名共用一张 SAN 证书,统一放在 /etc/letsencrypt/live/stonelan.cn/。
|
||||
# 由 nginx/enable-ssl.sh 在证书就绪后复制到 ssl.d/ 才会生效。
|
||||
server {
|
||||
listen 8443 ssl;
|
||||
server_name image.stonelan.cn;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/stonelan.cn/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/stonelan.cn/privkey.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_tickets off;
|
||||
|
||||
location / {
|
||||
proxy_pass http://10.0.3.173:3004;
|
||||
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;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
30
nginx/ssl.d.available/registry.conf
Normal file
30
nginx/ssl.d.available/registry.conf
Normal file
@@ -0,0 +1,30 @@
|
||||
# HTTPS 配置 —— registry.stonelan.cn
|
||||
# 5 个域名共用一张 SAN 证书,统一放在 /etc/letsencrypt/live/stonelan.cn/。
|
||||
# 由 nginx/enable-ssl.sh 在证书就绪后复制到 ssl.d/ 才会生效。
|
||||
server {
|
||||
listen 8443 ssl;
|
||||
server_name registry.stonelan.cn;
|
||||
client_max_body_size 500m;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/stonelan.cn/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/stonelan.cn/privkey.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_tickets off;
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:3005;
|
||||
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;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
29
nginx/ssl.d.available/www.conf
Normal file
29
nginx/ssl.d.available/www.conf
Normal file
@@ -0,0 +1,29 @@
|
||||
# HTTPS 配置 —— www.stonelan.cn
|
||||
# 5 个域名共用一张 SAN 证书,统一放在 /etc/letsencrypt/live/stonelan.cn/。
|
||||
# 由 nginx/enable-ssl.sh 在证书就绪后复制到 ssl.d/ 才会生效。
|
||||
server {
|
||||
listen 8443 ssl;
|
||||
server_name www.stonelan.cn;
|
||||
|
||||
ssl_certificate /etc/letsencrypt/live/stonelan.cn/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/stonelan.cn/privkey.pem;
|
||||
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers off;
|
||||
ssl_session_cache shared:SSL:10m;
|
||||
ssl_session_timeout 1d;
|
||||
ssl_session_tickets off;
|
||||
|
||||
location / {
|
||||
proxy_pass http://10.0.3.173:8080;
|
||||
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;
|
||||
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
2
nginx/ssl.d/.gitkeep
Normal file
2
nginx/ssl.d/.gitkeep
Normal file
@@ -0,0 +1,2 @@
|
||||
# nginx 从这里加载 HTTPS 配置(wildcard include,目录为空时 nginx 正常启动)。
|
||||
# 首次申请证书前本目录为空,由 ../enable-ssl.sh 按需写入。
|
||||
@@ -1,4 +1,8 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# 把仓库里的 nginx 配置同步到宿主机 nginx(非容器部署路径)。
|
||||
#
|
||||
set -euo pipefail
|
||||
|
||||
# 检查并创建nginx用户
|
||||
if ! id -u nginx >/dev/null 2>&1; then
|
||||
@@ -6,31 +10,55 @@ if ! id -u nginx >/dev/null 2>&1; then
|
||||
sudo useradd -r -s /sbin/nologin nginx
|
||||
fi
|
||||
|
||||
# 创建 conf.d 目录(如果不存在)
|
||||
sudo mkdir -p /etc/nginx/conf.d
|
||||
# 创建配置目录(ssl.d 必须存在,nginx.conf 里的 wildcard include 在目录缺失时会报 emerg)
|
||||
sudo mkdir -p /etc/nginx/conf.d /etc/nginx/ssl.d
|
||||
|
||||
# 备份并覆盖 nginx.conf 文件
|
||||
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak
|
||||
sudo cp nginx.conf /etc/nginx/
|
||||
|
||||
# 备份并覆盖 conf.d 目录下的所有 .conf 文件
|
||||
# 备份并覆盖 conf.d 目录下的所有 .conf 文件(只放不依赖证书的配置)
|
||||
for conf in conf.d/*.conf; do
|
||||
filename=$(basename "$conf")
|
||||
sudo cp "/etc/nginx/conf.d/$filename" "/etc/nginx/conf.d/${filename}.bak" 2>/dev/null || true
|
||||
sudo cp "$conf" /etc/nginx/conf.d/
|
||||
done
|
||||
|
||||
# HTTPS 配置:证书就绪后才启用,避免 nginx 因证书缺失拒绝启动
|
||||
# 5 个域名共用一张 SAN 证书,统一放在 CERT_NAME 目录下
|
||||
CERT_NAME="${CERT_NAME:-stonelan.cn}"
|
||||
CERT_FULL="/etc/letsencrypt/live/$CERT_NAME/fullchain.pem"
|
||||
DOMAINS="${DOMAINS:-fastgpt.stonelan.cn gitea.stonelan.cn image.stonelan.cn registry.stonelan.cn www.stonelan.cn}"
|
||||
|
||||
if [ -f "$CERT_FULL" ]; then
|
||||
for d in $DOMAINS; do
|
||||
src="ssl.d.available/$d.conf"
|
||||
if [ -f "$src" ]; then
|
||||
sudo cp "$src" "/etc/nginx/ssl.d/$d.conf"
|
||||
echo "已启用 $d"
|
||||
else
|
||||
echo "跳过 $d:缺少 $src"
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo "证书尚未生成($CERT_FULL),跳过 HTTPS 配置"
|
||||
fi
|
||||
|
||||
# 测试并重载配置
|
||||
if sudo nginx -t; then
|
||||
sudo systemctl reload nginx
|
||||
echo "配置已生效,HTTPS已启用"
|
||||
if sudo systemctl is-active --quiet nginx; then
|
||||
sudo systemctl reload nginx
|
||||
echo "配置已重载"
|
||||
else
|
||||
sudo systemctl start nginx
|
||||
echo "nginx 已启动"
|
||||
fi
|
||||
else
|
||||
echo "配置测试失败,已恢复备份"
|
||||
# 恢复 nginx.conf 备份
|
||||
sudo cp /etc/nginx/nginx.conf.bak /etc/nginx/nginx.conf
|
||||
# 恢复 conf.d 目录下的所有 .conf 文件备份
|
||||
for conf in conf.d/*.conf; do
|
||||
filename=$(basename "$conf")
|
||||
sudo mv -f "/etc/nginx/conf.d/${filename}.bak" "/etc/nginx/conf.d/$filename" 2>/dev/null || true
|
||||
done
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
1
nginx/verification.html
Normal file
1
nginx/verification.html
Normal file
@@ -0,0 +1 @@
|
||||
verify_01965aad87b3aae1c15f4373ae9efcfb
|
||||
Reference in New Issue
Block a user