mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
deploy: remove local build compose path
This commit is contained in:
@@ -1,131 +0,0 @@
|
|||||||
# syntax=docker/dockerfile:1
|
|
||||||
# Aether 运行镜像:Rust gateway 直接服务 API + 前端静态文件(国内镜像源版本)
|
|
||||||
# 构建命令: docker build -f Dockerfile.app.local -t aether-app:latest .
|
|
||||||
|
|
||||||
# ==================== 前端构建 ====================
|
|
||||||
FROM node:22-slim AS frontend-builder
|
|
||||||
WORKDIR /app/frontend
|
|
||||||
COPY frontend/package*.json ./
|
|
||||||
RUN npm config set registry https://registry.npmmirror.com && npm ci
|
|
||||||
COPY frontend/ ./
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
# ==================== Rust gateway 构建 ====================
|
|
||||||
FROM rust:1.94.1-slim AS gateway-base
|
|
||||||
WORKDIR /build
|
|
||||||
|
|
||||||
# 本地镜像优先缩短构建时间,保留 release 语义,但改用更快的 thin LTO。
|
|
||||||
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse \
|
|
||||||
CARGO_PROFILE_RELEASE_LTO=thin \
|
|
||||||
CARGO_PROFILE_RELEASE_CODEGEN_UNITS=16
|
|
||||||
|
|
||||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
|
||||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
|
||||||
sed -i 's/deb.debian.org/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list.d/debian.sources && \
|
|
||||||
apt-get update && apt-get install -y --no-install-recommends \
|
|
||||||
build-essential \
|
|
||||||
ca-certificates \
|
|
||||||
libssl-dev \
|
|
||||||
pkg-config \
|
|
||||||
perl
|
|
||||||
|
|
||||||
RUN --mount=type=cache,id=aether-cargo-registry,target=/usr/local/cargo/registry,sharing=locked \
|
|
||||||
--mount=type=cache,id=aether-cargo-git,target=/usr/local/cargo/git,sharing=locked \
|
|
||||||
cargo install cargo-chef --locked
|
|
||||||
|
|
||||||
FROM gateway-base AS gateway-planner
|
|
||||||
COPY Cargo.toml Cargo.lock ./
|
|
||||||
COPY apps/ ./apps/
|
|
||||||
COPY crates/ ./crates/
|
|
||||||
RUN cargo chef prepare --recipe-path recipe.json
|
|
||||||
|
|
||||||
FROM gateway-base AS gateway-builder
|
|
||||||
COPY --from=gateway-planner /build/recipe.json ./recipe.json
|
|
||||||
RUN --mount=type=cache,id=aether-cargo-registry,target=/usr/local/cargo/registry,sharing=locked \
|
|
||||||
--mount=type=cache,id=aether-cargo-git,target=/usr/local/cargo/git,sharing=locked \
|
|
||||||
--mount=type=cache,id=aether-cargo-target-local,target=/build/target,sharing=locked \
|
|
||||||
cargo chef cook --release --locked --package aether-gateway --bin aether-gateway --recipe-path recipe.json
|
|
||||||
|
|
||||||
COPY Cargo.toml Cargo.lock ./
|
|
||||||
COPY apps/ ./apps/
|
|
||||||
COPY crates/ ./crates/
|
|
||||||
RUN --mount=type=cache,id=aether-cargo-registry,target=/usr/local/cargo/registry,sharing=locked \
|
|
||||||
--mount=type=cache,id=aether-cargo-git,target=/usr/local/cargo/git,sharing=locked \
|
|
||||||
--mount=type=cache,id=aether-cargo-target-local,target=/build/target,sharing=locked \
|
|
||||||
cargo build --release --locked -p aether-gateway && \
|
|
||||||
cp target/release/aether-gateway /tmp/aether-gateway
|
|
||||||
|
|
||||||
# ==================== 最小运行时打包 ====================
|
|
||||||
FROM gateway-builder AS runtime-prep
|
|
||||||
RUN set -eux; \
|
|
||||||
mkdir -p \
|
|
||||||
/runtime-root/app/data \
|
|
||||||
/runtime-root/app/logs \
|
|
||||||
/runtime-root/etc \
|
|
||||||
/runtime-root/etc/ssl \
|
|
||||||
/runtime-root/lib \
|
|
||||||
/runtime-root/lib64 \
|
|
||||||
/runtime-root/usr/local/bin; \
|
|
||||||
cp /tmp/aether-gateway /runtime-root/usr/local/bin/aether-gateway; \
|
|
||||||
: > /tmp/runtime-libs.txt; \
|
|
||||||
: > /tmp/runtime-scan-queue.txt; \
|
|
||||||
printf '%s\n' /tmp/aether-gateway >> /tmp/runtime-scan-queue.txt; \
|
|
||||||
while [ -s /tmp/runtime-scan-queue.txt ]; do \
|
|
||||||
current="$(head -n1 /tmp/runtime-scan-queue.txt)"; \
|
|
||||||
sed -i '1d' /tmp/runtime-scan-queue.txt; \
|
|
||||||
ldd "$current" | awk '/=>/ { print $3 } $1 ~ /^\// { print $1 }' | while read -r lib; do \
|
|
||||||
[ -n "$lib" ]; \
|
|
||||||
if ! grep -Fxq "$lib" /tmp/runtime-libs.txt; then \
|
|
||||||
printf '%s\n' "$lib" >> /tmp/runtime-libs.txt; \
|
|
||||||
printf '%s\n' "$lib" >> /tmp/runtime-scan-queue.txt; \
|
|
||||||
fi; \
|
|
||||||
done; \
|
|
||||||
done; \
|
|
||||||
sort -u /tmp/runtime-libs.txt -o /tmp/runtime-libs.txt; \
|
|
||||||
while read -r lib; do \
|
|
||||||
[ -n "$lib" ]; \
|
|
||||||
dest="/runtime-root$(dirname "$lib")"; \
|
|
||||||
mkdir -p "$dest"; \
|
|
||||||
cp -L "$lib" "$dest/"; \
|
|
||||||
done < /tmp/runtime-libs.txt; \
|
|
||||||
for lib in \
|
|
||||||
/lib/x86_64-linux-gnu/libnss_dns.so.2 \
|
|
||||||
/lib/x86_64-linux-gnu/libnss_files.so.2 \
|
|
||||||
/lib/x86_64-linux-gnu/libresolv.so.2; do \
|
|
||||||
if [ -f "$lib" ]; then \
|
|
||||||
dest="/runtime-root$(dirname "$lib")"; \
|
|
||||||
mkdir -p "$dest"; \
|
|
||||||
cp -L "$lib" "$dest/"; \
|
|
||||||
fi; \
|
|
||||||
done; \
|
|
||||||
cp -a /usr/lib/ssl /runtime-root/usr/lib/; \
|
|
||||||
cp -a /etc/ssl/certs /runtime-root/etc/ssl/; \
|
|
||||||
if [ -f /etc/ssl/openssl.cnf ]; then \
|
|
||||||
cp /etc/ssl/openssl.cnf /runtime-root/etc/ssl/openssl.cnf; \
|
|
||||||
fi; \
|
|
||||||
if [ -f /etc/nsswitch.conf ]; then \
|
|
||||||
cp /etc/nsswitch.conf /runtime-root/etc/nsswitch.conf; \
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ==================== 运行时镜像 ====================
|
|
||||||
FROM scratch
|
|
||||||
|
|
||||||
# 复制 gateway 二进制
|
|
||||||
COPY --from=runtime-prep /runtime-root/ /
|
|
||||||
|
|
||||||
# 复制前端构建产物
|
|
||||||
COPY --from=frontend-builder /app/frontend/dist /srv/frontend
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
ENV LANG=C.UTF-8 \
|
|
||||||
LC_ALL=C.UTF-8 \
|
|
||||||
RUST_LOG=aether_gateway=info \
|
|
||||||
APP_PORT=8084 \
|
|
||||||
AETHER_GATEWAY_STATIC_DIR=/srv/frontend
|
|
||||||
|
|
||||||
EXPOSE 8084
|
|
||||||
|
|
||||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
||||||
CMD ["/usr/local/bin/aether-gateway", "--healthcheck"]
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/aether-gateway"]
|
|
||||||
138
README.md
138
README.md
@@ -44,70 +44,23 @@ cd Aether
|
|||||||
|
|
||||||
# 2. 配置环境变量
|
# 2. 配置环境变量
|
||||||
cp .env.example .env
|
cp .env.example .env
|
||||||
./generate_keys.sh # 生成 JWT_SECRET_KEY / ENCRYPTION_KEY, 并填入 .env
|
# 生成 JWT_SECRET_KEY / ENCRYPTION_KEY, 并填入 .env
|
||||||
# 编辑 .env 设置 ADMIN_PASSWORD
|
|
||||||
|
|
||||||
# 3. 首次部署 / 更新
|
|
||||||
docker compose pull && docker compose up -d
|
|
||||||
|
|
||||||
# 4. 默认会在 app 启动前自动执行挂起的 migration / backfill
|
|
||||||
# 如需手工控制,可在 .env 中设 AETHER_GATEWAY_AUTO_PREPARE_DATABASE=false
|
|
||||||
# 然后按需执行:
|
|
||||||
docker compose run --rm app --migrate
|
|
||||||
docker compose run --rm app --apply-backfills
|
|
||||||
|
|
||||||
# 5. 升级前备份 (可选)
|
|
||||||
docker compose exec postgres pg_dump -U postgres aether | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gz
|
|
||||||
```
|
|
||||||
|
|
||||||
### Docker Compose(本地构建镜像)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 克隆代码
|
|
||||||
git clone https://github.com/fawney19/Aether.git
|
|
||||||
cd Aether
|
|
||||||
|
|
||||||
# 2. 配置环境变量
|
|
||||||
cp .env.example .env
|
|
||||||
./generate_keys.sh # 生成 JWT_SECRET_KEY / ENCRYPTION_KEY, 并填入 .env
|
|
||||||
# 编辑 .env 设置 ADMIN_PASSWORD
|
|
||||||
|
|
||||||
# 3. 部署 / 更新(自动构建并启动)
|
|
||||||
git pull
|
|
||||||
./deploy.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
### Docker Compose(单容器 SQLite / solo)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 1. 克隆代码
|
|
||||||
git clone https://github.com/fawney19/Aether.git
|
|
||||||
cd Aether
|
|
||||||
|
|
||||||
# 2. 配置环境变量
|
|
||||||
cp .env.example .env
|
|
||||||
./generate_keys.sh
|
./generate_keys.sh
|
||||||
# 编辑 .env 设置 ADMIN_PASSWORD
|
# 编辑 .env 设置 ADMIN_PASSWORD
|
||||||
|
|
||||||
# 3. 启动单容器 SQLite 版本
|
# 3. 首次部署 / 更新 (从以下数据库、内存策略任选其一)
|
||||||
docker compose -f docker-compose.solo.yml up -d
|
# Postgres + Redis (适用于企业或多人使用)
|
||||||
|
docker compose pull && docker compose up -d
|
||||||
# 4. 升级前备份(可选)
|
# 仅SQLite (适用于个人用户或朋友分享)
|
||||||
cp -a data/aether.db backup_$(date +%Y%m%d_%H%M%S).db
|
docker compose -f docker-compose.sqlite.yml pull && docker compose -f docker-compose.sqlite.yml up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
### 一键安装(可选部署方式)
|
### 一键安装(可选部署方式)
|
||||||
|
|
||||||
安装脚本先从 `aether-rust-pioneer` 分支下载,不依赖 GitHub Release 的 `latest` 脚本地址。运行后会先选择语言,再选择版本和部署方式。Linux 单机 / 集群服务使用 systemd,macOS 单机 / 集群服务使用系统级 launchd;脚本会按当前系统自动下载 `linux-*` 或 `macos-*` Release 压缩包。
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -fsSL https://raw.githubusercontent.com/fawney19/Aether/aether-rust-pioneer/install.sh | sudo bash
|
curl -fsSL https://raw.githubusercontent.com/fawney19/Aether/main/install.sh | sudo bash
|
||||||
```
|
```
|
||||||
|
|
||||||
运行后按提示输入语言、版本和部署方式。默认会安装最新正式版。需要提前测试时可用 `AETHER_CHANNEL=rc` 或 `AETHER_CHANNEL=beta`;Docker Compose 模式默认使用 `latest` 镜像通道。固定安装某个 tag 时,版本选择选 `4`,再输入类似 `v0.7.0-rc.1` 的 tag。
|
|
||||||
二进制安装在下载 Release 压缩包前会询问是否使用下载加速源;选择使用时会先打印原始 GitHub URL,再要求输入新的压缩包下载 URL。非交互式安装可用 `AETHER_RELEASE_ARCHIVE_URL` 指定压缩包 URL。
|
|
||||||
如果安装目录里已经有配置,脚本会优先复用:Docker Compose 保留已有 `.env`,二进制服务模式保留已有 `/etc/aether/aether-gateway.env`。只有首次生成新配置时才会提示输入管理员密码。
|
|
||||||
|
|
||||||
```text
|
```text
|
||||||
请选择安装语言 / Choose installer language:
|
请选择安装语言 / Choose installer language:
|
||||||
1) 中文
|
1) 中文
|
||||||
@@ -173,47 +126,6 @@ DATABASE_URL=postgresql://...
|
|||||||
REDIS_URL=redis://...
|
REDIS_URL=redis://...
|
||||||
```
|
```
|
||||||
|
|
||||||
### 本地开发
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 启动依赖
|
|
||||||
docker compose -f docker-compose.build.yml up -d postgres redis
|
|
||||||
|
|
||||||
# 数据库迁移(仅在已有数据库引入新 migration 时需要)
|
|
||||||
./dev.sh --migrate
|
|
||||||
|
|
||||||
# 数据回填
|
|
||||||
./dev.sh --apply-backfills
|
|
||||||
|
|
||||||
# 后端
|
|
||||||
./dev.sh
|
|
||||||
|
|
||||||
# 前端
|
|
||||||
cd frontend && npm install && npm run dev
|
|
||||||
```
|
|
||||||
|
|
||||||
`./dev.sh` 现在只保留一种本地模式:
|
|
||||||
|
|
||||||
| 角色 | 本地地址 | 说明 |
|
|
||||||
|------|----------|------|
|
|
||||||
| Rust frontdoor | 默认 `http://localhost:8084` | `aether-gateway`,本地唯一公开入口;实际端口由 `APP_PORT` 控制 |
|
|
||||||
|
|
||||||
本地默认链路是:
|
|
||||||
|
|
||||||
```text
|
|
||||||
client -> rust frontdoor (aether-gateway) -> execution_runtime/provider transport
|
|
||||||
```
|
|
||||||
|
|
||||||
其中:
|
|
||||||
|
|
||||||
- `aether-gateway` 负责公开入口、健康检查、格式转换、本地执行 runtime,以及当前已迁到 Rust 的 frontdoor/control/background 路径。
|
|
||||||
- `./dev.sh` 不再启动 Python 宿主;未下沉到 Rust 的 legacy 路由会直接失败。
|
|
||||||
- `./dev.sh --migrate` 会复用 `.env` 里的数据库配置,显式执行一次数据库迁移后退出。
|
|
||||||
- `./dev.sh` 默认把 `AETHER_GATEWAY_VIDEO_TASK_TRUTH_SOURCE_MODE` 设为 `rust-authoritative`,避免本地还依赖 Python sync report 语义。
|
|
||||||
- 空库首次启动会自动初始化到当前 baseline。
|
|
||||||
- `aether-gateway` 默认启动不会自动应用后续 schema migration;如果数据库版本落后,服务会拒绝启动,并提示先执行 `aether-gateway --migrate`。
|
|
||||||
- 仓库自带的 `docker-compose.yml` 和 `docker-compose.build.yml` 都已把 `AETHER_GATEWAY_AUTO_PREPARE_DATABASE` 设为默认开启,因此无论是预构建镜像部署还是 `./deploy.sh` / 本地构建 compose,常规启动都会在监听端口前自动执行挂起的 migration 和 backfill。
|
|
||||||
|
|
||||||
## Aether Proxy (可选)
|
## Aether Proxy (可选)
|
||||||
|
|
||||||
Aether Proxy 是配套的正向代理节点,部署在海外 VPS 上,为墙内的 Aether 实例中转 API 流量。或者部署在其他服务器为指定的提供商、账号、Key使用不同的节点访问。支持 TUI 向导一键配置、systemd 服务管理、TLS 加密、DNS 缓存及连接池调优。
|
Aether Proxy 是配套的正向代理节点,部署在海外 VPS 上,为墙内的 Aether 实例中转 API 流量。或者部署在其他服务器为指定的提供商、账号、Key使用不同的节点访问。支持 TUI 向导一键配置、systemd 服务管理、TLS 加密、DNS 缓存及连接池调优。
|
||||||
@@ -240,7 +152,7 @@ Aether Proxy 是配套的正向代理节点,部署在海外 VPS 上,为墙
|
|||||||
- `AETHER_DATABASE_DRIVER` / `AETHER_DATABASE_URL`:二进制单机部署可用 `sqlite`,例如 `sqlite:///opt/aether/data/aether.db`
|
- `AETHER_DATABASE_DRIVER` / `AETHER_DATABASE_URL`:二进制单机部署可用 `sqlite`,例如 `sqlite:///opt/aether/data/aether.db`
|
||||||
- `DATABASE_URL` / `REDIS_URL`:共享后端连接串;多节点必须配置共享数据库和 Redis
|
- `DATABASE_URL` / `REDIS_URL`:共享后端连接串;多节点必须配置共享数据库和 Redis
|
||||||
- `AETHER_RUNTIME_BACKEND=memory|redis`:运行时缓存/协调后端。单机 SQLite 默认用 `memory`,不会连接 Redis;显式设为 `redis` 或多节点部署才会把 `REDIS_URL` 注入运行时 Redis 后端
|
- `AETHER_RUNTIME_BACKEND=memory|redis`:运行时缓存/协调后端。单机 SQLite 默认用 `memory`,不会连接 Redis;显式设为 `redis` 或多节点部署才会把 `REDIS_URL` 注入运行时 Redis 后端
|
||||||
- `AETHER_GATEWAY_AUTO_PREPARE_DATABASE`:常规启动前自动执行挂起的 schema migration 和 backfill;仓库自带的 `docker-compose.yml` 和 `docker-compose.build.yml` 默认开启
|
- `AETHER_GATEWAY_AUTO_PREPARE_DATABASE`:常规启动前自动执行挂起的 schema migration 和 backfill;仓库自带的 `docker-compose.yml` 默认开启
|
||||||
- `JWT_SECRET_KEY` / `ENCRYPTION_KEY`:认证和敏感数据加密所需密钥
|
- `JWT_SECRET_KEY` / `ENCRYPTION_KEY`:认证和敏感数据加密所需密钥
|
||||||
- `API_KEY_PREFIX`:用户和管理员新建 API Key 时使用的前缀,默认 `sk`
|
- `API_KEY_PREFIX`:用户和管理员新建 API Key 时使用的前缀,默认 `sk`
|
||||||
- `ADMIN_USERNAME` / `ADMIN_PASSWORD` / `ADMIN_EMAIL`:首次启动时自举首个本地管理员;`install.sh` 会提示输入管理员密码
|
- `ADMIN_USERNAME` / `ADMIN_PASSWORD` / `ADMIN_EMAIL`:首次启动时自举首个本地管理员;`install.sh` 会提示输入管理员密码
|
||||||
@@ -252,40 +164,6 @@ Aether Proxy 是配套的正向代理节点,部署在海外 VPS 上,为墙
|
|||||||
|
|
||||||
systemd 的 `.env` 必须保持简单 `KEY=VALUE` 形式,不要写 `export`、`${VAR}` 或命令替换。
|
systemd 的 `.env` 必须保持简单 `KEY=VALUE` 形式,不要写 `export`、`${VAR}` 或命令替换。
|
||||||
|
|
||||||
## Q&A
|
|
||||||
|
|
||||||
### Q: 如何开启/关闭请求体记录?
|
|
||||||
|
|
||||||
管理员在 **系统设置** 中配置日志记录的详细程度:
|
|
||||||
|
|
||||||
| 级别 | 记录内容 |
|
|
||||||
|------|----------|
|
|
||||||
| Base | 基本请求信息 |
|
|
||||||
| Headers | Base + 请求头 |
|
|
||||||
| Full | Headers + 请求体 |
|
|
||||||
|
|
||||||
### Q: 更新出问题如何回滚?
|
|
||||||
|
|
||||||
**有备份的情况(推荐):**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Docker Compose:
|
|
||||||
# 1. 切回旧镜像 tag / digest
|
|
||||||
# 2. 恢复 Postgres 备份
|
|
||||||
# 3. 再启动 app
|
|
||||||
|
|
||||||
# systemd:
|
|
||||||
# 1. 把 /opt/aether/current 切回旧 release
|
|
||||||
# 2. systemctl restart aether-gateway
|
|
||||||
# 3. 如果升级包含数据库结构变更,再恢复 Postgres 备份
|
|
||||||
```
|
|
||||||
|
|
||||||
> 可以在升级前通过 `docker inspect ghcr.io/fawney19/aether:latest --format '{{index .RepoDigests 0}}'` 记录当前镜像 digest,方便回滚时使用。
|
|
||||||
|
|
||||||
**没有备份的情况:**
|
|
||||||
|
|
||||||
当前不应该再依赖旧的 `alembic downgrade` 路线。空库首次启动会自动初始化;如果开启 `AETHER_GATEWAY_AUTO_PREPARE_DATABASE=true`(仓库自带的两份 compose 默认都如此),常规服务启动也会自动应用挂起的 migration/backfill。无论是否自动执行,只要本次发布带来了不可逆的数据结构变化,没有备份就不能保证安全回滚。因此升级前强烈建议先备份 `Postgres`。
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 许可证
|
## 许可证
|
||||||
|
|||||||
144
deploy.sh
144
deploy.sh
@@ -1,144 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# 智能部署脚本 - 自动检测代码变化并重建
|
|
||||||
#
|
|
||||||
# 用法:
|
|
||||||
# 部署/更新: ./deploy.sh
|
|
||||||
# 强制全部重建: ./deploy.sh --force
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
cd "$(dirname "$0")"
|
|
||||||
|
|
||||||
# 兼容 docker-compose 和 docker compose
|
|
||||||
if command -v docker-compose &> /dev/null; then
|
|
||||||
DC="docker-compose -f docker-compose.build.yml"
|
|
||||||
USE_LEGACY_COMPOSE=true
|
|
||||||
else
|
|
||||||
DC="docker compose -f docker-compose.build.yml"
|
|
||||||
USE_LEGACY_COMPOSE=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
compose_up() {
|
|
||||||
if [ "$USE_LEGACY_COMPOSE" = true ]; then
|
|
||||||
$DC up -d --no-build "$@"
|
|
||||||
else
|
|
||||||
$DC up -d --no-build --pull never "$@"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 缓存文件
|
|
||||||
CODE_HASH_FILE=".code-hash"
|
|
||||||
|
|
||||||
usage() {
|
|
||||||
cat <<'EOF'
|
|
||||||
Usage: ./deploy.sh [options]
|
|
||||||
|
|
||||||
Options:
|
|
||||||
--force, -f 强制重建并重启
|
|
||||||
-h, --help 显示帮助
|
|
||||||
EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
FORCE_REBUILD_ALL=false
|
|
||||||
|
|
||||||
while [ $# -gt 0 ]; do
|
|
||||||
case "$1" in
|
|
||||||
--force|-f)
|
|
||||||
FORCE_REBUILD_ALL=true
|
|
||||||
shift
|
|
||||||
;;
|
|
||||||
-h|--help)
|
|
||||||
usage
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Unknown argument: $1"
|
|
||||||
usage
|
|
||||||
exit 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# 计算代码文件的哈希值
|
|
||||||
calc_code_hash() {
|
|
||||||
{
|
|
||||||
cat Dockerfile.app.local 2>/dev/null
|
|
||||||
cat Cargo.toml Cargo.lock 2>/dev/null
|
|
||||||
find frontend/src -type f \( -name "*.vue" -o -name "*.ts" -o -name "*.tsx" -o -name "*.js" \) 2>/dev/null | sort | xargs cat 2>/dev/null
|
|
||||||
find apps -type f \( -name "*.rs" -o -name "Cargo.toml" \) 2>/dev/null | sort | xargs cat 2>/dev/null
|
|
||||||
find crates -type f \( -name "*.rs" -o -name "*.sql" -o -name "Cargo.toml" \) 2>/dev/null | sort | xargs cat 2>/dev/null
|
|
||||||
} | md5sum | cut -d' ' -f1
|
|
||||||
}
|
|
||||||
|
|
||||||
# 检查代码是否变化
|
|
||||||
check_code_changed() {
|
|
||||||
local current_hash=$(calc_code_hash)
|
|
||||||
if [ -f "$CODE_HASH_FILE" ]; then
|
|
||||||
local saved_hash=$(cat "$CODE_HASH_FILE")
|
|
||||||
if [ "$current_hash" = "$saved_hash" ]; then
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
save_code_hash() { calc_code_hash > "$CODE_HASH_FILE"; }
|
|
||||||
|
|
||||||
# 构建应用镜像
|
|
||||||
build_app() {
|
|
||||||
echo ">>> Building app image (rust gateway + frontend)..."
|
|
||||||
docker build --pull=false -f Dockerfile.app.local -t aether-app:latest .
|
|
||||||
save_code_hash
|
|
||||||
}
|
|
||||||
|
|
||||||
# 强制全部重建
|
|
||||||
if [ "$FORCE_REBUILD_ALL" = true ]; then
|
|
||||||
echo ">>> Force rebuilding everything..."
|
|
||||||
build_app
|
|
||||||
compose_up --force-recreate
|
|
||||||
docker image prune -f
|
|
||||||
echo ">>> Done!"
|
|
||||||
$DC ps
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 标记是否需要重启
|
|
||||||
NEED_RESTART=false
|
|
||||||
|
|
||||||
# 检查代码是否变化
|
|
||||||
if ! docker image inspect aether-app:latest >/dev/null 2>&1; then
|
|
||||||
echo ">>> App image not found, building..."
|
|
||||||
build_app
|
|
||||||
NEED_RESTART=true
|
|
||||||
elif check_code_changed; then
|
|
||||||
echo ">>> Code changed, rebuilding app image..."
|
|
||||||
build_app
|
|
||||||
NEED_RESTART=true
|
|
||||||
else
|
|
||||||
echo ">>> Code unchanged."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 检查容器是否在运行
|
|
||||||
CONTAINERS_RUNNING=true
|
|
||||||
if [ -z "$($DC ps -q 2>/dev/null)" ]; then
|
|
||||||
CONTAINERS_RUNNING=false
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 有变化时重启,或容器未运行时启动
|
|
||||||
if [ "$NEED_RESTART" = true ]; then
|
|
||||||
echo ">>> Restarting services..."
|
|
||||||
compose_up
|
|
||||||
elif [ "$CONTAINERS_RUNNING" = false ]; then
|
|
||||||
echo ">>> Containers not running, starting services..."
|
|
||||||
compose_up
|
|
||||||
else
|
|
||||||
echo ">>> No changes detected, skipping restart."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 清理
|
|
||||||
docker image prune -f >/dev/null 2>&1 || true
|
|
||||||
|
|
||||||
echo ">>> Done!"
|
|
||||||
echo ">>> Note: empty databases auto-bootstrap on first start."
|
|
||||||
echo ">>> Note: docker compose now defaults to auto-running pending migrations/backfills on app startup."
|
|
||||||
echo ">>> Note: set AETHER_GATEWAY_AUTO_PREPARE_DATABASE=false if you want to keep manual rollout."
|
|
||||||
$DC ps
|
|
||||||
4
dev.sh
4
dev.sh
@@ -95,13 +95,13 @@ dev_uses_redis_runtime() {
|
|||||||
print_dev_infra_hint() {
|
print_dev_infra_hint() {
|
||||||
echo "=> 本地开发依赖未就绪。"
|
echo "=> 本地开发依赖未就绪。"
|
||||||
echo "=> 请先启动 Postgres / Redis:"
|
echo "=> 请先启动 Postgres / Redis:"
|
||||||
echo "=> docker compose -f docker-compose.build.yml up -d postgres redis"
|
echo "=> docker compose up -d postgres redis"
|
||||||
}
|
}
|
||||||
|
|
||||||
print_postgres_hint() {
|
print_postgres_hint() {
|
||||||
echo "=> PostgreSQL 未就绪。"
|
echo "=> PostgreSQL 未就绪。"
|
||||||
echo "=> 请先启动 Postgres:"
|
echo "=> 请先启动 Postgres:"
|
||||||
echo "=> docker compose -f docker-compose.build.yml up -d postgres"
|
echo "=> docker compose up -d postgres"
|
||||||
}
|
}
|
||||||
|
|
||||||
check_postgres_ready() {
|
check_postgres_ready() {
|
||||||
|
|||||||
@@ -1,95 +0,0 @@
|
|||||||
# Aether 部署配置 - 本地构建
|
|
||||||
# 使用方法:
|
|
||||||
# 启动服务: docker compose -f docker-compose.build.yml up -d --build
|
|
||||||
# 或使用: ./deploy.sh
|
|
||||||
|
|
||||||
services:
|
|
||||||
postgres:
|
|
||||||
image: postgres:15
|
|
||||||
container_name: aether-postgres
|
|
||||||
environment:
|
|
||||||
POSTGRES_DB: aether
|
|
||||||
POSTGRES_USER: postgres
|
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
ports:
|
|
||||||
- "${DB_PORT:-5432}:5432"
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
|
|
||||||
interval: 5s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7-alpine
|
|
||||||
container_name: aether-redis
|
|
||||||
command: redis-server --appendonly yes --appendfsync everysec --save 60 1000 --requirepass ${REDIS_PASSWORD}
|
|
||||||
volumes:
|
|
||||||
- redis_data:/data
|
|
||||||
ports:
|
|
||||||
- "${REDIS_PORT:-6379}:6379"
|
|
||||||
healthcheck:
|
|
||||||
test: [ "CMD-SHELL", "redis-cli -a \"${REDIS_PASSWORD}\" ping | grep -q PONG" ]
|
|
||||||
interval: 5s
|
|
||||||
timeout: 3s
|
|
||||||
retries: 5
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
mysql:
|
|
||||||
image: mysql:8.0
|
|
||||||
container_name: aether-mysql
|
|
||||||
profiles:
|
|
||||||
- mysql
|
|
||||||
environment:
|
|
||||||
MYSQL_DATABASE: ${MYSQL_DATABASE:-aether}
|
|
||||||
MYSQL_USER: ${MYSQL_USER:-aether}
|
|
||||||
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-aether}
|
|
||||||
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-aether_root}
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
volumes:
|
|
||||||
- mysql_data:/var/lib/mysql
|
|
||||||
ports:
|
|
||||||
- "${MYSQL_PORT:-3306}:3306"
|
|
||||||
healthcheck:
|
|
||||||
test:
|
|
||||||
[
|
|
||||||
"CMD-SHELL",
|
|
||||||
"mysqladmin ping -h 127.0.0.1 -u$${MYSQL_USER} -p$${MYSQL_PASSWORD} --silent"
|
|
||||||
]
|
|
||||||
interval: 5s
|
|
||||||
timeout: 5s
|
|
||||||
retries: 10
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
app:
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: Dockerfile.app.local
|
|
||||||
image: aether-app:latest
|
|
||||||
container_name: aether-app
|
|
||||||
env_file:
|
|
||||||
- .env
|
|
||||||
environment:
|
|
||||||
DATABASE_URL: postgresql://postgres:${DB_PASSWORD}@postgres:5432/aether
|
|
||||||
REDIS_URL: redis://:${REDIS_PASSWORD}@redis:6379/0
|
|
||||||
TZ: Asia/Shanghai
|
|
||||||
APP_PORT: ${APP_PORT:-8084}
|
|
||||||
AETHER_GATEWAY_AUTO_PREPARE_DATABASE: ${AETHER_GATEWAY_AUTO_PREPARE_DATABASE:-true}
|
|
||||||
depends_on:
|
|
||||||
postgres:
|
|
||||||
condition: service_healthy
|
|
||||||
redis:
|
|
||||||
condition: service_healthy
|
|
||||||
ports:
|
|
||||||
- "${APP_PORT:-8084}:${APP_PORT:-8084}"
|
|
||||||
volumes:
|
|
||||||
- ./logs:/app/logs
|
|
||||||
restart: unless-stopped
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
mysql_data:
|
|
||||||
redis_data:
|
|
||||||
@@ -12,6 +12,8 @@ services:
|
|||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
volumes:
|
volumes:
|
||||||
- postgres_data:/var/lib/postgresql/data
|
- postgres_data:/var/lib/postgresql/data
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:${DB_PORT:-5432}:5432"
|
||||||
command: postgres -c idle_in_transaction_session_timeout=30000 -c tcp_keepalives_idle=30 -c tcp_keepalives_interval=10
|
command: postgres -c idle_in_transaction_session_timeout=30000 -c tcp_keepalives_idle=30 -c tcp_keepalives_interval=10
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
|
test: [ "CMD-SHELL", "pg_isready -U postgres" ]
|
||||||
@@ -26,6 +28,8 @@ services:
|
|||||||
command: redis-server --appendonly yes --appendfsync everysec --save 60 1000 --requirepass ${REDIS_PASSWORD}
|
command: redis-server --appendonly yes --appendfsync everysec --save 60 1000 --requirepass ${REDIS_PASSWORD}
|
||||||
volumes:
|
volumes:
|
||||||
- redis_data:/data
|
- redis_data:/data
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:${REDIS_PORT:-6379}:6379"
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: [ "CMD-SHELL", "redis-cli -a \"${REDIS_PASSWORD}\" ping | grep -q PONG" ]
|
test: [ "CMD-SHELL", "redis-cli -a \"${REDIS_PASSWORD}\" ping | grep -q PONG" ]
|
||||||
interval: 5s
|
interval: 5s
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import {
|
|||||||
Server,
|
Server,
|
||||||
Key,
|
Key,
|
||||||
Container,
|
Container,
|
||||||
Code,
|
|
||||||
Shield,
|
Shield,
|
||||||
Monitor,
|
Monitor,
|
||||||
Check,
|
Check,
|
||||||
@@ -44,38 +43,11 @@ const productionSteps = [
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const localBuildSteps = [
|
|
||||||
{
|
|
||||||
title: '克隆代码',
|
|
||||||
code: 'git clone https://github.com/fawney19/Aether.git\ncd Aether',
|
|
||||||
icon: Code
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '配置环境变量',
|
|
||||||
note: '生成密钥并填入 .env',
|
|
||||||
code: 'cp .env.example .env\npython generate_keys.py',
|
|
||||||
icon: Key
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '构建',
|
|
||||||
note: '自动构建、启动、迁移',
|
|
||||||
code: './deploy.sh',
|
|
||||||
icon: Container
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: '更新',
|
|
||||||
note: '需要拉取最新代码',
|
|
||||||
code: 'git pull origin main',
|
|
||||||
icon: Code,
|
|
||||||
optional: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const developmentSteps = [
|
const developmentSteps = [
|
||||||
{
|
{
|
||||||
title: '启动依赖',
|
title: '启动依赖',
|
||||||
note: 'PostgreSQL + Redis',
|
note: 'PostgreSQL + Redis',
|
||||||
code: 'docker compose -f docker-compose.build.yml up -d postgres redis',
|
code: 'docker compose up -d postgres redis',
|
||||||
icon: Container
|
icon: Container
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -133,7 +105,6 @@ function copyStep(stepId: string, code: string) {
|
|||||||
<button
|
<button
|
||||||
v-for="(tab, idx) in [
|
v-for="(tab, idx) in [
|
||||||
{ icon: Container, label: 'Docker 预构建镜像' },
|
{ icon: Container, label: 'Docker 预构建镜像' },
|
||||||
{ icon: Code, label: '本地代码构建' },
|
|
||||||
{ icon: Monitor, label: '本地开发' }
|
{ icon: Monitor, label: '本地开发' }
|
||||||
]"
|
]"
|
||||||
:key="idx"
|
:key="idx"
|
||||||
@@ -200,58 +171,9 @@ function copyStep(stepId: string, code: string) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 本地构建步骤 -->
|
|
||||||
<div
|
|
||||||
v-show="activeDeployTab === 1"
|
|
||||||
class="p-5 space-y-3"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
v-for="(step, idx) in localBuildSteps"
|
|
||||||
:key="idx"
|
|
||||||
class="group rounded-xl border border-[#e5e4df] dark:border-[rgba(227,224,211,0.12)] overflow-hidden transition-colors"
|
|
||||||
:class="step.optional ? 'border-dashed opacity-80' : ''"
|
|
||||||
>
|
|
||||||
<div class="flex items-center gap-3 px-4 py-3">
|
|
||||||
<span class="w-6 h-6 rounded-full flex items-center justify-center text-xs font-bold flex-shrink-0 bg-[#cc785c] text-white">
|
|
||||||
{{ idx + 1 }}
|
|
||||||
</span>
|
|
||||||
<div class="flex-1 min-w-0">
|
|
||||||
<div class="flex items-center gap-2">
|
|
||||||
<span class="text-sm font-medium text-[#262624] dark:text-[#f1ead8]">{{ step.title }}</span>
|
|
||||||
<span
|
|
||||||
v-if="step.optional"
|
|
||||||
class="text-[10px] px-1.5 py-0.5 rounded-full bg-[#e5e4df] dark:bg-[rgba(227,224,211,0.12)] text-[#666663] dark:text-[#a3a094]"
|
|
||||||
>
|
|
||||||
更新时
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<span
|
|
||||||
v-if="step.note"
|
|
||||||
class="text-xs text-[#91918d] dark:text-[#a3a094]/80"
|
|
||||||
>{{ step.note }}</span>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
class="flex items-center gap-1.5 px-2.5 py-1 rounded-md text-xs text-[#666663] dark:text-[#a3a094] hover:bg-[#f0f0eb] dark:hover:bg-[#3a3731] transition-colors shrink-0"
|
|
||||||
@click="copyStep(`build-${idx}`, step.code)"
|
|
||||||
>
|
|
||||||
<Check
|
|
||||||
v-if="copiedStep === `build-${idx}`"
|
|
||||||
class="h-3.5 w-3.5 text-green-500"
|
|
||||||
/>
|
|
||||||
<Copy
|
|
||||||
v-else
|
|
||||||
class="h-3.5 w-3.5"
|
|
||||||
/>
|
|
||||||
{{ copiedStep === `build-${idx}` ? '已复制' : '复制' }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<pre class="px-4 pb-3 text-[13px] font-mono text-[#262624] dark:text-[#f1ead8] overflow-x-auto leading-relaxed border-t border-[#e5e4df]/50 dark:border-[rgba(227,224,211,0.06)] pt-3 mx-4 mb-1"><code>{{ step.code }}</code></pre>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 开发环境步骤 -->
|
<!-- 开发环境步骤 -->
|
||||||
<div
|
<div
|
||||||
v-show="activeDeployTab === 2"
|
v-show="activeDeployTab === 1"
|
||||||
class="p-5 space-y-3"
|
class="p-5 space-y-3"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -20,28 +20,11 @@ docker compose pull && docker compose up -d
|
|||||||
docker compose exec postgres pg_dump -U postgres aether | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gz
|
docker compose exec postgres pg_dump -U postgres aether | gzip > backup_$(date +%Y%m%d_%H%M%S).sql.gz
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. 本地代码构建镜像 (Docker Compose)
|
### 2. 本地开发
|
||||||
```markdown
|
|
||||||
# 1. 克隆代码
|
|
||||||
git clone https://github.com/fawney19/Aether.git
|
|
||||||
cd Aether
|
|
||||||
|
|
||||||
# 2. 配置环境变量
|
|
||||||
cp .env.example .env
|
|
||||||
./generate_keys.sh # 生成密钥, 并将生成的密钥填入 .env
|
|
||||||
|
|
||||||
# 3. 构建(自动构建、启动、迁移)
|
|
||||||
./deploy.sh
|
|
||||||
|
|
||||||
# 4. 更新需要拉取最新代码
|
|
||||||
git pull origin main
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. 本地开发
|
|
||||||
依赖 Docker、uv、nodejs
|
依赖 Docker、uv、nodejs
|
||||||
```markdown
|
```markdown
|
||||||
# 启动数据库
|
# 启动数据库
|
||||||
docker compose -f docker-compose.build.yml up -d postgres redis
|
docker compose up -d postgres redis
|
||||||
|
|
||||||
# 后端
|
# 后端
|
||||||
uv sync
|
uv sync
|
||||||
|
|||||||
29
install.sh
29
install.sh
@@ -49,9 +49,9 @@ Usage: install.sh [options]
|
|||||||
Install Aether Gateway.
|
Install Aether Gateway.
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--mode MODE Deployment mode: compose, compose-solo, single, or cluster
|
--mode MODE Deployment mode: compose, compose-sqlite, single, or cluster
|
||||||
compose: Docker Compose app + Postgres + Redis
|
compose: Docker Compose app + Postgres + Redis
|
||||||
compose-solo: Docker Compose app + SQLite
|
compose-sqlite: Docker Compose app + SQLite
|
||||||
single: system service with SQLite + in-process runtime
|
single: system service with SQLite + in-process runtime
|
||||||
cluster: system service connected to shared database + Redis
|
cluster: system service connected to shared database + Redis
|
||||||
Linux services use systemd; macOS services use launchd
|
Linux services use systemd; macOS services use launchd
|
||||||
@@ -436,8 +436,8 @@ select_mode() {
|
|||||||
MODE="compose"
|
MODE="compose"
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
compose-solo|solo|docker-solo|docker-solo-compose)
|
compose-sqlite|sqlite-compose|compose-solo|solo|docker-solo|docker-solo-compose)
|
||||||
MODE="compose-solo"
|
MODE="compose-sqlite"
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
single|service|systemd|launchd|sqlite)
|
single|service|systemd|launchd|sqlite)
|
||||||
@@ -451,7 +451,7 @@ select_mode() {
|
|||||||
auto|"")
|
auto|"")
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
die "unsupported install mode: ${MODE}; expected compose, compose-solo, single, or cluster"
|
die "unsupported install mode: ${MODE}; expected compose, compose-sqlite, single, or cluster"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -494,7 +494,7 @@ EOF
|
|||||||
MODE="cluster"
|
MODE="cluster"
|
||||||
;;
|
;;
|
||||||
4)
|
4)
|
||||||
MODE="compose-solo"
|
MODE="compose-sqlite"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
if ui_is_zh; then
|
if ui_is_zh; then
|
||||||
@@ -1054,7 +1054,7 @@ generate_compose_env() {
|
|||||||
replace_or_append_env "${output}" "AETHER_GATEWAY_AUTO_PREPARE_DATABASE" "true"
|
replace_or_append_env "${output}" "AETHER_GATEWAY_AUTO_PREPARE_DATABASE" "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
generate_compose_solo_env() {
|
generate_compose_sqlite_env() {
|
||||||
local output="$1"
|
local output="$1"
|
||||||
local jwt_key encryption_key
|
local jwt_key encryption_key
|
||||||
prompt_admin_password
|
prompt_admin_password
|
||||||
@@ -1488,11 +1488,11 @@ Generate a fresh key set any time:
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
install_compose_solo_mode() {
|
install_compose_sqlite_mode() {
|
||||||
info "preparing Docker Compose solo deployment in ${COMPOSE_DIR}"
|
info "preparing Docker Compose SQLite deployment in ${COMPOSE_DIR}"
|
||||||
install -d -m 0755 "${COMPOSE_DIR}" "${COMPOSE_DIR}/logs" "${COMPOSE_DIR}/data"
|
install -d -m 0755 "${COMPOSE_DIR}" "${COMPOSE_DIR}/logs" "${COMPOSE_DIR}/data"
|
||||||
|
|
||||||
install_project_file "docker-compose.solo.yml" "${COMPOSE_DIR}/docker-compose.yml" "0644"
|
install_project_file "docker-compose.sqlite.yml" "${COMPOSE_DIR}/docker-compose.yml" "0644"
|
||||||
install_project_file ".env.example" "${COMPOSE_DIR}/.env.example" "0644"
|
install_project_file ".env.example" "${COMPOSE_DIR}/.env.example" "0644"
|
||||||
write_generate_keys_script "${COMPOSE_DIR}/generate_keys.sh"
|
write_generate_keys_script "${COMPOSE_DIR}/generate_keys.sh"
|
||||||
|
|
||||||
@@ -1500,13 +1500,13 @@ install_compose_solo_mode() {
|
|||||||
warn "keeping existing ${COMPOSE_DIR}/.env"
|
warn "keeping existing ${COMPOSE_DIR}/.env"
|
||||||
else
|
else
|
||||||
info "generating ${COMPOSE_DIR}/.env"
|
info "generating ${COMPOSE_DIR}/.env"
|
||||||
generate_compose_solo_env "${COMPOSE_DIR}/.env"
|
generate_compose_sqlite_env "${COMPOSE_DIR}/.env"
|
||||||
chmod 0600 "${COMPOSE_DIR}/.env"
|
chmod 0600 "${COMPOSE_DIR}/.env"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat <<EOF
|
cat <<EOF
|
||||||
|
|
||||||
Docker Compose solo files are ready:
|
Docker Compose SQLite files are ready:
|
||||||
${COMPOSE_DIR}/docker-compose.yml
|
${COMPOSE_DIR}/docker-compose.yml
|
||||||
${COMPOSE_DIR}/.env
|
${COMPOSE_DIR}/.env
|
||||||
${COMPOSE_DIR}/.env.example
|
${COMPOSE_DIR}/.env.example
|
||||||
@@ -1516,6 +1516,7 @@ Docker Compose solo files are ready:
|
|||||||
|
|
||||||
Next steps:
|
Next steps:
|
||||||
cd ${COMPOSE_DIR}
|
cd ${COMPOSE_DIR}
|
||||||
|
docker compose pull
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
docker compose logs -f app
|
docker compose logs -f app
|
||||||
|
|
||||||
@@ -1941,8 +1942,8 @@ main() {
|
|||||||
|
|
||||||
if [[ "${MODE}" == "compose" ]]; then
|
if [[ "${MODE}" == "compose" ]]; then
|
||||||
install_compose_mode
|
install_compose_mode
|
||||||
elif [[ "${MODE}" == "compose-solo" ]]; then
|
elif [[ "${MODE}" == "compose-sqlite" ]]; then
|
||||||
install_compose_solo_mode
|
install_compose_sqlite_mode
|
||||||
else
|
else
|
||||||
require_root
|
require_root
|
||||||
require_service_manager
|
require_service_manager
|
||||||
|
|||||||
Reference in New Issue
Block a user