Phala 部署教程
注意查看自己的prod,截止博客更新时,prod默认为7
AList
环境变量
CLOUDFLARE_API_TOKEN=your_cloudflare_api_token_here
CERTBOT_EMAIL=your_email@example.com
DOMAIN=alist.xxx.com
POSTGRES_PASSWORD=your_password
容器编排
services:
initial_setup:
image: docker.io/alpine:latest
container_name: initial_setup
environment:
- DOMAIN=${DOMAIN}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
networks:
- default
volumes:
- alist-data:/opt/alist/data
command:
- sh
- -c
- |
echo "🚀 初始化设置 - 域名: ${DOMAIN:-'未设置'}"
# 安装必要工具
apk add --no-cache curl > /dev/null 2>&1
# 初始化配置文件
echo "📦 初始化目录"
mkdir -p /opt/alist/data
echo "🔽 下载 config.json..."
cd /opt/alist/data
curl -s -L -o config.json https://raw.githubusercontent.com/Raimbaulty/freebsd/main/alist.json
if [ $? -ne 0 ]; then
echo "❌ config.json 下载失败!"
exit 1
fi
# 替换环境变量
if [ -n "$DOMAIN" ]; then
sed -i "s/alist.com/$DOMAIN/g" /opt/alist/data/config.json
else
echo "❌ 未设置 DOMAIN 环境变量"
exit 1
fi
if [ -n "$POSTGRES_PASSWORD" ]; then
sed -i "s/alist_password/$POSTGRES_PASSWORD/g" /opt/alist/data/config.json
else
echo "❌ 未设置 POSTGRES_PASSWORD 环境变量"
exit 1
fi
# 验证配置
if [ ! -s "/opt/alist/data/config.json" ]; then
echo "❌ 配置文件验证失败!"
exit 1
fi
echo "✅ 初始化完成 - 访问地址: https://$DOMAIN"
dstack-ingress:
image: kvin/dstack-ingress:250428
ports:
- "443:443"
networks:
- default
environment:
- GATEWAY_DOMAIN=_.dstack-prod7.phala.network
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
- SET_CAA=true
- DOMAIN=${DOMAIN}
- TARGET_ENDPOINT=http://alist:5244
volumes:
- cert-data:/etc/letsencrypt
- /var/run/tappd.sock:/var/run/tappd.sock
restart: unless-stopped
alist_db:
container_name: alist_db
image: postgres:17
networks:
- internal
restart: always
environment:
- POSTGRES_USER=alist
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=alist
volumes:
- postgres-data:/var/lib/postgresql/data
alist:
image: 'xhofe/alist:beta-aio'
container_name: alist
volumes:
- alist-data:/opt/alist/data
ports:
- '5244:5244'
networks:
- internal
- default
environment:
- PUID=0
- PGID=0
- UMASK=022
- TZ=Asia/Shanghai
depends_on:
- alist_db
- dstack-ingress
- initial_setup
restart: unless-stopped
networks:
internal:
driver: bridge
internal: true
volumes:
cert-data:
name: cert-data
alist-data:
name: alist-data
postgres-data:
name: postgres-data
n8n
方案一
官方 custom domain 方案,但是 ws 连接有问题
环境变量
CLOUDFLARE_API_TOKEN=your_cloudflare_api_token_here
CERTBOT_EMAIL=your_email@example.com
DOMAIN=n8n.xxx.com
POSTGRES_PASSWORD=your_postgres_password
REDIS_PASSWORD=your_redis_password
WEBHOOK_URL=https://n8n.xxx.com
VUE_APP_URL_BASE_API=https://n8n.xxx.com
容器编排
services:
initial_setup:
image: docker.io/alpine:latest
container_name: initial_setup
environment:
- DOMAIN=${DOMAIN}
volumes:
- nginx-data:/etc/nginx
- dist-data:/dist
command:
- sh
- -c
- |
echo "🚀 初始化设置 - 域名: ${DOMAIN:-'未设置'}"
# 安装必要工具
apk add --no-cache curl > /dev/null 2>&1
# 初始化 editor-ui
echo "📦 初始化 editor-ui..."
mkdir -p /dist
echo "🔽 下载 editor-ui.tar.gz..."
cd /dist
curl -s -L -o editor-ui.tar.gz https://github.com/other-blowsnow/n8n-i18n-chinese/releases/latest/download/editor-ui.tar.gz
if [ $? -ne 0 ]; then
echo "❌ editor-ui.tar.gz 下载失败!"
exit 1
fi
echo "📂 解压 editor-ui..."
tar -xzf editor-ui.tar.gz --strip-components=1
if [ $? -ne 0 ]; then
echo "❌ editor-ui 解压失败!"
exit 1
fi
rm -f editor-ui.tar.gz
echo "✅ editor-ui 初始化完成!"
# 配置 Nginx
echo "🌐 配置 Nginx..."
mkdir -p /etc/nginx/conf.d
curl -s -L -o /etc/nginx/nginx.conf https://raw.githubusercontent.com/Raimbaulty/freebsd/main/n8n.conf
if [ $? -ne 0 ]; then
echo "❌ nginx.conf 下载失败!"
exit 1
fi
# 替换域名变量
if [ -n "$DOMAIN" ]; then
sed -i 's/n8n.com/'"$DOMAIN"'/g' /etc/nginx/nginx.conf
if ! grep -q "$DOMAIN" /etc/nginx/nginx.conf; then
echo "❌ 域名替换失败!"
exit 1
fi
else
echo "❌ DOMAIN 环境变量未设置!"
exit 1
fi
rm -f /etc/nginx/conf.d/*.conf
# 验证配置
if [ ! -s "/etc/nginx/nginx.conf" ]; then
echo "❌ 配置文件验证失败!"
exit 1
fi
echo "✅ 初始化完成 - 访问地址: https://$DOMAIN"
dstack-ingress:
image: kvin/dstack-ingress:250428
ports:
- "443:443"
environment:
- GATEWAY_DOMAIN=_.dstack-prod7.phala.network
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
- SET_CAA=true
- DOMAIN=${DOMAIN}
- TARGET_ENDPOINT=http://n8n:5678
depends_on:
initial_setup:
condition: service_started
volumes:
- /var/run/tappd.sock:/var/run/tappd.sock
- cert-data:/etc/letsencrypt
restart: unless-stopped
n8n-db:
image: postgres:17
container_name: n8n-db
restart: unless-stopped
environment:
- TZ=Asia/Shanghai
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=n8n
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -h localhost -U n8n -d n8n']
interval: 5s
timeout: 5s
retries: 10
networks:
- internal
n8n-redis:
image: redis:latest
container_name: n8n-redis
restart: unless-stopped
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}", "--bind", "0.0.0.0", "--protected-mode", "yes"]
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 5s
timeout: 5s
retries: 10
networks:
- internal
n8n:
image: docker.n8n.io/n8nio/n8n
container_name: n8n
restart: unless-stopped
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=n8n-db
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- N8N_SECURE_COOKIE=true
- GENERIC_TIMEZONE=Asia/Shanghai
- N8N_DEFAULT_LOCALE=zh-CN
- N8N_PROXY_HOPS=1
- N8N_RUNNERS_ENABLED=true
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
- QUEUE_BULL_REDIS_HOST=n8n-redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD}
- WEBHOOK_URL=${WEBHOOK_URL}
- VUE_APP_URL_BASE_API=${VUE_APP_URL_BASE_API}
ports:
- "5678:5678"
volumes:
- n8n-data:/home/node/.n8n
- dist-data:/usr/local/lib/node_modules/n8n/node_modules/n8n-editor-ui/dist
depends_on:
initial_setup:
condition: service_started
n8n-db:
condition: service_healthy
n8n-redis:
condition: service_healthy
networks:
- internal
- default
networks:
internal:
driver: bridge
internal: true
volumes:
nginx-data:
name: nginx-data
cert-data:
name: cert-data
dist-data:
name: dist-data
redis-data:
name: redis-data
n8n-data:
name: n8n-data
postgres-data:
name: postgres-data
方案二
cloudflared 方案
环境变量
CLOUDFLARE_TUNNEL_TOKEN=your_cloudflar_tunnel_token
POSTGRES_PASSWORD=your_postgres_password
REDIS_PASSWORD=your_redis_password
WEBHOOK_URL=https://n8n.xxx.com
VUE_APP_URL_BASE_API=https://n8n.xxx.com
容器编排
services:
initial_setup:
image: docker.io/alpine:latest
container_name: initial_setup
networks:
- default
volumes:
- dist-data:/dist
command:
- sh
- -c
- |
echo "🚀 初始化设置"
# 安装必要工具
apk add --no-cache curl > /dev/null 2>&1
# 初始化 editor-ui
echo "📦 初始化 editor-ui..."
mkdir -p /dist
echo "🔽 下载 editor-ui.tar.gz..."
cd /dist
curl -s -L -o editor-ui.tar.gz https://github.com/other-blowsnow/n8n-i18n-chinese/releases/latest/download/editor-ui.tar.gz
if [ $$? -ne 0 ]; then
echo "❌ editor-ui.tar.gz 下载失败!"
exit 1
fi
echo "📂 解压 editor-ui..."
tar -xzf editor-ui.tar.gz --strip-components=1
if [ $$? -ne 0 ]; then
echo "❌ editor-ui 解压失败!"
exit 1
fi
rm -f editor-ui.tar.gz
echo "✅ editor-ui 初始化完成!"
echo "✅ 初始化完成!"
n8n-tunnel:
image: milgradesec/cloudflared:latest
container_name: n8n-tunnel
restart: unless-stopped
networks:
- default
command: ["tunnel", "--no-autoupdate", "run", "--token", "${CLOUDFLARE_TUNNEL_TOKEN}"]
n8n-db:
image: postgres:17
container_name: n8n-db
restart: unless-stopped
environment:
- TZ=Asia/Shanghai
- POSTGRES_USER=n8n
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=n8n
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -h localhost -U n8n -d n8n']
interval: 5s
timeout: 5s
retries: 10
networks:
- internal
n8n-redis:
image: redis:latest
container_name: n8n-redis
restart: unless-stopped
command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}", "--bind", "0.0.0.0", "--protected-mode", "yes"]
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
interval: 5s
timeout: 5s
retries: 10
networks:
- internal
n8n:
image: docker.n8n.io/n8nio/n8n
container_name: n8n
restart: unless-stopped
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=n8n-db
- DB_POSTGRESDB_PORT=5432
- DB_POSTGRESDB_DATABASE=n8n
- DB_POSTGRESDB_USER=n8n
- DB_POSTGRESDB_PASSWORD=${POSTGRES_PASSWORD}
- N8N_SECURE_COOKIE=true
- GENERIC_TIMEZONE=Asia/Shanghai
- N8N_DEFAULT_LOCALE=zh-CN
- N8N_PROXY_HOPS=1
- N8N_RUNNERS_ENABLED=true
- N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true
- QUEUE_BULL_REDIS_HOST=n8n-redis
- QUEUE_BULL_REDIS_PORT=6379
- QUEUE_BULL_REDIS_PASSWORD=${REDIS_PASSWORD}
- WEBHOOK_URL=${WEBHOOK_URL}
- VUE_APP_URL_BASE_API=${VUE_APP_URL_BASE_API}
ports:
- "5678:5678"
volumes:
- n8n-data:/home/node/.n8n
- dist-data:/usr/local/lib/node_modules/n8n/node_modules/n8n-editor-ui/dist
depends_on:
initial_setup:
condition: service_completed_successfully
n8n-db:
condition: service_healthy
n8n-redis:
condition: service_healthy
networks:
- internal
- default
networks:
internal:
driver: bridge
internal: true
volumes:
dist-data:
name: dist-data
redis-data:
name: redis-data
n8n-data:
name: n8n-data
postgres-data:
name: postgres-data
Calibre-web
点击下载 桌面端,下载后双击安装,使用默认设置安装后会自动打开
不要直接使用自动生成的 metadata.db
,需要点击 Calibre 书库 → 切换/建立书库,勾选 在新的位置建立空的书库,选择位置后点击 确定,然后进入新位置所在的文件夹,将 metadata.db
上传即可
环境变量
DOMAIN=calibre.xxx.com
CERTBOT_EMAIL=xxx@xxx.com
CLOUDFLARE_API_TOKEN=*************************
容器编排
services:
initial_setup:
image: docker.io/alpine:latest
container_name: initial_setup
environment:
- DOMAIN=${DOMAIN}
volumes:
- calibre-data:/app/calibre-web
- nginx-data:/etc/nginx
command:
- sh
- -c
- |
echo "🚀 初始化设置 - 域名: ${DOMAIN:-'未设置'}"
# 安装必要工具
apk add --no-cache curl > /dev/null 2>&1
# 初始化 Calibre 数据库
if [ ! -f "/app/calibre-web/books/metadata.db" ]; then
echo "📚 初始化 Calibre 数据库..."
mkdir -p /app/calibre-web/books
chown -R 1000:1000 /app/calibre-web
cd /app/calibre-web/books
curl -s -L -o metadata.db https://raw.githubusercontent.com/Raimbaulty/freebsd/main/metadata.db
if [ $? -ne 0 ]; then
echo "❌ metadata.db 下载失败!"
exit 1
fi
chmod 666 /app/calibre-web/books/metadata.db
echo "✅ Calibre 数据库初始化完成"
fi
# 配置 Nginx
echo "🌐 配置 Nginx..."
mkdir -p /etc/nginx/conf.d
curl -s -L -o /etc/nginx/nginx.conf https://raw.githubusercontent.com/Raimbaulty/freebsd/main/calibre.conf
if [ $? -ne 0 ]; then
echo "❌ nginx.conf 下载失败!"
exit 1
fi
# 替换域名变量
if [ -n "$DOMAIN" ]; then
sed -i 's/calibre-web.com/'"$DOMAIN"'/g' /etc/nginx/nginx.conf
if ! grep -q "$DOMAIN" /etc/nginx/nginx.conf; then
echo "❌ 域名替换失败!"
exit 1
fi
else
echo "❌ DOMAIN 环境变量未设置!"
exit 1
fi
rm -f /etc/nginx/conf.d/*.conf
# 验证配置
if [ ! -s "/etc/nginx/nginx.conf" ] || [ ! -s "/app/calibre-web/books/metadata.db" ]; then
echo "❌ 配置文件验证失败!"
exit 1
fi
echo "✅ 初始化完成 - 访问地址: https://$DOMAIN"
calibre-web:
image: linuxserver/calibre-web:latest
container_name: calibre-web
environment:
- PUID=1000
- PGID=1000
- TZ=Asia/Shanghai
- DOCKER_MODS=linuxserver/mods:universal-calibre
- OAUTHLIB_RELAX_TOKEN_SCOPE=1
- OAUTHLIB_INSECURE_TRANSPORT=1
- HTTP_X_SCHEME=https
- HTTP_X_FORWARDED_PROTO=https
- HTTP_X_FORWARDED_PORT=443
ports:
- 8083:8083
volumes:
- calibre-data:/app/calibre-web
restart: always
depends_on:
- initial_setup
networks:
- internal
- default
dstack-ingress:
image: kvin/dstack-ingress:250428
ports:
- "443:443"
environment:
- GATEWAY_DOMAIN=_.dstack-prod7.phala.network
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
- SET_CAA=true
- DOMAIN=${DOMAIN}
- TARGET_ENDPOINT=http://calibre-web:8083
volumes:
- /var/run/tappd.sock:/var/run/tappd.sock
- cert-data:/etc/letsencrypt
- nginx-data:/etc/nginx
restart: unless-stopped
depends_on:
- initial_setup
networks:
- default
networks:
internal:
driver: bridge
internal: true
volumes:
cert-data:
name: cert-data
calibre-data:
name: calibre-data
nginx-data:
name: nginx-data
使用配置(管理员向)
基本配置
初始用户名 admin
,密码 admin123
登录 Calibre-web 站点
登录后点击 📁 图标,进入 books 目录,点击选中 metadata.db 后保存
点击顶部导航栏的 admin 菜单,依次修改用户名、用户邮箱、密码、推送邮箱,并修改语言为中文,然后点击底部保存
点击顶部导航栏的 管理权限 菜单,点击 编辑基本配置,展开 拓展程序配置,Path to Calibre Binaries 输入 /usr/bin
后点击保存
用户管理
点击顶部导航栏的 管理权限 菜单,点击 编辑基本配置,展开 功能配置,勾选 启用注册 但不勾选 使用邮箱或用户名 后保存
点击顶部导航栏的 管理权限 菜单,点击 编辑界面配置,展开 新用户默认权限设置,勾选需要的权限并选择默认语言后保存
GitHub登录
点击这里 创建应用,Homepage URL 填写 https://n8n.xxx.com
,Callback URL 填写 http://n8n.xxx.com/login/github/authorized
,取消勾选 Webhook 的 Active 点击 Save changes
回到 Calibre-web 站点,点击顶部导航栏的 管理权限 菜单,点击 编辑基本配置,展开 功能配置,登录类型 选择 使用 OAuth 认证
,依次填入 github OAuth 客户端 Id 和 github OAuth 客户端 Secret 后保存
点击右上角用户名,点击 github OAuth 设置 旁的 链接,使用 GitHub 账户登录完成绑定,账户就可使用 GitHub 登录了
上传书籍
右上角退出登录,使用新的用户名密码登录,点击顶部导航栏的 管理权限 菜单,点击 编辑基本配置,展开 功能配置,勾选 启用上传 后点击 底部 保存
点击顶部导航栏的 管理权限 菜单,点击 管理用户,勾选 允许上传书籍 底部的方形框,刷新页面就可以看到 上传书籍 按钮了
上传书籍后,点击底部 获取元数据,先搜索书籍名称,然后仅勾选 豆瓣,点击正确的书籍封面图自动导入元数据,然后点击 保存
如果上传报错提示 File type isn't allowed to be uploaded to this server
,点击顶部导航栏的 管理权限 菜单,点击 编辑基本配置,展开 安全设置,取消勾选 Check if file extensions matches file content on upload
后重试
推送书籍
首先需要自备一台电子书设备,下面介绍的是 Kindle 的教程
点击 Calibre-web 站点顶部导航栏的 管理权限 菜单,点击 编辑邮件服务器设置,SMTP 主机名 填写 SMTP 服务器地址,加密 选择 STARTTLS 协议,如果后续测试不通过可以修改为 无 重试,其他自行填入后点击底部 保存设置并发送测试邮件,点击顶部导航栏的 任务列表 菜单查看任务状态,也可登入你设置的服务邮箱地址确认测试邮件
点击注册 Amazon 美区账号,如果 Kindle 登录过中亚账号需要先注销,然后使用新账号在Kindle登录并获得设备验证码
点击这里 登录美区账号验证后输入设备验证码绑定设备,然后 点击这里 接着点击 Personal Document Settings → Add a new e-mail address,添加你的服务邮箱地址
点击这里 进入绑定好的设备,可以点击 Email 旁边的 Edit 修改地址,然后使用这个地址作为转发邮箱地址
回到 Calibre-web 站点,点击头像 - 用户名,在 Send to eReader Email Address. Use comma to separate emails for multiple eReaders 填写转发邮箱地址
点击左侧 书籍 菜单,点击需要推送的书籍,点击推送
点击顶部导航栏的 任务列表 菜单查看任务状态
移动设备
IOS 应用商店搜索 KyBook 3,Android 应用商店搜索 Librera 下载,这里讲解 KyBook 3 的使用方法
进入应用后,点击 目录,然后点击 添加,标题输入 Calibre
,URL输入 https://站点地址/opds
添加,然后输入用户名密码验证即可
Zenfeed
环境变量
DOMAIN=zen.xxx.com
CERTBOT_EMAIL=admin@example.com
CLOUDFLARE_API_TOKEN=hijklmnopqrst
容器编排
services:
dstack-ingress:
container_name: dstack-ingress
image: kvin/dstack-ingress:250428
ports:
- "443:443"
environment:
- GATEWAY_DOMAIN=_.dstack-prod7.phala.network
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
- SET_CAA=true
- DOMAIN=${DOMAIN}
- TARGET_ENDPOINT=http://zenfeed-web:1400
volumes:
- /var/run/tappd.sock:/var/run/tappd.sock
- cert-data:/etc/letsencrypt
restart: unless-stopped
networks:
- zenfeed-net
zenfeed-web:
image: glidea/zenfeed-web:latest
ports:
- "1400:1400"
environment:
- PUBLIC_DEFAULT_API_URL=http://zenfeed:1300
depends_on:
- zenfeed
restart: unless-stopped
networks:
- zenfeed-net
zenfeed:
image: glidea/zenfeed:latest
entrypoint: >
sh -c "
if [ ! -f /app/config/config.yaml ]; then
echo 'Config file not found in volume, initializing from base config...'
cp /app/config.base.yaml /app/config/config.yaml;
else
echo 'Existing config file found in volume.'
fi &&
echo 'Starting Zenfeed...' &&
exec /app/zenfeed --config /app/config/config.yaml
"
configs:
- source: zenfeed_config_base
target: /app/config.base.yaml
volumes:
- zenfeed-data:/app/data
- zenfeed-config:/app/config
depends_on:
- rsshub
restart: unless-stopped
networks:
- zenfeed-net
rsshub:
image: diygod/rsshub:2024-12-14
environment:
- NODE_ENV=production
restart: unless-stopped
networks:
- zenfeed-net
volumes:
zenfeed-data:
name: zenfeed_data
zenfeed-data:
name: zenfeed-data
cert-data:
name: cert-data
configs:
zenfeed_config_base:
content: |
timezone: ${TZ:-Asia/Shanghai}
llms:
- name: general
default: true
provider: siliconflow
model: Qwen/Qwen2.5-7B-Instruct
api_key: ${API_KEY:-your-api-key}
- name: embed
provider: siliconflow
embedding_model: Pro/BAAI/bge-m3
api_key: ${API_KEY:-your-api-key}
scrape:
rsshub_endpoint: http://rsshub:1200
storage:
feed:
rewrites:
- transform:
to_text:
prompt: |
Respond in ${LANG:-Chinese}
label: summary_html_snippet
embedding_llm: embed
notify:
channels:
email:
feed_html_snippet_template: |
networks:
zenfeed-net:
driver: bridge
Chat-Share
环境变量
DOMAIN=share.xxx.com
SECRET_KEY=1234567abcdefg
AUTHORIZATION=sk-123
CERTBOT_EMAIL=admin@example.com
CLOUDFLARE_API_TOKEN=hijklmnopqrst
容器编排
services:
dstack-ingress:
image: kvin/dstack-ingress:250428
ports:
- "443:443"
environment:
- GATEWAY_DOMAIN=_.dstack-prod7.phala.network
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
- SET_CAA=true
- DOMAIN=${DOMAIN}
- TARGET_ENDPOINT=http://chat-share:5100
volumes:
- /var/run/tappd.sock:/var/run/tappd.sock
- cert-data:/etc/letsencrypt
restart: unless-stopped
chat-share:
image: ghcr.io/h88782481/chat-share:latest
container_name: chat-share
restart: unless-stopped
environment:
- TZ=Asia/Shanghai
- SECRET_KEY=${SECRET_KEY}
- AUTHORIZATION=${AUTHORIZATION}
- DOMAIN_CHATGPT=https://898u-lan.hf.space
- DOMAIN_CLAUDE=https://mpfo-fo.hf.space
volumes:
- share-data:/app/data
volumes:
cert-data:
-name: cert-data
share-data:
-name: share-data
Elasticsearch/Kibana
容器编排
services:
dstack-ingress:
image: kvin/dstack-ingress:250428
ports:
- "443:443"
environment:
- GATEWAY_DOMAIN=_.dstack-prod7.phala.network
- CLOUDFLARE_API_TOKEN=${CLOUDFLARE_API_TOKEN}
- CERTBOT_EMAIL=${CERTBOT_EMAIL}
- SET_CAA=true
- DOMAIN=${DOMAIN}
- TARGET_ENDPOINT=http://elasticsearch:65536
volumes:
- /var/run/tappd.sock:/var/run/tappd.sock
- cert-data:/etc/letsencrypt
restart: unless-stopped
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.4.2
container_name: elasticsearch
environment:
- discovery.type=single-node
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- "http.cors.enabled=true"
- "http.cors.allow-origin=*"
- "xpack.security.enabled=false"
- "cluster.name=es-docker-cluster"
- "network.bind_host=0.0.0.0"
- "network.publish_host=0.0.0.0"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
volumes:
- elasticsearch-data:/usr/share/elasticsearch/data
ports:
- 9200:9200
- 9300:9300
networks:
- elk-network
# elk-network:
# aliases:
# - elasticsearch
restart: always
kibana:
image: docker.elastic.co/kibana/kibana:7.4.2
container_name: kibana
environment:
- "ELASTICSEARCH_HOSTS=http://elasticsearch:9200"
- "SERVER_NAME=kibana"
- "SERVER_HOST=0.0.0.0"
- "ELASTICSEARCH_REQUESTTIMEOUT=90000"
ports:
- 5601:5601
networks:
- elk-network
restart: on-failure
depends_on:
- elasticsearch
setup-plugin:
image: docker.io/alpine:latest
container_name: setup-plugin
ports:
- 9999:9999
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: >
sh -c '
echo "等待 Elasticsearch 启动..." &&
sleep 30 &&
echo "开始安装 Docker CLI 工具..." &&
apk add --no-cache docker-cli curl &&
echo "开始检查 Elasticsearch 健康状态..." &&
until curl -s http://elasticsearch:9200/_cluster/health | grep -q "status"; do
echo "等待 Elasticsearch 健康检查通过..."
sleep 5
done &&
echo "Elasticsearch 已启动,开始安装分词器..." &&
docker exec elasticsearch elasticsearch-plugin install --batch https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-7.4.2.zip &&
echo "IK 分词器安装完成,重启 Elasticsearch..." &&
docker restart elasticsearch &&
echo "Elasticsearch 重启完成,等待服务就绪..." &&
sleep 30 &&
echo "安装流程完成!"
'
depends_on:
- elasticsearch
networks:
- elk-network
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: --cleanup --interval 300
networks:
elk-network:
driver: bridge
default:
driver: bridge
volumes:
cert-data:
name: cert-data
elasticsearch-data:
driver: local
name:elasticsearch-data
参考链接
- https://linux.do/t/topic/611405/25
- https://github.com/janeczku/calibre-web/issues/2383