mirror of
https://github.com/whyour/qinglong.git
synced 2025-11-22 16:38:33 +08:00
Add non-root Docker user support with automatic command setup (#2830)
* Initial plan * Add non-root user guide and improve error messages Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add PM2_HOME configuration to fix non-root user permission errors Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Fix PM2 socket error by using /tmp for PM2_HOME instead of mounted volume Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Document symlink permission limitation for non-root users Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Clarify that scheduled tasks auto-adapt to use full paths when symlinks unavailable Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add error handling for symlink creation to prevent worker crashes Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Add practical solutions for non-root users to use ql and task commands Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * Modify linkCommand to create symlinks in ~/bin for non-root users Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> * 修复链接 task 命令 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: whyour <22700758+whyour@users.noreply.github.com> Co-authored-by: whyour <imwhyour@gmail.com>
This commit is contained in:
parent
e41eed81ae
commit
8f23c61fee
|
|
@ -41,6 +41,8 @@ Timed task management platform supporting Python3, JavaScript, Shell, Typescript
|
|||
|
||||
The `latest` image is built on `alpine` and the `debian` image is built on `debian-slim`. If you need to use a dependency that is not supported by `alpine`, it is recommended that you use the `debian` image.
|
||||
|
||||
**⚠️ Important**: If you need to run Docker as a **non-root user**, please use the `debian` image. Alpine's `crond` requires root privileges.
|
||||
|
||||
```bash
|
||||
docker pull whyour/qinglong:latest
|
||||
docker pull whyour/qinglong:debian
|
||||
|
|
|
|||
|
|
@ -43,6 +43,8 @@ Timed task management platform supporting Python3, JavaScript, Shell, Typescript
|
|||
|
||||
`latest` 镜像是基于 `alpine` 构建,`debian` 镜像是基于 `debian-slim` 构建。如果需要使用 `alpine` 不支持的依赖,建议使用 `debian` 镜像
|
||||
|
||||
**⚠️ 重要提示**: 如果您需要以**非 root 用户**运行 Docker,请使用 `debian` 镜像。Alpine 的 `crond` 需要 root 权限。
|
||||
|
||||
```bash
|
||||
docker pull whyour/qinglong:latest
|
||||
docker pull whyour/qinglong:debian
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
import path from 'path';
|
||||
import fs from 'fs/promises';
|
||||
import os from 'os';
|
||||
import chokidar from 'chokidar';
|
||||
import config from '../config/index';
|
||||
import { fileExist, promiseExec, rmPath } from '../config/util';
|
||||
import { promiseExec } from '../config/util';
|
||||
|
||||
async function linkToNodeModule(src: string, dst?: string) {
|
||||
const target = path.join(config.rootPath, 'node_modules', dst || src);
|
||||
|
|
@ -17,8 +18,21 @@ async function linkToNodeModule(src: string, dst?: string) {
|
|||
}
|
||||
|
||||
async function linkCommand() {
|
||||
const commandPath = await promiseExec('which node');
|
||||
const commandDir = path.dirname(commandPath);
|
||||
const homeDir = os.homedir();
|
||||
const userBinDir = path.join(homeDir, 'bin');
|
||||
|
||||
try {
|
||||
await fs.mkdir(userBinDir, { recursive: true });
|
||||
} catch (error) {
|
||||
const commandPath = await promiseExec('which node');
|
||||
const commandDir = path.dirname(commandPath);
|
||||
return await linkCommandToDir(commandDir);
|
||||
}
|
||||
|
||||
await linkCommandToDir(userBinDir);
|
||||
}
|
||||
|
||||
async function linkCommandToDir(commandDir: string) {
|
||||
const linkShell = [
|
||||
{
|
||||
src: 'update.sh',
|
||||
|
|
@ -42,6 +56,7 @@ async function linkCommand() {
|
|||
await fs.unlink(tmpTarget);
|
||||
}
|
||||
} catch (error) { }
|
||||
|
||||
await fs.symlink(source, tmpTarget);
|
||||
await fs.rename(tmpTarget, target);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -669,12 +669,23 @@ export default class CronService {
|
|||
|
||||
await writeFileWithLock(config.crontabFile, crontab_string);
|
||||
|
||||
execSync(`crontab ${config.crontabFile}`);
|
||||
try {
|
||||
execSync(`crontab ${config.crontabFile}`);
|
||||
} catch (error: any) {
|
||||
const errorMsg = error.message || String(error);
|
||||
this.logger.error('[crontab] Failed to update system crontab:', errorMsg);
|
||||
}
|
||||
|
||||
await CrontabModel.update({ saved: true }, { where: {} });
|
||||
}
|
||||
|
||||
public importCrontab() {
|
||||
exec('crontab -l', (error, stdout, stderr) => {
|
||||
exec('crontab -l', (error, stdout) => {
|
||||
if (error) {
|
||||
const errorMsg = error.message || String(error);
|
||||
this.logger.error('[crontab] Failed to read system crontab:', errorMsg);
|
||||
}
|
||||
|
||||
const lines = stdout.split('\n');
|
||||
const namePrefix = new Date().getTime();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
#!/bin/bash
|
||||
|
||||
# Add ~/bin to PATH for non-root users
|
||||
export PATH="$HOME/bin:$PATH"
|
||||
|
||||
dir_shell=/ql/shell
|
||||
. $dir_shell/share.sh
|
||||
|
||||
|
|
|
|||
|
|
@ -59,15 +59,10 @@ list_own_user=$dir_list_tmp/own_user.list
|
|||
list_own_add=$dir_list_tmp/own_add.list
|
||||
list_own_drop=$dir_list_tmp/own_drop.list
|
||||
|
||||
## 软连接及其原始文件对应关系
|
||||
link_name=(
|
||||
task
|
||||
ql
|
||||
)
|
||||
original_name=(
|
||||
task.sh
|
||||
update.sh
|
||||
)
|
||||
|
||||
init_env() {
|
||||
local pnpm_global_path=$(pnpm root -g 2>/dev/null)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user