安装

一行安装脚本

在 Linux 与 macOS 上下载发布版、校验 sha256 并装入 PATH;Linux 上可同时注册 systemd 服务。重复执行即升级。

用法

终端
curl -fsSL https://raw.githubusercontent.com/x-haose/imgyoung/main/install.sh | sh

选项经 sh -s -- 传给脚本:

终端
# 装成 systemd 服务并启动(仅 Linux,需要 root)
curl -fsSL https://raw.githubusercontent.com/x-haose/imgyoung/main/install.sh | sudo sh -s -- --service

# 安装指定版本
curl -fsSL https://raw.githubusercontent.com/x-haose/imgyoung/main/install.sh | sh -s -- --version 1.0.0

想先读一遍脚本再执行:

终端
curl -fsSLo install.sh https://raw.githubusercontent.com/x-haose/imgyoung/main/install.sh
less install.sh
sudo sh install.sh --service

脚本需要 curl、tar、install,以及 sha256sum 或 shasum 之一;--service 还需要 systemctl。

选项与环境变量

选项默认说明
--version X.Y.Z最新正式版安装指定版本,前缀 v 可带可不带
--dir DIRroot 为 /usr/local/bin,其他用户为 ~/.local/bin二进制安装目录,不存在时创建,必须可写;与 --service 同用时须为绝对路径,且不在 /home、/root、/run/user 下
--service不安装仅 Linux,需要 root:同时安装并启动 systemd 服务 imgyoung,数据在 /var/lib/imgyoung
环境变量默认说明
IMGYOUNG_RELEASEShttps://github.com/x-haose/imgyoung/releases发布页地址。用镜像站或内网分发时设置,目录结构须与 GitHub Releases 一致,见下文「镜像站与内网分发」

传入未知选项或格式不对的版本号,脚本当场报错退出,不做任何改动。

脚本做了什么

  1. 检查前提。确认 curl、tar、install 存在;带 --service 时再确认系统是 Linux、以 root 运行、有 systemctl,且指定的 --dir 是家目录之外的绝对路径。不满足就在下载之前退出,不动系统。
  2. 识别平台。uname -s 为 Linux 或 Darwin,uname -m 为 x86_64 / amd64 或 aarch64 / arm64;其他系统或架构直接报错(Windows 请用 发布包)。
  3. 确定版本。没给 --version 时请求 <发布页>/latest,跟随跳转,取最终地址的最后一段作为版本标签;GitHub 的 latest 不含预发布版。
  4. 下载并校验。在临时目录下载 imgyoung_<版本号>_<系统>_<架构>.tar.gz 与同版本的 checksums.txt,核对 sha256;不一致即中止,不安装任何东西。临时目录在脚本退出时删除。
  5. 安装二进制。以 0755 权限装到目标目录的 imgyoung,并打印它的版本信息。
  6. 安装服务(仅 --service)。把发布包里的 deploy/imgyoung.service 写到 /etc/systemd/system/imgyoung.service,其中 ExecStart 换成实际安装路径,与原有文件内容不同时给出提示;执行 systemctl daemon-reload 并 enable。服务已在运行就重启以换上新版本,否则启动。
  7. 提示下一步。目标目录不在 PATH 中时提醒;打印登录地址与出厂账号。

没加 --service 时,脚本只安装二进制,不会启动它。直接运行 imgyoung 即可,数据写在当前目录的 data/(可用 IMGYOUNG_DATA_DIR 指定)。长期运行请交给进程管理器,原因见 安装方式。

systemd 服务

--service 安装的就是仓库里的这份示例,只改了 ExecStart:

deploy/imgyoung.service
# ImgYoung 的 systemd 服务示例;install.sh --service 安装的就是它。
# 手动安装:二进制放到 /usr/local/bin/imgyoung,本文件复制到 /etc/systemd/system/imgyoung.service,
# 然后 systemctl daemon-reload && systemctl enable --now imgyoung。
# 数据在 /var/lib/imgyoung(数据库、本地存储渠道、master.key),备份它。
[Unit]
Description=ImgYoung 自部署图床
Documentation=https://github.com/x-haose/imgyoung
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/imgyoung
Environment=IMGYOUNG_DATA_DIR=%S/imgyoung
# 渠道参数直接交给 rclone,不用 rclone 的配置文件;置空让 rclone 启动时不去寻找家目录下的配置
Environment=RCLONE_CONFIG=
# 只经本机反向代理对外时,改成只监听回环:
# Environment=IMGYOUNG_LISTEN=127.0.0.1:8721

# 以临时系统用户运行,数据目录由 systemd 创建并归属该用户
DynamicUser=yes
StateDirectory=imgyoung

# 后台「从快照恢复」会让服务优雅退出,靠这里重新拉起后换入快照;正常退出也要拉起
Restart=always
RestartSec=3s
# 优雅停机先停收新请求、等在途请求至多 6 秒,再停后台任务至多 2 秒;多出的是关库与退出的余量
TimeoutStopSec=15s

# 数据目录里有 master.key,新建文件只给运行用户自己读写
UMask=0077
# 进程只能写自己的数据目录;本地存储渠道指向别处时,用 ReadWritePaths= 放开那个目录
NoNewPrivileges=yes
CapabilityBoundingSet=
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
ProtectKernelLogs=yes
ProtectClock=yes
ProtectHostname=yes
RestrictNamespaces=yes
RestrictRealtime=yes
RestrictSUIDSGID=yes
LockPersonality=yes
SystemCallArchitectures=native

[Install]
WantedBy=multi-user.target

几个关键设置:

  • 数据目录。IMGYOUNG_DATA_DIR=%S/imgyoung 即 /var/lib/imgyoung,由 StateDirectory=imgyoung 让 systemd 创建并交给运行用户。启用 DynamicUser 时实际目录是 /var/lib/private/imgyoung,/var/lib/imgyoung 是指向它的符号链接。里面是 imgyoung.db、master.key、local 渠道的 blobs/ 与衍生图缓存 variants/。
  • DynamicUser=yes。每次启动由 systemd 分配一个临时系统用户来运行,不需要预先建用户。配合 ProtectSystem=strict、ProtectHome=yes 等沙箱设置,进程只能写自己的数据目录:local 渠道的路径改到别处时,要用 ReadWritePaths= 放开那个目录;二进制也不能装在 /home 或 /root 下,否则服务启动不了,脚本遇到这种 --dir 会直接拒绝。
  • Restart=always。后台「恢复」快照会让服务正常退出,systemd 3 秒后重新拉起,启动时在开库前换入快照。Restart=on-failure 不会拉起正常退出的进程,恢复要等到有人手动启动服务才完成。
  • TimeoutStopSec=15s。停止时先停收新请求,在途请求最多等 6 秒(超时强制断开);再取消后台循环与在途补齐任务,最多等 2 秒;然后关库退出。合计约 8 秒,15 秒留出余量。被取消的补齐任务在下次启动时由对账重新入队。
  • UMask=0077。新建的文件(包括 master.key)只有运行用户可读写。
  • RCLONE_CONFIG=(置空)。渠道参数由 ImgYoung 直接交给 rclone,不读 rclone 的配置文件。

常用命令:

终端
systemctl status imgyoung        # 运行状态
journalctl -u imgyoung -f        # 跟踪日志
sudo systemctl restart imgyoung  # 改了环境变量后重启生效

修改服务配置

带 --service 重跑脚本时,/etc/systemd/system/imgyoung.service 会被发布包里的版本整个覆盖,内容有变化时脚本会提示。本地的改动不要写进这个文件,写进 drop-in:

终端
sudo systemctl edit imgyoung

在打开的编辑器里写入要覆盖的设置,例如只经本机反向代理对外时改成只监听回环:

/etc/systemd/system/imgyoung.service.d/override.conf
[Service]
Environment=IMGYOUNG_LISTEN=127.0.0.1:8721

保存后执行 sudo systemctl restart imgyoung。可用的环境变量见 配置。

升级

重新执行安装时的同一条命令:

  • 加过 --service:替换二进制、重写服务文件,并重启服务换上新版本。升级时必须同样带上 --service,否则只换了磁盘上的文件,运行中的仍是旧版本。
  • 没加 --service:只替换二进制,自己重启进程。

要停在某个版本,用 --version。数据库结构在新版本启动时自动迁移。

--version 也能装回旧版本,但不能借此降级:被新版本迁移过的数据库,旧版本会拒绝启动,并在错误里写明库里与二进制各自的最新迁移版本。回滚只能用旧版本加升级前的快照,步骤与升级前的准备见 升级。

卸载

装了服务时:

终端
sudo systemctl disable --now imgyoung
sudo rm /etc/systemd/system/imgyoung.service
sudo rm -rf /etc/systemd/system/imgyoung.service.d   # 用过 systemctl edit 才有
sudo systemctl daemon-reload
sudo rm /usr/local/bin/imgyoung

数据目录不会随之删除。确认已经不需要其中的图片、数据库与 master.key 之后再删:

终端
sudo rm -rf /var/lib/private/imgyoung /var/lib/imgyoung

只装了二进制时,删除二进制(默认 ~/.local/bin/imgyoung 或 /usr/local/bin/imgyoung),再按需删除运行时用过的数据目录。

镜像站与内网分发

访问 GitHub 不便时,把发布物放到镜像站或内网服务器,用 IMGYOUNG_RELEASES 指过去。环境变量要给执行脚本的 sh,不是给 curl:

终端
curl -fsSL https://mirror.example.com/imgyoung/install.sh \
  | sudo IMGYOUNG_RELEASES=https://mirror.example.com/imgyoung/releases sh -s -- --service

install.sh 本身也要能从那里取到。镜像站的目录须与 GitHub Releases 一致:

<IMGYOUNG_RELEASES>/latest                                   跳转到 .../tag/vX.Y.Z
<IMGYOUNG_RELEASES>/download/vX.Y.Z/imgyoung_X.Y.Z_linux_amd64.tar.gz
<IMGYOUNG_RELEASES>/download/vX.Y.Z/checksums.txt

/latest 只在不指定 --version 时用到:脚本跟随跳转,把最终地址的最后一段当作版本号,它必须以 v 加数字开头。镜像站做不到这种跳转时,安装与升级都显式带上 --version。

本页目录