mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-15 05:12:49 +00:00
no message
This commit is contained in:
parent
66ea277a59
commit
a5faa378b0
@ -9,6 +9,24 @@ use Symfony\Component\Yaml\Exception\ParseException;
|
|||||||
|
|
||||||
class Apps
|
class Apps
|
||||||
{
|
{
|
||||||
|
// 受保护的服务名称列表
|
||||||
|
protected static array $protectedServiceNames = [
|
||||||
|
'php',
|
||||||
|
'nginx',
|
||||||
|
'redis',
|
||||||
|
'mariadb',
|
||||||
|
'office',
|
||||||
|
'fileview',
|
||||||
|
'drawio-webapp',
|
||||||
|
'drawio-expont',
|
||||||
|
'minder',
|
||||||
|
'approve',
|
||||||
|
'ai',
|
||||||
|
'okr',
|
||||||
|
'face',
|
||||||
|
'search',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行docker-compose up命令
|
* 执行docker-compose up命令
|
||||||
* @param string $appName
|
* @param string $appName
|
||||||
@ -18,6 +36,8 @@ class Apps
|
|||||||
*/
|
*/
|
||||||
public static function dockerComposeUp(string $appName, string $version = 'latest', string $command = 'up'): array
|
public static function dockerComposeUp(string $appName, string $version = 'latest', string $command = 'up'): array
|
||||||
{
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
// 获取版本信息
|
// 获取版本信息
|
||||||
$versions = self::getAvailableVersions($appName);
|
$versions = self::getAvailableVersions($appName);
|
||||||
if (empty($versions)) {
|
if (empty($versions)) {
|
||||||
@ -37,32 +57,41 @@ class Apps
|
|||||||
file_put_contents($versionInfo['base_dir'] . '/latest', $versionInfo['version']);
|
file_put_contents($versionInfo['base_dir'] . '/latest', $versionInfo['version']);
|
||||||
|
|
||||||
// 生成docker-compose.yml文件
|
// 生成docker-compose.yml文件
|
||||||
$result = self::generateDockerComposeYml($versionInfo['compose_file'], [
|
$res = self::generateDockerComposeYml($versionInfo['compose_file'], [
|
||||||
'PROXY_PORT' => '33062', // todo 参数自定义
|
'PROXY_PORT' => '33062', // todo 参数自定义
|
||||||
]);
|
]);
|
||||||
if (!$result) {
|
if (Base::isError($res)) {
|
||||||
return Base::retError('生成docker-compose.yml失败');
|
return $res;
|
||||||
}
|
}
|
||||||
|
$result['generate'] = $res['data'];
|
||||||
|
|
||||||
// 执行docker-compose命令
|
// 执行docker-compose命令
|
||||||
$url = "http://host.docker.internal:" . env("APPS_PORT") . "/apps/{$command}/{$appName}";
|
$res = self::curl("apps/{$command}/{$appName}");
|
||||||
$extra = [
|
|
||||||
'Content-Type' => 'application/json',
|
|
||||||
'Authorization' => 'Bearer ' . env('APP_KEY'),
|
|
||||||
];
|
|
||||||
$res = Ihttp::ihttp_request($url, [], $extra);
|
|
||||||
if (Base::isError($res)) {
|
if (Base::isError($res)) {
|
||||||
return Base::retError("请求错误", $res);
|
return $res;
|
||||||
}
|
}
|
||||||
|
$result['compose'] = $res['data'];
|
||||||
|
|
||||||
// 解析响应
|
// nginx配置文件处理
|
||||||
$resData = Base::json2array($res['data']);
|
$nginxFile = $versionInfo['path'] . '/nginx.conf';
|
||||||
if ($resData['code'] != 200) {
|
$nginxTarget = base_path('docker/nginx/apps/' . $appName . '.conf');
|
||||||
return Base::retError("请求失败", $resData);
|
if (file_exists($nginxTarget)) {
|
||||||
|
unlink($nginxTarget);
|
||||||
|
}
|
||||||
|
if (file_exists($nginxFile)) {
|
||||||
|
if ($command === 'up') {
|
||||||
|
copy($nginxFile, $nginxTarget);
|
||||||
|
}
|
||||||
|
// 重启nginx
|
||||||
|
$res = self::curl("nginx/reload");
|
||||||
|
if (Base::isError($res)) {
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
$result['nginx'] = $res['data'];
|
||||||
}
|
}
|
||||||
|
|
||||||
// 返回结果
|
// 返回结果
|
||||||
return Base::retSuccess("success", $resData['data']);
|
return Base::retSuccess("success", $result);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,18 +107,17 @@ class Apps
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成docker-compose.yml文件配置
|
* 生成docker-compose.yml文件配置
|
||||||
*
|
|
||||||
* @param string $filePath docker-compose.yml文件路径
|
* @param string $filePath docker-compose.yml文件路径
|
||||||
* @param array $params 可选参数,替换docker-compose.yml中的${XXX}变量
|
* @param array $params 可选参数,替换docker-compose.yml中的${XXX}变量
|
||||||
* @return bool 是否生成成功
|
* @return array
|
||||||
*/
|
*/
|
||||||
private static function generateDockerComposeYml(string $filePath, array $params = []): bool
|
private static function generateDockerComposeYml(string $filePath, array $params = []): array
|
||||||
{
|
{
|
||||||
// 应用名称
|
// 应用名称
|
||||||
$appName = basename(dirname($filePath, 2));
|
$appName = basename(dirname($filePath, 2));
|
||||||
|
|
||||||
// 服务名称
|
// 服务名称
|
||||||
$serviceName = 'dootask-app-' . strtolower(preg_replace('/(?<!^)([A-Z])/', '-$1', $appName));
|
$serviceName = 'dootask-app-' . $appName;
|
||||||
|
|
||||||
// 网络名称
|
// 网络名称
|
||||||
$networkName = 'dootask-networks-' . env('APP_ID');
|
$networkName = 'dootask-networks-' . env('APP_ID');
|
||||||
@ -106,7 +134,7 @@ class Apps
|
|||||||
|
|
||||||
// 确保services部分存在
|
// 确保services部分存在
|
||||||
if (!isset($content['services'])) {
|
if (!isset($content['services'])) {
|
||||||
return false;
|
return Base::retError('Docker compose文件缺少services配置');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置服务名称
|
// 设置服务名称
|
||||||
@ -118,6 +146,13 @@ class Apps
|
|||||||
// 添加网络配置
|
// 添加网络配置
|
||||||
$content['networks'][$networkName] = ['external' => true];
|
$content['networks'][$networkName] = ['external' => true];
|
||||||
|
|
||||||
|
// 检查服务名称是否被保护
|
||||||
|
foreach ($content['services'] as $name => $service) {
|
||||||
|
if (in_array($name, self::$protectedServiceNames)) {
|
||||||
|
return Base::retError('服务名称 "' . $name . '" 被保护,不能使用');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($content['services'] as &$service) {
|
foreach ($content['services'] as &$service) {
|
||||||
// 确保所有服务都有网络配置
|
// 确保所有服务都有网络配置
|
||||||
$service['networks'] = [$networkName];
|
$service['networks'] = [$networkName];
|
||||||
@ -137,15 +172,17 @@ class Apps
|
|||||||
}, $yamlContent);
|
}, $yamlContent);
|
||||||
|
|
||||||
// 保存文件
|
// 保存文件
|
||||||
file_put_contents($savePath, $yamlContent);
|
if (file_put_contents($savePath, $yamlContent) === false) {
|
||||||
|
return Base::retError('无法写入配置文件');
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
// 返回成功
|
||||||
} catch (ParseException) {
|
return Base::retSuccess('success', [
|
||||||
|
'file' => $savePath,
|
||||||
|
]);
|
||||||
|
} catch (ParseException $e) {
|
||||||
// YAML解析错误
|
// YAML解析错误
|
||||||
return false;
|
return Base::retError('YAML parsing error:' . $e->getMessage());
|
||||||
} catch (\Exception) {
|
|
||||||
// 其他错误
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,4 +265,33 @@ class Apps
|
|||||||
|
|
||||||
return $versions;
|
return $versions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行curl请求
|
||||||
|
* @param $path
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private static function curl($path): array
|
||||||
|
{
|
||||||
|
$url = "http://host.docker.internal:" . env("APPS_PORT") . "/{$path}";
|
||||||
|
$extra = [
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'Authorization' => 'Bearer ' . env('APP_KEY'),
|
||||||
|
];
|
||||||
|
|
||||||
|
// 执行请求
|
||||||
|
$res = Ihttp::ihttp_request($url, [], $extra);
|
||||||
|
if (Base::isError($res)) {
|
||||||
|
return Base::retError("请求错误", $res);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析响应
|
||||||
|
$resData = Base::json2array($res['data']);
|
||||||
|
if ($resData['code'] != 200) {
|
||||||
|
return Base::retError("请求失败", $resData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回结果
|
||||||
|
return Base::retSuccess("success", $resData['data']);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
2
docker/nginx/apps/.gitignore
vendored
Normal file
2
docker/nginx/apps/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
@ -79,6 +79,7 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
include /etc/nginx/conf.d/location/*.conf;
|
include /etc/nginx/conf.d/location/*.conf;
|
||||||
|
include /etc/nginx/conf.d/apps/*.conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
include /etc/nginx/conf.d/conf.d/*.conf;
|
include /etc/nginx/conf.d/conf.d/*.conf;
|
||||||
|
|||||||
@ -848,3 +848,11 @@ AI机器人不存在
|
|||||||
「(*)」移动至「(*)」
|
「(*)」移动至「(*)」
|
||||||
设备不存在或已被删除
|
设备不存在或已被删除
|
||||||
删除附件:(*)
|
删除附件:(*)
|
||||||
|
|
||||||
|
Docker compose文件缺少services配置
|
||||||
|
服务名称 "(*)" 被保护,不能使用
|
||||||
|
无法写入配置文件
|
||||||
|
请求错误
|
||||||
|
请求失败
|
||||||
|
没有可用的版本
|
||||||
|
没有找到版本(*)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user