mirror of
https://gitee.com/ulthon/ulthon_admin.git
synced 2026-08-30 12:45:32 +08:00
feat(stack): 新增 stack 模式管理功能
- 新增 `php think admin:stack:mode` 命令,支持 list/use/current/rollback 操作 - 新增 StackModeService 服务,负责模式切换、备份与回滚逻辑 - 在 source/stack/ 目录下添加 default、full、base-build 三种模式的配置文件 - 更新 UlthonAdminService 以注册新的命令行工具
This commit is contained in:
140
source/stack/default/.gitea/workflows/build-and-deploy.yml
Normal file
140
source/stack/default/.gitea/workflows/build-and-deploy.yml
Normal file
@@ -0,0 +1,140 @@
|
||||
name: build-and-deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
REMOTE_APP_DIR: /data/projects/ulthon_admin/docker
|
||||
PACKAGE_NAME: ulthon_admin_release.tar.gz
|
||||
COMPOSE_PROJECT_NAME: ulthon_admin
|
||||
DB_HOSTNAME: host.docker.internal
|
||||
|
||||
jobs:
|
||||
deploy_host15:
|
||||
name: 直传代码并部署到 Host15
|
||||
runs-on: main
|
||||
container:
|
||||
image: catthehacker/ubuntu:act-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 1
|
||||
|
||||
- name: 生成 .env
|
||||
shell: bash
|
||||
env:
|
||||
MYSQL_PASSWORD: ${{ secrets.MYSQL_PASSWORD }}
|
||||
DB_HOSTNAME: ${{ env.DB_HOSTNAME }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cp .example.env .env
|
||||
|
||||
awk -v host="$DB_HOSTNAME" -v newpwd="$MYSQL_PASSWORD" '
|
||||
BEGIN { has_host = 0; has_pwd = 0 }
|
||||
$0 ~ /^HOSTNAME=/ {
|
||||
print "HOSTNAME=" host
|
||||
has_host = 1
|
||||
next
|
||||
}
|
||||
$0 ~ /^PASSWORD=/ {
|
||||
print "PASSWORD=" newpwd
|
||||
has_pwd = 1
|
||||
next
|
||||
}
|
||||
{ print }
|
||||
END {
|
||||
if (!has_host) print "HOSTNAME=" host
|
||||
if (!has_pwd) print "PASSWORD=" newpwd
|
||||
}' .env > .env.tmp
|
||||
|
||||
mv .env.tmp .env
|
||||
|
||||
- name: 打包发布文件
|
||||
shell: bash
|
||||
env:
|
||||
PACKAGE_NAME: ${{ env.PACKAGE_NAME }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TMP_PACKAGE="/tmp/${PACKAGE_NAME}"
|
||||
rm -f "$TMP_PACKAGE" "$PACKAGE_NAME"
|
||||
|
||||
tar -czf "$TMP_PACKAGE" \
|
||||
--exclude="$PACKAGE_NAME" \
|
||||
--exclude-vcs \
|
||||
--exclude="./runtime/*" \
|
||||
--exclude="./.trae/*" \
|
||||
--exclude="./source/clients/uniapp/node_modules/*" \
|
||||
.
|
||||
cp -f "$TMP_PACKAGE" "$PACKAGE_NAME"
|
||||
|
||||
- name: 创建远端目录
|
||||
uses: appleboy/ssh-action@v0.1.10
|
||||
env:
|
||||
REMOTE_APP_DIR: ${{ env.REMOTE_APP_DIR }}
|
||||
with:
|
||||
host: ${{ secrets.UL_HOST15_IP }}
|
||||
username: ${{ secrets.UL_HOST15_USER }}
|
||||
password: ${{ secrets.UL_HOST15_PASSWORD }}
|
||||
port: ${{ secrets.UL_HOST15_PORT }}
|
||||
envs: REMOTE_APP_DIR
|
||||
script: |
|
||||
set -euo pipefail
|
||||
mkdir -p "${REMOTE_APP_DIR}/incoming"
|
||||
mkdir -p "${REMOTE_APP_DIR}/releases"
|
||||
|
||||
- name: 上传发布包与 compose
|
||||
uses: appleboy/scp-action@v0.1.7
|
||||
env:
|
||||
REMOTE_APP_DIR: ${{ env.REMOTE_APP_DIR }}
|
||||
PACKAGE_NAME: ${{ env.PACKAGE_NAME }}
|
||||
with:
|
||||
host: ${{ secrets.UL_HOST15_IP }}
|
||||
username: ${{ secrets.UL_HOST15_USER }}
|
||||
password: ${{ secrets.UL_HOST15_PASSWORD }}
|
||||
port: ${{ secrets.UL_HOST15_PORT }}
|
||||
source: "${{ env.PACKAGE_NAME }},docker-compose.yaml"
|
||||
target: "${{ env.REMOTE_APP_DIR }}/incoming"
|
||||
overwrite: true
|
||||
|
||||
- name: 远端解压并启动
|
||||
uses: appleboy/ssh-action@v0.1.10
|
||||
env:
|
||||
REMOTE_APP_DIR: ${{ env.REMOTE_APP_DIR }}
|
||||
PACKAGE_NAME: ${{ env.PACKAGE_NAME }}
|
||||
COMPOSE_PROJECT_NAME: ${{ env.COMPOSE_PROJECT_NAME }}
|
||||
GITHUB_RUN_ID: ${{ github.run_id }}
|
||||
with:
|
||||
host: ${{ secrets.UL_HOST15_IP }}
|
||||
username: ${{ secrets.UL_HOST15_USER }}
|
||||
password: ${{ secrets.UL_HOST15_PASSWORD }}
|
||||
port: ${{ secrets.UL_HOST15_PORT }}
|
||||
timeout: 120s
|
||||
command_timeout: 60m
|
||||
envs: REMOTE_APP_DIR,PACKAGE_NAME,COMPOSE_PROJECT_NAME,GITHUB_RUN_ID
|
||||
script: |
|
||||
set -euo pipefail
|
||||
|
||||
RELEASE_DIR="${REMOTE_APP_DIR}/releases/${GITHUB_RUN_ID}"
|
||||
PACKAGE_PATH="${REMOTE_APP_DIR}/incoming/${PACKAGE_NAME}"
|
||||
COMPOSE_PATH="${REMOTE_APP_DIR}/incoming/docker-compose.yaml"
|
||||
|
||||
rm -rf "${RELEASE_DIR}"
|
||||
mkdir -p "${RELEASE_DIR}"
|
||||
|
||||
tar -xzf "${PACKAGE_PATH}" -C "${RELEASE_DIR}"
|
||||
|
||||
if [ -f "${COMPOSE_PATH}" ]; then
|
||||
cp -f "${COMPOSE_PATH}" "${RELEASE_DIR}/docker-compose.yaml"
|
||||
fi
|
||||
|
||||
cd "${RELEASE_DIR}"
|
||||
export COMPOSE_PROJECT_NAME
|
||||
|
||||
docker compose down || true
|
||||
docker compose up -d --build --remove-orphans
|
||||
|
||||
ln -sfn "${RELEASE_DIR}" "${REMOTE_APP_DIR}/current"
|
||||
|
||||
ls -1dt "${REMOTE_APP_DIR}/releases"/* 2>/dev/null | tail -n +6 | xargs -r rm -rf
|
||||
81
source/stack/default/Dockerfile
Normal file
81
source/stack/default/Dockerfile
Normal file
@@ -0,0 +1,81 @@
|
||||
FROM php:8.2-fpm-bookworm
|
||||
|
||||
RUN rm -rf /etc/apt/sources.list.d/* \
|
||||
&& echo "deb http://mirrors.ustc.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list \
|
||||
&& echo "deb http://mirrors.ustc.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list \
|
||||
&& echo "deb http://mirrors.ustc.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
||||
|
||||
RUN apt-get update
|
||||
|
||||
# 安装nginx
|
||||
RUN apt-get install -y nginx
|
||||
|
||||
ADD --chmod=0755 https://nexus.hl7.top:1243/repository/github-raw-proxy/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
|
||||
|
||||
# 配置代理
|
||||
RUN sed -i 's|aomedia.googlesource.com|nexus.hl7.top:1243/repository/raw-aomedia.googlesource.com|g' /usr/local/bin/install-php-extensions
|
||||
RUN sed -i 's|chromium.googlesource.com|nexus.hl7.top:1243/repository/raw-chromium.googlesource.com|g' /usr/local/bin/install-php-extensions
|
||||
RUN sed -i 's|https://github.com|https://nexus.hl7.top:1243/repository/github-raw-proxy|g' /usr/local/bin/install-php-extensions
|
||||
|
||||
RUN install-php-extensions pdo_mysql
|
||||
RUN install-php-extensions gd
|
||||
RUN install-php-extensions fileinfo
|
||||
RUN install-php-extensions opcache
|
||||
RUN install-php-extensions redis
|
||||
RUN install-php-extensions event
|
||||
RUN install-php-extensions imagick
|
||||
RUN install-php-extensions zip
|
||||
RUN install-php-extensions pcntl
|
||||
|
||||
# 清理默认 Nginx 配置
|
||||
RUN rm /etc/nginx/sites-available/default /etc/nginx/sites-enabled/default
|
||||
|
||||
|
||||
# 安装其他需要的依赖
|
||||
# RUN apt-get install -y ffmpeg
|
||||
# RUN apt-get install -y libreoffice
|
||||
# RUN apt-get install -y redis-server
|
||||
# RUN apt-get install -y git
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# 安装 Composer
|
||||
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
|
||||
RUN chmod +x /usr/local/bin/composer
|
||||
RUN composer config -g repos.packagist composer https://nexus.hl7.top:1243/repository/composer-proxy/
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /var/www/html
|
||||
|
||||
# 预先拷贝 composer 文件并安装依赖,利用 Docker 缓存
|
||||
COPY composer.json composer.lock /var/www/html/
|
||||
RUN composer install --no-dev --no-interaction --no-scripts --no-autoloader
|
||||
|
||||
# 将当前目录下的文件拷贝到工作目录
|
||||
COPY . /var/www/html
|
||||
|
||||
# 生成自动加载文件
|
||||
RUN composer dump-autoload --optimize --no-dev --classmap-authoritative
|
||||
|
||||
# 内部安装compsoer并安装依赖,如果不需要可以注释掉
|
||||
# RUN install-php-extensions @composer
|
||||
|
||||
VOLUME /var/www/html/runtime
|
||||
VOLUME /var/www/html/public/storage
|
||||
VOLUME /var/www/html/public/build
|
||||
VOLUME /var/www/html/storage
|
||||
|
||||
# 挂载主目录,也可以选择直接挂载主目录,可以把上面的几个指定的目录删掉
|
||||
# VOLUME ["/var/www/html"]
|
||||
|
||||
# 暴露 Nginx 端口
|
||||
EXPOSE 80
|
||||
|
||||
RUN chmod +x /var/www/html/docker/run.sh
|
||||
|
||||
# 启动 Nginx PHP 然后阻塞
|
||||
ENTRYPOINT ["/var/www/html/docker/run.sh"]
|
||||
|
||||
CMD ["server"]
|
||||
|
||||
20
source/stack/default/docker-compose.yaml
Normal file
20
source/stack/default/docker-compose.yaml
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
name: ulthon_admin
|
||||
|
||||
|
||||
services:
|
||||
ulthon_admin:
|
||||
# 正式环境中,您应当构建一个完整镜像,使用镜像名称或id运行,不要使用dockerfile
|
||||
# image: ulthon/ulthon_admin:v1
|
||||
build:
|
||||
context: . # Dockerfile 所在的目录
|
||||
dockerfile: Dockerfile # Dockerfile 的名称
|
||||
restart: always
|
||||
ports:
|
||||
- "88:80" # HTTP
|
||||
volumes:
|
||||
- ./:/var/www/html # 直接分发代码可以去掉注释并将下面的目录增加注释
|
||||
# - ./runtime:/var/www/html/runtime
|
||||
# - ./public/storage:/var/www/html/public/storage
|
||||
# - ./public/build:/var/www/html/public/build
|
||||
# - ./storage:/var/www/html/storage
|
||||
Reference in New Issue
Block a user