修复非 root debian dockerfile

This commit is contained in:
whyour 2026-05-30 23:55:57 +08:00
parent 84d730d510
commit abad29cbf9
15 changed files with 97 additions and 1046 deletions

View File

@ -11,6 +11,9 @@ on:
- "v*" - "v*"
workflow_dispatch: workflow_dispatch:
permissions:
contents: read
jobs: jobs:
code_gitlab: code_gitlab:
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -340,7 +343,7 @@ jobs:
network: host network: host
platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/386 platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64,linux/ppc64le,linux/386
context: . context: .
file: ./docker/310.Dockerfile file: ./docker/Dockerfile.310
push: true push: true
tags: | tags: |
whyour/qinglong:python3.10 whyour/qinglong:python3.10
@ -403,7 +406,7 @@ jobs:
network: host network: host
platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x platforms: linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le,linux/s390x
context: . context: .
file: ./docker/310.Dockerfile.debian file: ./docker/Dockerfile.debian310
push: true push: true
tags: | tags: |
whyour/qinglong:debian-python3.10 whyour/qinglong:debian-python3.10

View File

@ -48,6 +48,17 @@ docker pull whyour/qinglong:latest
docker pull whyour/qinglong:debian docker pull whyour/qinglong:debian
``` ```
When running the `debian` image as a non-root user, specify `--user qinglong`:
```bash
docker run -d \
-v /path/to/ql/data:/ql/data \
-p 5700:5700 \
--user qinglong \
--name qinglong \
whyour/qinglong:debian
```
### npm ### npm
The npm version supports `debian/ubuntu/alpine` systems and requires `node/npm/python3/pip3/pnpm` to be installed. The npm version supports `debian/ubuntu/alpine` systems and requires `node/npm/python3/pip3/pnpm` to be installed.

View File

@ -50,6 +50,17 @@ docker pull whyour/qinglong:latest
docker pull whyour/qinglong:debian docker pull whyour/qinglong:debian
``` ```
使用 `debian` 镜像以非 root 用户运行时,需指定 `--user qinglong`
```bash
docker run -d \
-v /path/to/ql/data:/ql/data \
-p 5700:5700 \
--user qinglong \
--name qinglong \
whyour/qinglong:debian
```
### npm ### npm
npm 版本支持 `debian/ubuntu/alpine` 系统,需要自行安装 `node/npm/python3/pip3/pnpm` npm 版本支持 `debian/ubuntu/alpine` 系统,需要自行安装 `node/npm/python3/pip3/pnpm`

View File

@ -60,17 +60,17 @@ export const LINUX_DEPENDENCE_COMMAND: Record<
} }
> = { > = {
Debian: { Debian: {
install: 'apt-get install -y', install: 'sudo apt-get install -y',
uninstall: 'apt-get remove -y', uninstall: 'sudo apt-get remove -y',
info: 'dpkg-query -s', info: 'sudo dpkg-query -s',
check(info: string) { check(info: string) {
return info.includes('install ok installed'); return info.includes('install ok installed');
}, },
}, },
Ubuntu: { Ubuntu: {
install: 'apt-get install -y', install: 'sudo apt-get install -y',
uninstall: 'apt-get remove -y', uninstall: 'sudo apt-get remove -y',
info: 'dpkg-query -s', info: 'sudo dpkg-query -s',
check(info: string) { check(info: string) {
return info.includes('install ok installed'); return info.includes('install ok installed');
}, },

View File

@ -581,7 +581,7 @@ except:
''')"`, ''')"`,
[DependenceTypes.linux]: getOsTypeSync() === 'Alpine' [DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
? `apk info -es ${name}` ? `apk info -es ${name}`
: `dpkg-query -s ${name}`, : `sudo dpkg-query -s ${name}`,
}; };
return baseCommands[type]; return baseCommands[type];
@ -594,7 +594,7 @@ export function getInstallCommand(type: DependenceTypes, name: string): string {
'pip3 install --disable-pip-version-check --root-user-action=ignore', 'pip3 install --disable-pip-version-check --root-user-action=ignore',
[DependenceTypes.linux]: getOsTypeSync() === 'Alpine' [DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
? 'apk add --no-check-certificate' ? 'apk add --no-check-certificate'
: 'apt-get install -y', : 'sudo apt-get install -y',
}; };
let command = baseCommands[type]; let command = baseCommands[type];
@ -616,7 +616,7 @@ export function getUninstallCommand(
'pip3 uninstall --disable-pip-version-check --root-user-action=ignore -y', 'pip3 uninstall --disable-pip-version-check --root-user-action=ignore -y',
[DependenceTypes.linux]: getOsTypeSync() === 'Alpine' [DependenceTypes.linux]: getOsTypeSync() === 'Alpine'
? 'apk del' ? 'apk del'
: 'apt-get remove -y', : 'sudo apt-get remove -y',
}; };
return `${baseCommands[type]} ${name.trim()}`; return `${baseCommands[type]} ${name.trim()}`;
@ -740,7 +740,7 @@ async function _updateLinuxMirror(
currentDomainWithScheme, currentDomainWithScheme,
mirrorDomainWithScheme || 'http://deb.debian.org', mirrorDomainWithScheme || 'http://deb.debian.org',
); );
return 'apt-get update'; return 'sudo apt-get update';
} else { } else {
throw Error(`Current mirror domain not found.`); throw Error(`Current mirror domain not found.`);
} }
@ -753,7 +753,7 @@ async function _updateLinuxMirror(
currentDomainWithScheme, currentDomainWithScheme,
mirrorDomainWithScheme || 'http://archive.ubuntu.com', mirrorDomainWithScheme || 'http://archive.ubuntu.com',
); );
return 'apt-get update'; return 'sudo apt-get update';
} else { } else {
throw Error(`Current mirror domain not found.`); throw Error(`Current mirror domain not found.`);
} }

View File

@ -81,6 +81,10 @@ RUN pip3 install --prefix ${PYTHON_HOME} requests
COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/ COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/
RUN ln -sf ${QL_DIR}/shell/task.sh /usr/local/bin/task \
&& ln -sf ${QL_DIR}/shell/update.sh /usr/local/bin/ql \
&& chmod +x /usr/local/bin/task /usr/local/bin/ql
WORKDIR ${QL_DIR} WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \ HEALTHCHECK --interval=5s --timeout=2s --retries=20 \

View File

@ -81,6 +81,10 @@ RUN pip3 install --prefix ${PYTHON_HOME} requests
COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/ COPY --from=builder /tmp/build/node_modules/. /ql/node_modules/
RUN ln -sf ${QL_DIR}/shell/task.sh /usr/local/bin/task \
&& ln -sf ${QL_DIR}/shell/update.sh /usr/local/bin/ql \
&& chmod +x /usr/local/bin/task /usr/local/bin/ql
WORKDIR ${QL_DIR} WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \ HEALTHCHECK --interval=5s --timeout=2s --retries=20 \

View File

@ -32,7 +32,9 @@ RUN groupadd -g ${QL_GID} qinglong && \
useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \ useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \
mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \ mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \
chmod 700 /home/qinglong/.ssh && \ chmod 700 /home/qinglong/.ssh && \
chown -R ${QL_UID}:${QL_GID} /home/qinglong chown -R ${QL_UID}:${QL_GID} /home/qinglong && \
mkdir -p /etc/sudoers.d && \
echo 'qinglong ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/qinglong
ENV QL_USER=qinglong ENV QL_USER=qinglong
ENV QL_HOME=/home/$QL_USER ENV QL_HOME=/home/$QL_USER
@ -55,6 +57,7 @@ RUN set -x && \
jq \ jq \
procps \ procps \
netcat-openbsd \ netcat-openbsd \
sudo \
unzip \ unzip \
libatomic1 && \ libatomic1 && \
apt-get clean && \ apt-get clean && \
@ -69,7 +72,7 @@ RUN set -x && \
rm -rf /etc/apt/apt.conf.d/docker-clean && \ rm -rf /etc/apt/apt.conf.d/docker-clean && \
ulimit -c 0 ulimit -c 0
RUN mkdir -p ${QL_DIR} ${QL_DIR}/data && \ RUN mkdir -p ${QL_DIR} && \
chown -R ${QL_UID}:${QL_GID} ${QL_DIR} chown -R ${QL_UID}:${QL_GID} ${QL_DIR}
USER qinglong USER qinglong
@ -87,7 +90,7 @@ RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \ ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \ PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3 \ PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3 \
HOME=/root HOME=/home/qinglong
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin:${HOME}/bin \ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin:${HOME}/bin \
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules \ NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules \
@ -100,6 +103,10 @@ COPY --chown=qinglong:qinglong --from=builder /tmp/build/node_modules/. /ql/node
USER root USER root
RUN ln -sf ${QL_DIR}/shell/task.sh /usr/local/bin/task \
&& ln -sf ${QL_DIR}/shell/update.sh /usr/local/bin/ql \
&& chmod +x /usr/local/bin/task /usr/local/bin/ql
WORKDIR ${QL_DIR} WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \ HEALTHCHECK --interval=5s --timeout=2s --retries=20 \

View File

@ -32,7 +32,9 @@ RUN groupadd -g ${QL_GID} qinglong && \
useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \ useradd -m -u ${QL_UID} -g ${QL_GID} -s /bin/bash qinglong && \
mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \ mkdir -p /home/qinglong/bin /home/qinglong/.ssh && \
chmod 700 /home/qinglong/.ssh && \ chmod 700 /home/qinglong/.ssh && \
chown -R ${QL_UID}:${QL_GID} /home/qinglong chown -R ${QL_UID}:${QL_GID} /home/qinglong && \
mkdir -p /etc/sudoers.d && \
echo 'qinglong ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/qinglong
ENV QL_USER=qinglong ENV QL_USER=qinglong
ENV QL_HOME=/home/$QL_USER ENV QL_HOME=/home/$QL_USER
@ -54,6 +56,7 @@ RUN set -x && \
jq \ jq \
procps \ procps \
netcat-openbsd \ netcat-openbsd \
sudo \
unzip \ unzip \
libatomic1 && \ libatomic1 && \
apt-get clean && \ apt-get clean && \
@ -68,7 +71,7 @@ RUN set -x && \
rm -rf /etc/apt/apt.conf.d/docker-clean && \ rm -rf /etc/apt/apt.conf.d/docker-clean && \
ulimit -c 0 ulimit -c 0
RUN mkdir -p ${QL_DIR} ${QL_DIR}/data && \ RUN mkdir -p ${QL_DIR} && \
chown -R ${QL_UID}:${QL_GID} ${QL_DIR} chown -R ${QL_UID}:${QL_GID} ${QL_DIR}
USER qinglong USER qinglong
@ -87,7 +90,7 @@ RUN git clone --depth=1 -b ${QL_BRANCH} ${QL_URL} ${QL_DIR} && \
ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \ ENV PNPM_HOME=${QL_DIR}/data/dep_cache/node \
PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \ PYTHON_HOME=${QL_DIR}/data/dep_cache/python3 \
PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3 \ PYTHONUSERBASE=${QL_DIR}/data/dep_cache/python3 \
HOME=/root HOME=/home/qinglong
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin:${HOME}/bin \ ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${PNPM_HOME}:${PYTHON_HOME}/bin:${HOME}/bin \
NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules \ NODE_PATH=/usr/local/bin:/usr/local/lib/node_modules \
@ -100,6 +103,10 @@ COPY --chown=qinglong:qinglong --from=builder /tmp/build/node_modules/. /ql/node
USER root USER root
RUN ln -sf ${QL_DIR}/shell/task.sh /usr/local/bin/task \
&& ln -sf ${QL_DIR}/shell/update.sh /usr/local/bin/ql \
&& chmod +x /usr/local/bin/task /usr/local/bin/ql
WORKDIR ${QL_DIR} WORKDIR ${QL_DIR}
HEALTHCHECK --interval=5s --timeout=2s --retries=20 \ HEALTHCHECK --interval=5s --timeout=2s --retries=20 \

View File

@ -94,15 +94,16 @@ if ! grep -qE '^::1[[:space:]]+.*localhost' /etc/hosts 2>/dev/null; then
log_with_style "INFO" "🔧 0. 已添加 IPv6 localhost 解析" log_with_style "INFO" "🔧 0. 已添加 IPv6 localhost 解析"
fi fi
# 在一切操作之前检查目录权限 # 自定义用户(非 qinglong/root可能 HOME 为空或不可写
ensure_ql_permissions # 修正 HOME 确保 npm/pip/pm2 等工具有可用的缓存目录
# Dockerfile 中 HOME=/root非 root 用户无法写入
# 将 HOME 修正为临时目录PM2/npm/pip 等工具的运行时数据无需持久化
if [ ! -w "$HOME" ]; then if [ ! -w "$HOME" ]; then
mkdir -p "$QL_DIR/.tmp"
export HOME="$QL_DIR/.tmp" export HOME="$QL_DIR/.tmp"
fi fi
# 在一切操作之前检查目录权限
ensure_ql_permissions
log_with_style "INFO" "🚀 1. 检测配置文件..." log_with_style "INFO" "🚀 1. 检测配置文件..."
load_ql_envs load_ql_envs
export_ql_envs export_ql_envs

View File

@ -108,8 +108,8 @@ const push_config = {
QYWX_KEY: '', // 企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770)例如693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa QYWX_KEY: '', // 企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770)例如693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
TG_BOT_TOKEN: '', // tg 机器人的 TG_BOT_TOKEN1407203283:AAG9rt-6RDaaX0HBLZQq0laNOh898iFYaRQ TG_BOT_TOKEN: '', // tg 机器人的 TG_BOT_TOKEN1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
TG_USER_ID: '', // tg 机器人的 TG_USER_ID1434078534 TG_USER_ID: '', // tg 机器人的 TG_USER_ID1234567890
TG_API_HOST: 'https://api.telegram.org', // tg 代理 api TG_API_HOST: 'https://api.telegram.org', // tg 代理 api
TG_PROXY_AUTH: '', // tg 代理认证参数 TG_PROXY_AUTH: '', // tg 代理认证参数
TG_PROXY_HOST: '', // tg 机器人的 TG_PROXY_HOST TG_PROXY_HOST: '', // tg 机器人的 TG_PROXY_HOST

View File

@ -94,8 +94,8 @@ push_config = {
'QYWX_KEY': '', # 企业微信机器人 'QYWX_KEY': '', # 企业微信机器人
'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN1407203283:AAG9rt-6RDaaX0HBLZQq0laNOh898iFYaRQ 'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN1234567890:ABCdefGHIjklMNOpqrsTUVwxyz
'TG_USER_ID': '', # tg 机器人的 TG_USER_ID1434078534 'TG_USER_ID': '', # tg 机器人的 TG_USER_ID1234567890
'TG_API_HOST': '', # tg 代理 api 'TG_API_HOST': '', # tg 代理 api
'TG_PROXY_AUTH': '', # tg 代理认证参数 'TG_PROXY_AUTH': '', # tg 代理认证参数
'TG_PROXY_HOST': '', # tg 机器人的 TG_PROXY_HOST 'TG_PROXY_HOST': '', # tg 机器人的 TG_PROXY_HOST

File diff suppressed because it is too large Load Diff

View File

@ -13,12 +13,19 @@ os_name="${QL_OS_TYPE:-}"
if [ -z "$os_name" ]; then if [ -z "$os_name" ]; then
os_name=$(source /etc/os-release && echo "$ID") os_name=$(source /etc/os-release && echo "$ID")
fi fi
# 非 root 用户使用 sudo
SUDO=""
if [ "$(id -u)" -ne 0 ]; then
SUDO="sudo"
fi
case "$os_name" in case "$os_name" in
alpine) alpine)
apk --no-cache add -f zlib-dev gcc jpeg-dev python3-dev musl-dev freetype-dev $SUDO apk --no-cache add -f zlib-dev gcc jpeg-dev python3-dev musl-dev freetype-dev
;; ;;
debian|ubuntu) debian|ubuntu)
apt-get install -y gcc python3-dev musl-dev zlib1g-dev libjpeg-dev libfreetype-dev $SUDO apt-get install -y gcc python3-dev musl-dev zlib1g-dev libjpeg-dev libfreetype-dev
;; ;;
*) *)
echo -e "暂不支持此系统 $os_name" echo -e "暂不支持此系统 $os_name"

View File

@ -41,10 +41,16 @@ if [[ $command != "reload" ]]; then
os_name=$(source /etc/os-release && echo "$ID") os_name=$(source /etc/os-release && echo "$ID")
fi fi
# 非 root 用户使用 sudo
SUDO=""
if [ "$(id -u)" -ne 0 ]; then
SUDO="sudo"
fi
case "$os_name" in case "$os_name" in
alpine) alpine)
apk update $SUDO apk update
apk add -f bash \ $SUDO apk add -f bash \
coreutils \ coreutils \
git \ git \
curl \ curl \
@ -59,8 +65,8 @@ if [[ $command != "reload" ]]; then
netcat-openbsd netcat-openbsd
;; ;;
debian|ubuntu) debian|ubuntu)
apt-get update $SUDO apt-get update
apt-get install -y git curl wget tzdata perl openssl jq nginx procps netcat-openbsd openssh-client $SUDO apt-get install -y git curl wget tzdata perl openssl jq nginx procps netcat-openbsd openssh-client
;; ;;
*) *)
echo -e "暂不支持此系统部署 $os_name" echo -e "暂不支持此系统部署 $os_name"