Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.0.1
v0.2.1
5 changes: 0 additions & 5 deletions deploy/.gitignore

This file was deleted.

File renamed without changes.
5 changes: 5 additions & 0 deletions deploy/docker-compose/001-mysql-single/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/mysql/data/
/flexmodel/storage/
/flexmodel/pages/
/flexmodel/logs/
/flexmodel/database/
35 changes: 35 additions & 0 deletions deploy/docker-compose/002-mysql-fullstack/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
CONTAINER_NAME_PREFIX=prod2

# 运行模式: native (GraalVM 原生镜像) 或 jvm (JVM 模式)
# 切换方式:修改 FLEXMODEL_RUN_MODE 和 FLEXMODEL_SERVER_IMAGE 两行
# native → FLEXMODEL_SERVER_IMAGE=cjbi/flexmodel-server-native:latest
# jvm → FLEXMODEL_SERVER_IMAGE=cjbi/flexmodel-server:latest
FLEXMODEL_SERVER_IMAGE=cjbi/flexmodel-server-native:latest

# mysql
MYSQL_DATABASE=flexmodel
MYSQL_ROOT_PASSWORD=123456

# nginx
NGINX_HTTP_PORT=80
NGINX_HTTPS_PORT=443

# rabbitmq
RABBITMQ_DEFAULT_USER=flexmodel
RABBITMQ_DEFAULT_PASS=flexmodel
RABBITMQ_AMQP_PORT=5672
RABBITMQ_MANAGEMENT_PORT=15672
RABBITMQ_VIRTUAL_HOST=/

# rustfs (S3-compatible object storage)
RUSTFS_ACCESS_KEY=flexmodel
RUSTFS_SECRET_KEY=flexmodel123456
RUSTFS_BUCKET=flexmodel
# S3 API port (host) - used by external tools; server reaches rustfs internally
RUSTFS_S3_API_PORT=9000
# Web console port (host)
RUSTFS_CONSOLE_PORT=9001

# Project base domain (used for subdomain routing)
# e.g. preview.flexmodel.dev → {projectId}.preview.flexmodel.dev
FLEXMODEL_PROJECT_BASE_DOMAIN=flexmodel.wetech.tech
7 changes: 7 additions & 0 deletions deploy/docker-compose/002-mysql-fullstack/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/mysql/data/
/rustfs/data/
/rabbitmq/data/
/flexmodel/storage/
/flexmodel/pages/
/flexmodel/logs/
/flexmodel/database/
66 changes: 66 additions & 0 deletions deploy/docker-compose/002-mysql-fullstack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# docker-compose

Flexmodel 生产部署,包含以下服务:

| 服务 | 镜像 | 端口 |
|-------------------------------|-------------------------------------------|--------------|
| `mysql` | `mysql:8.0` | 3306 (内部) |
| `rabbitmq` | `rabbitmq:3.13-management` | 5672 / 15672 |
| `rustfs` | `rustfs/rustfs:latest` | 9000 / 9001 |
| `flexmodel` | `cjbi/flexmodel-server:latest` | 8080 (内部) |
| `flexmodel-ui` | `cjbi/flexmodel-ui:latest` | 80 |
| `flexmodel-functions-runtime` | `cjbi/flexmodel-functions-runtime:latest` | 9999 (内部) |
| `nginx` | `nginx:1.25.3` | 80 (内部) |

## 部署命令

* 拉取最新镜像

```shell
docker-compose pull
```

* 启动

```shell
docker-compose up
```

* 后台启动

```shell
docker-compose up -d
```

* 停止

```shell
docker-compose down
```

## RustFS 对象存储

本部署使用 [RustFS](https://rustfs.com)(S3 兼容的高性能对象存储)作为 `flexmodel-server` 的存储后端, 替代默认的本地磁盘存储。
`flexmodel.storage.type` 被置为 `s3`,所有 Bucket / 文件操作经由 S3 API 写入 RustFS。
| 服务 | 说明 |
|----------|---------------------------------------------------------------------| | `rustfs` | RustFS 主服务,S3 API
`9000`,Web 控制台 `9001`,使用宿主机目录持久化数据(./rustfs/data) |

### 关键配置(`.env`)

| 变量 | 说明 | 默认值 |
|-----------------------|-----------------------------|-------------------|
| `RUSTFS_ACCESS_KEY` | S3 Access Key | `flexmodel` |
| `RUSTFS_SECRET_KEY` | S3 Secret Key | `flexmodel123456` |
| `RUSTFS_BUCKET` | flexmodel-server 使用的桶名 | `flexmodel` |
| `RUSTFS_S3_API_PORT` | 对外暴露的 S3 API 端口 | `9000` |
| `RUSTFS_CONSOLE_PORT` | 对外暴露的 Web 控制台端口 | `9001` |

### 注意事项

- 单盘单节点模式下已开启 `RUSTFS_UNSAFE_BYPASS_DISK_CHECK=true`;生产环境建议挂载多盘并关闭该选项以启用纠删码。
- `flexmodel-server` 依赖 `rustfs` 健康检查通过后启动;启动时若桶不存在会自动创建(见下条)。
- `flexmodel-server` 的 `S3Backend` 对所有 S3 兼容存储通用:启动校验时桶不存在则自动 `createBucket`
,只读模式下不自动创建并报错提示运维预先建桶。因此本部署无需额外的初始化容器。
- Web 控制台访问:`http://<host>:${RUSTFS_CONSOLE_PORT}`,使用 `RUSTFS_ACCESS_KEY` / `RUSTFS_SECRET_KEY` 登录。
- 切回本地存储:删除 `flexmodel-server` 环境变量中的 `FLEXMODEL_STORAGE_TYPE` 及 `QUARKUS_S3_*` 配置即可回退到本地存储。
177 changes: 177 additions & 0 deletions deploy/docker-compose/002-mysql-fullstack/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
services:
mysql:
container_name: ${CONTAINER_NAME_PREFIX}-flexmodel-mysql
image: mysql:8.0
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
- ./mysql/my.cnf:/etc/my.cnf
restart: always
environment:
- MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
- TZ=GMT+08
command: >
bash -c "
chmod 644 /etc/my.cnf
&& /entrypoint.sh mysqld
"
--default-authentication-plugin=mysql_native_password
--character-set-server=utf8mb4
networks:
- flexmodel
healthcheck:
test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
timeout: 20s
retries: 10
rabbitmq:
container_name: ${CONTAINER_NAME_PREFIX}-flexmodel-rabbitmq
image: rabbitmq:3.13-management
volumes:
- ./rabbitmq/data:/var/lib/rabbitmq
restart: always
environment:
- RABBITMQ_DEFAULT_USER=${RABBITMQ_DEFAULT_USER}
- RABBITMQ_DEFAULT_PASS=${RABBITMQ_DEFAULT_PASS}
- TZ=GMT+08
ports:
- ${RABBITMQ_AMQP_PORT:-5672}:5672
- ${RABBITMQ_MANAGEMENT_PORT:-15672}:15672
networks:
- flexmodel
healthcheck:
test: [ "CMD", "rabbitmq-diagnostics", "-q", "ping" ]
timeout: 20s
retries: 10
rustfs:
container_name: ${CONTAINER_NAME_PREFIX}-flexmodel-rustfs
image: rustfs/rustfs:latest
restart: always
volumes:
- ./rustfs/data:/data
environment:
- TZ=GMT+08
- RUSTFS_VOLUMES=/data
- RUSTFS_ADDRESS=0.0.0.0:9000
- RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
- RUSTFS_CONSOLE_ENABLE=true
- RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS=*
- RUSTFS_ACCESS_KEY=${RUSTFS_ACCESS_KEY}
- RUSTFS_SECRET_KEY=${RUSTFS_SECRET_KEY}
- RUSTFS_OBS_LOGGER_LEVEL=info
# single-disk single-node mode; bypass strict disk topology check
- RUSTFS_UNSAFE_BYPASS_DISK_CHECK=true
ports:
- ${RUSTFS_S3_API_PORT:-9000}:9000
- ${RUSTFS_CONSOLE_PORT:-9001}:9001
networks:
- flexmodel
healthcheck:
test: [ "CMD", "sh", "-ec", "curl -fsS http://127.0.0.1:9000/health" ]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s
flexmodel-ui:
container_name: ${CONTAINER_NAME_PREFIX}-flexmodel-ui
image: cjbi/flexmodel-ui:latest
restart: always
environment:
- TZ=GMT+08
depends_on:
flexmodel-server:
condition: service_started
networks:
- flexmodel
nginx:
container_name: ${CONTAINER_NAME_PREFIX}-flexmodel-nginx
image: nginx:1.25.3
volumes:
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/conf.d/default.conf.template:/etc/nginx/conf.d/default.conf.template
- ./flexmodel/pages:/data/pages
restart: always
ports:
- ${NGINX_HTTP_PORT:-80}:80
- ${NGINX_HTTPS_PORT:-443}:443
environment:
- TZ=GMT+08
- FLEXMODEL_PROJECT_BASE_DOMAIN=${FLEXMODEL_PROJECT_BASE_DOMAIN:-localhost}
command: >
/bin/sh -c "export FLEXMODEL_PROJECT_BASE_DOMAIN_ESCAPED=$$(echo $$FLEXMODEL_PROJECT_BASE_DOMAIN | sed 's/\\./\\\\./g') && envsubst '$$FLEXMODEL_PROJECT_BASE_DOMAIN $$FLEXMODEL_PROJECT_BASE_DOMAIN_ESCAPED' < /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;'"
depends_on:
flexmodel-server:
condition: service_started
networks:
- flexmodel
flexmodel-server:
container_name: ${CONTAINER_NAME_PREFIX}-flexmodel-server
image: ${FLEXMODEL_SERVER_IMAGE:-cjbi/flexmodel-server-native:latest}
restart: always
volumes:
- ./flexmodel/storage:/deployments/storage
- ./flexmodel/database:/deployments/database
- ./flexmodel/logs:/deployments/logs
- ./flexmodel/pages:/deployments/pages
env_file: .env
environment:
- TZ=GMT+08
- FLEXMODEL_DATASOURCE_DB_KIND=mysql
# readTimeout: MySQL 容器重启后池中残留连接会读到已死对端,无超时会无限阻塞(曾导致事件循环冻结)
- FLEXMODEL_DATASOURCE_USERNAME=root
- FLEXMODEL_DATASOURCE_PASSWORD=${MYSQL_ROOT_PASSWORD}
- FLEXMODEL_PROJECT_URL_TEMPLATE=jdbc:mysql://mysql:3306/{{databaseName}}?connectTimeout=5000&readTimeout=15000
- QUARKUS_REST_CLIENT_FUNCTION_RUNTIME_URL=http://flexmodel-functions-runtime:9999
- QUARKUS_HTTP_LIMITS_MAX_BODY_SIZE=100M
- FLEXMODEL_PAGES_ROOT=/data/pages
- FLEXMODEL_PAGES_URL_TEMPLATE=${FLEXMODEL_PAGES_URL_TEMPLATE:-https://{{projectId}}.example.com}
- FLEXMODEL_EDGE_URL_TEMPLATE=${FLEXMODEL_EDGE_URL_TEMPLATE:-https://{{projectId}}.example.com/functions/{{name}}}
# RabbitMQ
- QUARKUS_RABBITMQ_HOST=rabbitmq
- QUARKUS_RABBITMQ_PORT=5672
- QUARKUS_RABBITMQ_USERNAME=${RABBITMQ_DEFAULT_USER}
- QUARKUS_RABBITMQ_PASSWORD=${RABBITMQ_DEFAULT_PASS}
- QUARKUS_RABBITMQ_VIRTUAL_HOST=${RABBITMQ_VIRTUAL_HOST:-/}
- FLEXMODEL_EVENTS_RABBITMQ_ENABLED=${FLEXMODEL_RABBITMQ_ENABLED:-true}

# RustFS (S3-compatible object storage)
- FLEXMODEL_STORAGE_TYPE=s3
- FLEXMODEL_STORAGE_S3_BUCKET=${RUSTFS_BUCKET}
- FLEXMODEL_STORAGE_S3_ENDPOINT=http://rustfs:9000
- FLEXMODEL_STORAGE_S3_REGION=us-east-1
- FLEXMODEL_STORAGE_S3_PATH_STYLE=true
- QUARKUS_S3_AWS_REGION=us-east-1
- QUARKUS_S3_AWS_CREDENTIALS_TYPE=static
- QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_ACCESS_KEY_ID=${RUSTFS_ACCESS_KEY}
- QUARKUS_S3_AWS_CREDENTIALS_STATIC_PROVIDER_SECRET_ACCESS_KEY=${RUSTFS_SECRET_KEY}
- QUARKUS_S3_ENDPOINT_OVERRIDE=http://rustfs:9000
- QUARKUS_S3_PATH_STYLE_ACCESS=true

networks:
- flexmodel
depends_on:
mysql:
condition: service_healthy
rabbitmq:
condition: service_healthy
rustfs:
condition: service_healthy

flexmodel-functions-runtime:
container_name: ${CONTAINER_NAME_PREFIX}-flexmodel-functions-runtime
image: cjbi/flexmodel-functions-runtime:latest
restart: always
env_file: .env
environment:
- FLEXMODEL_JAVA_HOST=flexmodel-server
- FLEXMODEL_JAVA_PORT=8080
- FLEXMODEL_PORT=9999
- FLEXMODEL_HOST=0.0.0.0
networks:
- flexmodel
depends_on:
- flexmodel-server
networks:
flexmodel:
name: ${CONTAINER_NAME_PREFIX}_flexmodel_default
driver: bridge
Empty file.
7 changes: 7 additions & 0 deletions deploy/docker-compose/002-mysql-fullstack/mysql/my.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server=utf8mb4
init_connect='SET NAMES utf8mb4'
Loading