bewCloud v4.21.0 Docker Compose 部署指南
在 Linux 服务器上用官方发行版从零部署 bewCloud v4.21.0:三服务 Compose 编排逐行说明、数据库迁移、首个管理员注册、文件上传与分享、CalDAV 连通性验证,以及目录权限、Cookie 安全与迁移缺失等部署期高频问题排障,全部命令与回显实测。
bewCloud v4.21.0 Docker Compose 部署指南
目标:在一台 Linux 服务器上用官方发行版 ghcr.io/bewcloud/bewcloud:v4.21.0 完成个人云从零到一的部署:三服务编排逐行说明、数据库迁移、首个管理员注册、文件上传与分享、CalDAV 连通性验证,以及部署期最常见的目录权限、Cookie 安全与迁移缺失问题排障。本文所有命令与回显均在 2026-10-30 的实测中逐条执行验证。
本文是 bewCloud 系列的第二篇。第一篇《bewCloud v4.21.0 介绍与选型指南》讲清了「它是什么、八个内置应用覆盖什么、适不适合你」,本篇解决「怎么把它跑起来」。配置文件的逐项参数讲解见 《bewCloud v4.21.0 配置参数详解》,JSON API 与 WebDAV/CalDAV 端点的调用方法见 《bewCloud v4.21.0 API 使用详解》。
一、环境信息
| 项目 | 值 |
|---|---|
| 组件版本 | bewCloud v4.21.0(官方 GitHub Releases latest,2026-10-30 实查;该版本升级需执行数据库迁移) |
| 发行形态 | 官方 Docker 镜像 ghcr.io/bewcloud/bewcloud:v4.21.0(仅此一种官方发行形态,无裸机安装包) |
| 依赖服务 | PostgreSQL 18.6(postgres:18.6)、Radicale 3.7.6.0(tomsquest/docker-radicale:3.7.6.0,官方编排指定版本) |
| 服务器系统 | Linux x86_64(内核 6.x) |
| 对外端口 | 8155 → 应用 8000(Web 界面、JSON API、WebDAV) |
| 内部端口 | 5432(PostgreSQL)、5232(Radicale,仅编排内网可达) |
| 实测日期 | 2026-10-30 |
bewCloud 的对外面收敛在一个端口:Web 界面、JSON API、WebDAV 文件端点共用 8000,CalDAV/CardDAV 请求也由它统一接收再转发给内网的 Radicale。所以对外只需映射一个端口,这是与「多协议多端口」类服务(流媒体、数据库)显著不同的部署形态。
二、镜像选型说明
官方编排固定三个镜像,本篇实测与其保持一致:
| 镜像 | 来源 | 选型理由 |
|---|---|---|
ghcr.io/bewcloud/bewcloud:v4.21.0 | GitHub Container Registry(官方唯一发行渠道) | 应用本体,Deno 运行时内置,固定 tag 保证可复现 |
postgres:18.6 | Docker Hub 官方 | 官方编排指定;bewCloud v4.21.0 的迁移脚本在此版本上验证 |
tomsquest/docker-radicale:3.7.6.0 | Docker Hub 社区维护(Radicale 官方无 Docker 镜像,这是事实上的社区标准镜像) | 官方编排指定;提供 CalDAV/CardDAV 数据后端 |
⚠️ 网络说明:ghcr.io 在部分网络环境拉取缓慢(实测约 40KB/s 量级)。实测可用的替代渠道是南京大学镜像源
ghcr.nju.edu.cn——拉取后用docker tag ghcr.nju.edu.cn/bewcloud/bewcloud:v4.21.0 ghcr.io/bewcloud/bewcloud:v4.21.0改回官方名,编排文件无需改动。两个渠道 2026-10-30 均验证可用。
三、前置条件
- 服务器已安装 Docker 与 Docker Compose v2(
docker compose version可执行); - 宿主 8155 端口空闲:
ss -ltn | grep 8155确认无输出; - 准备部署目录(示例为
/opt/bewcloud,读者可按自己的目录规范替换),并建好官方要求的三个子目录:
mkdir -p /opt/bewcloud/data-files /opt/bewcloud/data-radicale /opt/bewcloud/radicale-config
- 规划访问地址:本篇实测以
http://<服务器IP>:8155经 HTTP 访问(内网环境),对应配置见 4.3 节的skipCookieDomainSecurity说明;若走 HTTPS 反向代理,baseUrl要写成对外域名。
四、部署步骤
4.1 编写 docker-compose.yml
在 /opt/bewcloud/ 下编写编排文件。项目名显式声明为 bewcloud-v4.21.0-stack,网络名与子网一并显式固定——多套自托管服务并行部署时,显式资源命名能避免 Compose 随机命名带来的操作误伤:
name: bewcloud-v4.21.0-stack
services:
website:
image: ghcr.io/bewcloud/bewcloud:v4.21.0
container_name: bewcloud-v4.21.0-web
restart: always
ports:
- "8155:8000" # 对外唯一端口:Web / API / WebDAV
mem_limit: '256m'
env_file:
- path: .env # 密钥类环境变量(数据库口令、JWT 等)
required: true
volumes:
- ./data-files:/app/data-files # 用户文件本体
- ./bewcloud.config.ts:/app/bewcloud.config.ts # 业务配置(单文件挂载)
networks:
- bewcloud-net
postgresql:
image: postgres:18.6
container_name: bewcloud-v4.21.0-db
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=q1w2e3r4 # 演示口令,生产请换强口令并与 .env 保持一致
- POSTGRES_DB=bewcloud
restart: always
volumes:
- bewcloud-db:/var/lib/postgresql/18/docker
ulimits:
memlock:
soft: -1
hard: -1
mem_limit: '256m'
networks:
- bewcloud-net
radicale:
image: tomsquest/docker-radicale:3.7.6.0
container_name: bewcloud-v4.21.0-dav
init: true
read_only: true # Radicale 镜像按只读根文件系统设计
security_opt:
- no-new-privileges:true
cap_drop:
- ALL
cap_add:
- SETUID
- SETGID
- CHOWN
- KILL
restart: always
volumes:
- ./data-radicale:/data # 日历/通讯录条目
- ./radicale-config:/config:ro # Radicale 配置(只读挂载)
mem_limit: '256m'
networks:
- bewcloud-net
volumes:
bewcloud-db:
driver: local
networks:
bewcloud-net:
name: bewcloud-v4.21.0-net
driver: bridge
ipam:
config:
- subnet: 10.89.63.0/24
逐行说明:
website.ports:8155:8000是对外唯一入口。官方样例写的是127.0.0.1:8000:8000(仅本机访问),本篇要经局域网访问所以改为全网卡映射;如置于反向代理之后,建议改回绑定 127.0.0.1;website.env_file:.env是官方要求的必填文件(required: true),只放密钥类变量,逐项见第六节;website.volumes第一行:data-files是用户上传文件的本体目录,容器内固定挂到/app/data-files;第二行把bewcloud.config.ts以单文件挂进容器——bewCloud 的业务配置就是一个 TypeScript 文件,改完docker compose restart website生效;postgresql.environment:三行与.env里的POSTGRESQL_*四项一一对应(口令必须一致,否则应用连库失败);postgresql.ulimits.memlock:官方编排原样保留,PostgreSQL 18 的内存页锁定建议;radicale的read_only/cap_drop/cap_add:官方编排的安全加固原样保留——Radicale 以非特权用户运行、根文件系统只读,仅保留改属主所需的四个能力;networks.ipam.subnet:显式固定子网,避免与宿主上其他 bridge 网络冲突(实测环境已占用多段 10.89.x.x)。
4.2 编写 .env(密钥文件)
在 /opt/bewcloud/.env 写入(由官方 .env.sample 复制后修改):
PORT=8000
POSTGRESQL_HOST="postgresql"
POSTGRESQL_USER="postgres"
POSTGRESQL_PASSWORD="q1w2e3r4"
POSTGRESQL_DBNAME="bewcloud"
POSTGRESQL_PORT=5432
POSTGRESQL_CAFILE=""
JWT_SECRET="bewcloud-demo-jwt-7a3f9c2e"
PASSWORD_SALT="bewcloud-demo-salt-4d8b1f6a"
#SMTP_USERNAME=""
#SMTP_PASSWORD=""
逐项说明:PORT 是应用监听端口(与 ports 映射右侧一致);POSTGRESQL_HOST/PORT 用编排内服务名 postgresql 与默认 5432;POSTGRESQL_PASSWORD 必须与 4.1 节 POSTGRES_PASSWORD 完全一致;JWT_SECRET 是登录会话签名密钥、PASSWORD_SALT 是口令哈希盐——两者泄露即可伪造登录态,生产环境务必用长随机串替换(生成方式:openssl rand -hex 32);MFA_KEY/MFA_SALT(启用 MFA 时需要)与 OIDC_*(SSO)在本篇未启用故省略,说明见配置篇。
4.3 编写 bewcloud.config.ts(业务配置)
在 /opt/bewcloud/bewcloud.config.ts 写入(由官方样例精简而来,只保留本篇必需项):
import { Config, PartialDeep } from './lib/types.ts';
const config: PartialDeep<Config> = {
auth: {
baseUrl: 'http://<服务器IP>:8155', // 对外访问地址;浏览器可达即可
allowSignups: false, // 关闭开放注册(第一个注册仍会放行并成为管理员)
enableEmailVerification: false, // 未配 SMTP,关邮箱验证
enableForeverSignup: true, // 注册即长期有效,不过期
enableMultiFactor: false, // 演示不启用 MFA
skipCookieDomainSecurity: true, // HTTP + IP 访问必须:跳过 Cookie 域安全校验
},
files: {
rootPath: 'data-files',
allowPublicSharing: true, // 开启公共分享链接(实测要用)
allowDirectoryDownloads: true, // 允许目录打包下载
maxUploadSizeInMegabytes: 100, // 单文件上传上限 100MB
},
core: {
enabledApps: ['dashboard', 'files', 'news', 'notes', 'photos', 'expenses', 'contacts', 'calendar'],
maxRequestSizeInMegabytes: 12, // 除上传外的请求体上限
},
visuals: {
title: 'My own cloud',
description: 'This is my own cloud!',
helpEmail: '',
},
email: {
from: 'help@bewcloud.com',
host: 'localhost',
port: 465,
tlsMode: 'auto',
tlsVerify: true,
},
contacts: {
enableCardDavServer: true,
cardDavUrl: 'http://radicale:5232', // 编排内 Radicale 服务地址
},
calendar: {
enableCalDavServer: true,
calDavUrl: 'http://radicale:5232',
},
};
export default config;
关键项解读:auth.baseUrl 决定登录 Cookie 的作用域与绝对链接的生成基准,必须写成浏览器实际访问的地址;skipCookieDomainSecurity: true 是 HTTP + IP 访问的硬前置——bewCloud 默认拒绝在非安全上下文发 Cookie,不开启它登录会静默失败(实测踩坑,见第十一节);files.allowPublicSharing 默认关闭,本篇要实测公共分享链接所以开启。全部字段的完整语义见配置篇。
4.4 编写 Radicale 配置
在 /opt/bewcloud/radicale-config/config 写入(官方样例):
[server]
hosts = 0.0.0.0:5232
[auth]
type = http_x_remote_user
[storage]
filesystem_folder = /data/collections
[web]
type = none
[logging]
level = info
mask_passwords = True
解读:auth type = http_x_remote_user 是三服务协同的核心——Radicale 不自管认证,信任 bewCloud 应用反代进来时注入的 X-Remote-User 头;filesystem_folder 指向挂载的数据卷;[web] type = none 关闭 Radicale 自带 Web 界面(入口被 bewCloud 代理,直接访问无意义)。
4.5 启动与首启确认
cd /opt/bewcloud
docker compose up -d
docker compose ps
实测回显:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
bewcloud-v4.21.0-dav tomsquest/docker-radicale:3.7.6.0 "docker-entrypoint.s…" radicale 43 seconds ago Up 43 seconds (healthy) 5232/tcp
bewcloud-v4.21.0-db postgres:18.6 "docker-entrypoint.s…" postgresql 43 seconds ago Up 43 seconds 5432/tcp
bewcloud-v4.21.0-web ghcr.io/bewcloud/bewcloud:v4.21.0 "/tini -- docker-ent…" website 13 seconds ago Up 13 seconds 0.0.0.0:8155->8000/tcp, [::]:8155->8000/tcp
三个服务均为 Up 状态(radicale 会经健康检查转为 healthy)后,确认应用进程已监听:
curl -sI http://<服务器IP>:8155/ | head -5
实测回显:
HTTP/1.1 303 See Other
content-type: text/plain;charset=UTF-8
location: /login
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
未登录访问根路径被 303 重定向到 /login——这不是故障,而是 bewCloud 全站登录墙的预期行为,说明应用进程已正常监听。
4.6 首次数据库迁移
首次启动后必须执行一次数据库迁移,否则注册用户时会报迁移缺失错误(官方 README 将其列为「首次与每次升级数据变更时」的固定动作):
docker compose run --rm website bash -c "cd /app && make migrate-db"
实测回显(输出节选,实测首尾):
Container bewcloud-v4210-stack-website-run-4c60e33cd3b3 Creating
Container bewcloud-v4210-stack-website-run-4c60e33cd3b3 Created
deno task migrate-db
Task migrate-db deno task execute-with-permissions ./migrate-db.ts
Task execute-with-permissions deno run --allow-env --allow-net --allow-sys=networkInterfaces,hostname,cpus,homedir --allow-read=.,/ --allow-write=data-files,/ --allow-run './migrate-db.ts'
Running "001-base.pgsql"...
Success!
Running "002-news-app.pgsql"...
Success!
Running "003-expenses-app.pgsql"...
Success!
Running "004-public-file-sharing.pgsql"...
Success!
Running "005-authentication-challenges.pgsql"...
Success!
五个迁移脚本逐个执行成功(001 基础表结构到 005 认证质询,v4.21.0 的完整迁移集)。迁移是幂等的:重复执行会提示无待执行迁移。
4.7 修正文件目录属主
应用以镜像内 deno 用户(uid 1993)运行,上传目录属主不对会导致文件写入失败。宿主上执行:
sudo chown -R 1993:1993 data-files
ls -ln data-files
实测回显(目录修正后立即查看为空目录;注册用户并上传文件后复查):
$ ls -ln data-files
total 0
# 注册用户并上传文件后复查:
$ ls -ln data-files
total 4
drwxr-xr-x 6 1993 1993 4096 Oct 30 13:39 9d5ebad4-f6a7-4588-884e-f8c8c8ede632
复查可见按用户 ID 命名的存储目录属主已是 1993:1993(deno 用户)——若不预先 chown,应用将因无写权限创建失败,上传报 500。
4.8 注册第一个用户(自动成为管理员)
浏览器打开 http://<服务器IP>:8155,进入注册页,用演示账号注册:
- 邮箱:
admin@example.com - 密码:
q1w2e3r4
⚠️ 注意:官方 README 明确说明——即使
allowSignups=false,第一个注册的用户仍然会成功并自动成为管理员,之后的注册才会被关闭。这是单管理员场景的预期行为,不是配置失效。
命令行验证注册页可达与首用户登录(登录请求与 Cookie 验证的全过程见 API 篇 3.x 节,此处仅确认首页与登录跳转):
curl -s http://<服务器IP>:8155/signup | grep -o '<title>[^<]*</title>'
实测回显:
<title>Signup - bewCloud</title>
4.9 登录并进入文件应用
浏览器用 admin@example.com / q1w2e3r4 登录,落地页即 dashboard。命令行验证登录态(Cookie 获取):
curl -s -c /tmp/bewcloud-cookie.txt -X POST http://<服务器IP>:8155/login \
-d 'email=admin@example.com&password=q1w2e3r4' \
-o /dev/null -w '%{http_code} %{redirect_url}\n'
实测回显:
303 http://192.168.146.128:8155/
登录成功:303 跳转到 /(随后进入 dashboard 落地页),会话 Cookie 由 -c 参数写入 ~/bewcloud-cookie.txt。带 Cookie 访问受保护页面验证登录态:
curl -s -b ~/bewcloud-cookie.txt -o /dev/null -w '%{http_code}\n' http://<服务器IP>:8155/dashboard
实测回显:
200
五、数据持久化说明
三处持久化各司其职,备份策略围绕它们制定:
| 数据 | 落点 | 内容 | 备份方式 |
|---|---|---|---|
| 元数据 | 编排卷 bewcloud-db(宿主由 Docker 管理) | 用户、文件索引、笔记、RSS、记账、分享记录 | docker compose exec postgresql pg_dump -U postgres bewcloud > bewcloud.sql |
| 文件本体 | ./data-files | 上传文件,按用户 ID 分目录 | 直接 rsync/tar 该目录 |
| 日历/通讯录 | ./data-radicale | Radicale 集合文件(iCalendar/vCard) | 直接 rsync/tar 该目录 |
恢复:新机器上按本篇 4.1–4.4 重建编排后,docker compose up -d,把三个数据落回原位,再执行一次 docker compose run --rm website bash -c "cd /app && make migrate-db"(幂等操作),最后导入 pg_dump 备份即可。
六、环境变量表
.env 全部变量与默认值(来源:官方 .env.sample 与 lib/config.ts,2026-10-30 实查):
| 变量 | 必填 | 默认/样例值 | 说明 |
|---|---|---|---|
PORT | 是 | 8000 | 应用监听端口,与 ports 映射右侧一致 |
POSTGRESQL_HOST | 是 | postgresql | 数据库主机名(编排内服务名) |
POSTGRESQL_USER | 是 | postgres | 数据库用户 |
POSTGRESQL_PASSWORD | 是 | 样例 fake | 数据库口令,与 postgresql 服务 environment 一致 |
POSTGRESQL_DBNAME | 是 | bewcloud | 数据库名 |
POSTGRESQL_PORT | 是 | 5432 | 数据库端口 |
POSTGRESQL_CAFILE | 否 | 空 | 数据库 TLS CA 文件路径(内网可空) |
JWT_SECRET | 是 | 样例 fake | 会话签名密钥,生产必须换长随机串 |
PASSWORD_SALT | 是 | 样例 fake | 口令哈希盐,生产必须换长随机串 |
MFA_KEY / MFA_SALT | 启用 MFA 时必填 | 空 | TOTP 加密密钥与盐 |
OIDC_CLIENT_ID / OIDC_CLIENT_SECRET | 启用 SSO 时必填 | 空 | OIDC 单点登录凭据 |
SMTP_USERNAME / SMTP_PASSWORD | 启用邮件验证时必填 | 空 | 发信邮箱凭据 |
💡 技术拓展:为什么配置要拆成
.env+bewcloud.config.ts两层?这是 v2 重写时的明确设计(官方 FAQ 记载 v1 时代配置全在环境变量里):密钥类值走环境变量便于用 secret 管理工具注入、且不会进版本库;业务配置是类型化的 TypeScript 文件,改配置时编辑器能补全和校验,且可用 git 管理。两类值的判断标准:会泄露身份的进.env,描述行为的进bewcloud.config.ts。
七、配置参数说明
bewcloud.config.ts 七个配置域与本篇部署相关的关键项(完整逐项详解见配置篇):
| 域 | 关键项 | 本篇取值 | 取值原因 |
|---|---|---|---|
| auth | baseUrl | http://<服务器IP>:8155 | 浏览器实际访问地址,Cookie 作用域与跳转基准 |
| auth | allowSignups | false | 封闭注册;首用户不受此限制 |
| auth | skipCookieDomainSecurity | true | HTTP + IP 访问的硬前置 |
| files | allowPublicSharing | true | 实测公共分享链接所需 |
| files | maxUploadSizeInMegabytes | 100 | 单文件上传上限 |
| core | enabledApps | 全部 8 个 | 第一个元素 dashboard 为登录落地页 |
| contacts/calendar | cardDavUrl/calDavUrl | http://radicale:5232 | 编排内 Radicale 地址,应用侧反代目标 |
八、配置文件挂载
本篇共四处外部文件/目录进容器,路径对应关系(宿主 → 容器):
| 宿主路径 | 容器路径 | 挂载方式 | 改动后生效方式 |
|---|---|---|---|
.env | 环境变量注入(非文件挂载) | env_file | docker compose up -d 重建 |
bewcloud.config.ts | /app/bewcloud.config.ts | 单文件 bind mount | docker compose restart website |
data-files/ | /app/data-files | 目录 bind mount | 即时 |
data-radicale/ + radicale-config/ | /data + /config(只读) | 目录 bind mount | 配置改动需重启 radicale 服务 |
验证挂载生效:进应用容器确认配置文件就是宿主那份(以 4.3 节的 visuals.title 为锚点):
docker compose exec website grep -n 'My own cloud' /app/bewcloud.config.ts
实测回显:
23: title: 'My own cloud',
容器内第 23 行就是宿主配置文件里的 visuals.title——挂载与配置内容均确认生效。
九、等价 docker run 命令
不用 Compose 时,三条 docker run 可复现同一部署(先建网络,三条命令逐个执行):
# 1. 创建与 Compose 等价的 bridge 网络
docker network create --subnet 10.89.63.0/24 bewcloud-v4.21.0-net
# 2. PostgreSQL(数据卷 bewcloud-db)
docker run -d --name bewcloud-v4.21.0-db \
--network bewcloud-v4.21.0-net \
-e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=q1w2e3r4 -e POSTGRES_DB=bewcloud \
-v bewcloud-db:/var/lib/postgresql/18/docker \
--memory 256m --restart always postgres:18.6
# 3. Radicale(只读根文件系统 + 最小能力集)
docker run -d --name bewcloud-v4.21.0-dav \
--network bewcloud-v4.21.0-net --init --read-only \
--security-opt no-new-privileges:true --cap-drop ALL \
--cap-add SETUID --cap-add SETGID --cap-add CHOWN --cap-add KILL \
-v /opt/bewcloud/data-radicale:/data \
-v /opt/bewcloud/radicale-config:/config:ro \
--memory 256m --restart always tomsquest/docker-radicale:3.7.6.0
# 4. bewCloud 应用(等 .env 写好、配置文件就位后)
docker run -d --name bewcloud-v4.21.0-web \
--network bewcloud-v4.21.0-net \
-p 8155:8000 --memory 256m --restart always \
--env-file /opt/bewcloud/.env \
-v /opt/bewcloud/data-files:/app/data-files \
-v /opt/bewcloud/bewcloud.config.ts:/app/bewcloud.config.ts \
ghcr.io/bewcloud/bewcloud:v4.21.0
# 5. 迁移(等价 docker compose run --rm website 的用法)
docker run --rm --network bewcloud-v4.21.0-net --env-file /opt/bewcloud/.env \
ghcr.io/bewcloud/bewcloud:v4.21.0 bash -c "cd /app && make migrate-db"
说明:启动顺序上 PostgreSQL 与 Radicale 先行,应用最后启动;应用对数据库有启动重试,乱序启动一般也能自愈,但迁移必须等数据库就绪后执行。日常管理仍建议用 Compose(docker compose down 能一次性回收网络,docker run 方式需手动 docker network rm)。
十、常用运维命令
docker compose ps # 三服务状态
docker compose logs website --tail 50 # 应用日志(排查登录/上传问题先看这里)
docker compose logs radicale --tail 30 # CalDAV/CardDAV 后端日志
docker compose restart website # 改 bewcloud.config.ts 后重启生效
docker compose down # 停止并回收网络(数据卷与 bind 目录保留)
docker compose down -v # 连同数据库卷一起删除(危险:元数据全丢)
docker compose run --rm website bash -c "cd /app && make migrate-db" # 升级后重跑迁移
升级流程(小版本):改 compose 与 tag 中的版本号 → docker compose up -d → 重跑迁移命令 → 验证登录与大版本 Release Notes 中提到的功能。跨大版本(如 v3→v4)先读 Release Notes 的 breaking changes,备份三处数据后再动。
十一、常见问题
Q1:登录后立刻跳回登录页,或浏览器提示无法保持登录?
auth.baseUrl 与实际访问地址不一致,或经 HTTP + IP 访问但没开 skipCookieDomainSecurity: true。bewCloud 默认只信任 HTTPS(localhost 例外)场景的 Cookie;内网 HTTP 访问必须显式跳过校验。改 bewcloud.config.ts 后 docker compose restart website 生效(实测确认)。
Q2:注册时报数据库迁移相关错误?
首次启动后漏执行 docker compose run --rm website bash -c "cd /app && make migrate-db"。补跑即可,该操作幂等。
Q3:文件上传失败或报权限错误?
data-files 属主不是 1993(deno 用户 uid)。执行 sudo chown -R 1993:1993 data-files 后重试(实测确认属主正确后上传正常)。ls -ln data-files 可直接核 uid。
Q4:docker compose up 报 .env 缺失?
env_file.required: true 是硬校验,.env 文件必须存在(哪怕只放官方样例值)。从官方仓库 .env.sample 复制改名。
Q5:CalDAV 客户端连不上日历?
先确认 calendar.enableCalDavServer 未被关掉;再确认客户端用的是应用端口(8155)而非 Radicale 的 5232——5232 只在编排内网可达,对外统一走应用反代。连通性探针方法见 API 篇 CalDAV 节。
十二、参考链接
- 官方 README(部署步骤与首用户说明):https://github.com/bewcloud/bewcloud#readme
- 官方 docker-compose.yml 与 .env.sample:https://github.com/bewcloud/bewcloud/blob/main/docker-compose.yml
- 配置样例:https://github.com/bewcloud/bewcloud/blob/main/bewcloud.config.sample.ts
- 本系列其他篇章:《bewCloud v4.21.0 介绍与选型指南》、《bewCloud v4.21.0 配置参数详解》、《bewCloud v4.21.0 API 使用详解》