一行安装脚本
在 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 DIR | root 为 /usr/local/bin,其他用户为 ~/.local/bin | 二进制安装目录,不存在时创建,必须可写;与 --service 同用时须为绝对路径,且不在 /home、/root、/run/user 下 |
--service | 不安装 | 仅 Linux,需要 root:同时安装并启动 systemd 服务 imgyoung,数据在 /var/lib/imgyoung |
| 环境变量 | 默认 | 说明 |
|---|---|---|
IMGYOUNG_RELEASES | https://github.com/x-haose/imgyoung/releases | 发布页地址。用镜像站或内网分发时设置,目录结构须与 GitHub Releases 一致,见下文「镜像站与内网分发」 |
传入未知选项或格式不对的版本号,脚本当场报错退出,不做任何改动。
脚本做了什么
- 检查前提。确认
curl、tar、install存在;带--service时再确认系统是 Linux、以 root 运行、有systemctl,且指定的--dir是家目录之外的绝对路径。不满足就在下载之前退出,不动系统。 - 识别平台。
uname -s为 Linux 或 Darwin,uname -m为 x86_64 / amd64 或 aarch64 / arm64;其他系统或架构直接报错(Windows 请用 发布包)。 - 确定版本。没给
--version时请求<发布页>/latest,跟随跳转,取最终地址的最后一段作为版本标签;GitHub 的 latest 不含预发布版。 - 下载并校验。在临时目录下载
imgyoung_<版本号>_<系统>_<架构>.tar.gz与同版本的checksums.txt,核对 sha256;不一致即中止,不安装任何东西。临时目录在脚本退出时删除。 - 安装二进制。以 0755 权限装到目标目录的
imgyoung,并打印它的版本信息。 - 安装服务(仅
--service)。把发布包里的deploy/imgyoung.service写到/etc/systemd/system/imgyoung.service,其中ExecStart换成实际安装路径,与原有文件内容不同时给出提示;执行systemctl daemon-reload并 enable。服务已在运行就重启以换上新版本,否则启动。 - 提示下一步。目标目录不在
PATH中时提醒;打印登录地址与出厂账号。
没加 --service 时,脚本只安装二进制,不会启动它。直接运行 imgyoung 即可,数据写在当前目录的 data/(可用 IMGYOUNG_DATA_DIR 指定)。长期运行请交给进程管理器,原因见 安装方式。
systemd 服务
--service 安装的就是仓库里的这份示例,只改了 ExecStart:
# 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在打开的编辑器里写入要覆盖的设置,例如只经本机反向代理对外时改成只监听回环:
[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 -- --serviceinstall.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。