122个版本
0.5.17-pre.5 | 2024年7月21日 |
---|---|
0.5.17-pre.3 | 2024年6月26日 |
0.5.10 | 2024年3月24日 |
0.5.0-rc.9 | 2023年12月28日 |
0.3.0-alpha.42 | 2021年10月27日 |
80 在 图像 中排名
每月263次下载
在 lemmy_server 中使用
2MB
20K SLoC
pict-rs
一个简单的图像托管服务
导航
链接
用法
运行
命令行
$ pict-rs -h
A simple image hosting service
Usage: pict-rs [OPTIONS] <COMMAND>
Commands:
run Runs the pict-rs web server
migrate-store Migrates from one provided media store to another
migrate-repo Migrates from one provided repo to another
help Print this message or the help of the given subcommand(s)
Options:
-c, --config-file <CONFIG_FILE>
Path to the pict-rs configuration file
--old-repo-path <OLD_REPO_PATH>
Path to the old pict-rs sled database
--old-repo-cache-capacity <OLD_REPO_CACHE_CAPACITY>
The cache capacity, in bytes, allowed to sled for in-memory operations
--log-format <LOG_FORMAT>
Format of logs printed to stdout [possible values: compact, json, normal, pretty]
--log-targets <LOG_TARGETS>
Log levels to print to stdout, respects RUST_LOG formatting
--log-spans
Whether to log openning and closing of tracing spans to stdout
--console-address <CONSOLE_ADDRESS>
Address and port to expose tokio-console metrics
--console-buffer-capacity <CONSOLE_BUFFER_CAPACITY>
Capacity of the console-subscriber Event Buffer
--opentelemetry-url <OPENTELEMETRY_URL>
URL to send OpenTelemetry metrics
--opentelemetry-service-name <OPENTELEMETRY_SERVICE_NAME>
Service Name to use for OpenTelemetry
--opentelemetry-targets <OPENTELEMETRY_TARGETS>
Log levels to use for OpenTelemetry, respects RUST_LOG formatting
--save-to <SAVE_TO>
File to save the current configuration for reproducible runs
-h, --help
Print help
-V, --version
Print version
尝试运行 help
命令以获取更多运行时配置选项
$ pict-rs run -h
$ pict-rs run filesystem -h
$ pict-rs run object-storage -h
$ pict-rs run filesystem sled -h
$ pict-rs run filesystem postgres -h
$ pict-rs run object-storage sled -h
$ pict-rs run object-storage postgres -h
有关更多配置信息,请参阅 pict-rs.toml
示例
使用默认配置运行
$ ./pict-rs run
在所有接口上运行,端口8080,数据存储在/opt/data
$ ./pict-rs \
run -a 0.0.0.0:8080 \
filesystem -p /opt/data/files \
sled -p /opt/data/sled-repo
本地运行,端口9000,数据存储在data/,并将所有上传转换为PNG
$ ./pict-rs \
run \
-a 127.0.0.1:9000 \
--media-format png \
filesystem -p data/files \
sled -p data/sled-repo
本地运行,端口8080,数据存储在data/目录中,仅允许使用thumbnail
和identity
过滤器
$ ./pict-rs \
run \
-a 127.0.0.1:8080 \
--media-filters thumbnail \
--media-filters identity \
filesystem -p data/files \
sled -p data/sled-repo
从配置文件运行
$ ./pict-rs -c ./pict-rs.toml run
从文件系统存储迁移到对象存储。更多详细信息,请参阅文件系统到对象存储迁移
$ ./pict-rs \
migrate-store \
filesystem -p data/files \
object-storage \
-a ACCESS_KEY \
-b BUCKET_NAME \
-r REGION \
-s SECRET_KEY
将配置覆盖写入toml文件
$ ./pict-rs --save-to pict-rs.toml \
run \
object-storage \
-a ACCESS_KEY \
-b pict-rs \
-r us-east-1 \
-s SECRET_KEY \
sled -p data/sled-repo
Docker
运行以下命令
# Create a folder for the files (anywhere works)
$ mkdir ./pict-rs
$ cd ./pict-rs
$ mkdir -p volumes/pictrs
$ sudo chown -R 991:991 volumes/pictrs
$ wget https://git.asonix.dog/asonix/pict-rs/raw/branch/main/docker/prod/docker-compose.yml
$ sudo docker-compose up -d
注意
- pict-rs使用系统临时文件夹。在Linux上通常是
/tmp
裸机
有几个方法可以获得pict-rs以在docker外运行。
- 通过您选择的发行版打包
- 从发布页面下载二进制文件
- 从源代码编译
如果在外部运行docker,建议的配置方法是使用pict-rs.toml
文件。在运行pict-rs时,可以将文件作为命令行参数传递给二进制文件。
$ pict-rs -c /path/to/pict-rs.toml run
发行版软件包
如果您从您的发行版获取pict-rs,请确保它是最新版本(意味着0.3.x稳定版,或0.4.x稳定版)。如果它较旧,请考虑使用其他选项安装pict-rs。我目前知道pict-rs打包在AUR和nixpkgs中,但可能还有其他发行版也打包了它。
二进制下载
pict-rs提供了预编译的二进制文件,应该适用于任何x86_64、aarch64和armv7h的Linux系统。有关发布页面,请参阅发布页面。如果下载二进制文件,请确保已安装以下依赖项
ImageMagick
7ffmpeg
5或6exiftool
12(有时称为perl-image-exiftool
)
这些二进制文件由pict-rs调用以处理上传的媒体,因此它们必须位于pict-rs可用的$PATH
中。
这里的一个明显问题是ImageMagick 7,它未打包在Debian Sid中,因此在任何版本的Debian或Ubuntu中都不可用。如果您正在运行Ubuntu或Debian系统,请考虑使用Nix安装和运行方法。
更多信息请参阅Ubuntu和Debian文档
从源码编译
可以使用最新版本的rust编译器从源代码编译pict-rs。我在1.75上开发和发布版本
与二进制下载选项类似,必须安装imagemagick
、ffmpeg
和exiftool
才能正确运行pict-rs。
Nix
pict-rs附带相关的nix flake。这对于开发环境很有用,也可以用于运行带有所有必要依赖项的“生产”版本的pict-rs。
可以使用这些说明安装Nix包管理器。安装后,必须启用两个实验性功能:flake
和nix-command
。这些需要在/etc/nix/nix.conf
中添加。
experimental-features = nix-command flakes
启用 flakes 之后,您可以从 pict-rs 源目录运行 nix build
。这将生成包含 pict-rs 及其依赖项的 nix 包。同时,它还会在 pict-rs 目录中创建一个名为 result
的符号链接,指向新构建的包。result
的内容应为一个名为 bin
的单一文件夹,其中包含一个名为 pict-rs
的文件。此文件是一个 shell 脚本,用于调用具有所需 $PATH
的 pict-rs
二进制文件,以便找到 imagemagick 7、ffmpeg 6 和 exiftool。您可以像对待真正的 pict-rs 二进制文件一样处理此 shell 脚本,并传递给 pict-rs 相同的参数。
示例
./result/bin/pict-rs -c dev.toml run
API
pict-rs 提供以下端点
-
POST /image?{args}
用于上传图像。上传的内容必须是有效的 multipart/form-data,且图像数组位于images[]
键内{args} 查询在图像上传中具有多重用途。首先,它为上传的媒体提供请求级别的验证。以下是可以用的键:
- max_width:允许上传媒体的最大宽度(像素)
- max_height:允许上传媒体的最大高度(像素)
- max_area:允许上传媒体的最大面积(像素)
- max_frame_count:动画和视频允许的最大帧数
- max_file_size:允许的最大文件大小(兆字节)
- allow_image:是否允许上传静态图像
- allow_animation:是否允许上传动画
- allow_video:是否允许上传视频
这些验证在 pict-rs 配置中指定的验证之外应用,因此如果任何验证失败,上传的媒体将被拒绝。
{args} 查询的第二个目的是为上传的图像提供预处理步骤。格式与 process.{ext} 端点相同。使用这些步骤提供的图像在保存之前将进行处理。
此端点在成功时返回以下 JSON 结构,状态为 201 Created
{ "files": [ { "delete_token": "JFvFhqJA98", "file": "lkWZDRvugm.jpg", "details": { "width": 800, "height": 800, "content_type": "image/jpeg", "created_at": "2022-04-08T18:33:42.957791698Z" } }, { "delete_token": "kAYy9nk2WK", "file": "8qFS0QooAn.jpg", "details": { "width": 400, "height": 400, "content_type": "image/jpeg", "created_at": "2022-04-08T18:33:42.957791698Z" } }, { "delete_token": "OxRpM3sf0Y", "file": "1hJaYfGE01.jpg", "details": { "width": 400, "height": 400, "content_type": "image/jpeg", "created_at": "2022-04-08T18:33:42.957791698Z" } } ], "msg": "ok" }
-
POST /image/backgrounded?{args}
与/image
端点类似上传图像,但不需要等待验证和处理。{args} 查询与内联图像上传端点格式相同。此端点在成功时返回以下 JSON 结构,状态为 202 Accepted
{ "uploads": [ { "upload_id": "c61422e1-9294-4f1f-977f-c696b7939467", }, { "upload_id": "62cc707f-725c-44b6-908f-2bd8946c3c29" } ], "msg": "ok" }
-
GET /image/download?url={url}&backgrounded=(true|false)
从远程服务器下载图像,默认返回与POST /image
端点相同的 JSON 有效负载。如果
backgrounded
设置为true
,则摄取处理将被排队等待后续处理,响应 JSON 将与POST /image/backgrounded
端点相同。 -
GET /image/backgrounded/claim?upload_id={uuid}
等待后台上传完成,并声明其结果 可能的结果- 200 Ok(验证和摄取完成)
{ "files": [ { "delete_token": "OxRpM3sf0Y", "file": "1hJaYfGE01.jpg", "details": { "width": 400, "height": 400, "content_type": "image/jpeg", "created_at": "2022-04-08T18:33:42.957791698Z" } } ], "msg": "ok" }
- 422 Unprocessable Entity(验证或其他失败)
{ "msg": "Error message about what went wrong with upload" }
- 204 No Content(上传验证和摄取未完成,等待超时)在这种情况下,再次尝试是可行的
- 200 Ok(验证和摄取完成)
-
GET /image/original/{alias}
获取全分辨率图像。这里的alias
是file
键,来自/image
端点的 JSON -
GET /image/original?alias={alias}
获取全分辨率图像。这里的alias
是file
键,来自/image
端点的 JSON 可用源参数包括?alias={alias}
通过别名提供服务原始文件?proxy={url}
这个proxy
字段可用于通过原始端点代理外部 URL。这些代理图像在最后一次访问后的一段时间内从 pict-rs 中删除。这个时间可以通过PICTRS__MEDIA__RETENTION__PROXY
配置。更多信息请参见(./pict-rs.toml)[./pict-rs.toml]。
-
HEAD /image/original/{alias}
只返回与类似GET
请求相对应的头信息。 -
HEAD /image/original?alias={alias}
只返回与类似GET
请求相对应的头信息。可用源参数包括?alias={alias}
通过别名提供服务原始文件?proxy={url}
这个proxy
字段可用于通过原始端点代理外部 URL。这些代理图像在最后一次访问后的一段时间内从 pict-rs 中删除。这个时间可以通过PICTRS__MEDIA__RETENTION__PROXY
配置。更多信息请参见(./pict-rs.toml)[./pict-rs.toml]。
-
GET /image/details/original/{alias}
用于获取全分辨率图像的详细信息。返回的 JSON 结构如下{ "width": 800, "height": 537, "content_type": "image/webp", "created_at": "2022-04-08T18:33:42.957791698Z" }
-
GET /image/details/original?alias={alias}
与上述端点相同,但使用查询而不是路径可用源参数包括
?alias={alias}
通过别名提供服务原始文件?proxy={url}
此proxy
字段可用于获取 pict-rs 中代理图像的详细信息。这些代理图像在最后一次访问后一段时间将从 pict-rs 中删除。此时间可通过PICTRS__MEDIA__RETENTION__PROXY
配置。更多信息请参阅 (./pict-rs.toml)[./pict-rs.toml]。
-
GET /image/blurhash?alias={alias}
为提供的别名创建并存储 blurhash可用源参数包括
?alias={alias}
为通过提供的别名识别的图像提供 blurhash?proxy={url}
为位于url
的媒体提供 blurhash。这将下载并存储指定媒体的原始版本及其 blurhash。代理媒体的保留时间可通过PICTRS__MEDIA__RETENTION__PROXY
配置。更多信息请参阅 (./pict-rs.toml)[./pict-rs.toml]。
返回的 JSON 结构如下
{ "msg": "ok", "blurhash": "LGF5]+Yk^6#M@-5c,1J5@[or[Q6." }
-
GET /image/process.{ext}?src={alias}&...
获取应用了转换的文件。可用的源参数包括?src={alias}
此行为与之前版本相同?alias={alias}
此alias
字段与src
字段相同。重命名以提高一致性?proxy={url}
此proxy
字段可用于通过进程端点代理外部 URL。这些代理图像在最后一次访问后一段时间将从 pict-rs 中删除。此时间可通过PICTRS__MEDIA__RETENTION__PROXY
配置。更多信息请参阅 (./pict-rs.toml)[./pict-rs.toml]。
现有的转换包括
-
identity=true
:不应用任何更改 -
blur={float}
:对文件应用高斯模糊 -
thumbnail={int}
:通过原始像素采样生成适合{int}
正方形内的图像缩略图 -
resize={int}
:生成一个适合放入{int}
大小的正方形内的缩略图,使用 Lanczos2 过滤器。这比采样慢,但在某些情况下看起来会更好。 -
resize={filter}.(a){int}
:生成一个适合放入{int}
大小的正方形内的缩略图,或者当(a)
存在时,生成一个面积小于{int}
的缩略图。{filter}
是可选的,表示在调整图像大小时使用什么过滤器。可用的过滤器有Lanczos
、Lanczos2
、LanczosSharp
、Lanczos2Sharp
、Mitchell
和RobidouxSharp
。示例
resize=300
:生成一个适合放入 300x300 px 正方形内的图像reizie=.a10000
:生成一个面积最多为 10000 px 的图像resize=Mitchell.200
:使用 Mitchell 过滤器生成一个适合放入 200x200 px 正方形内的图像resize=RobidouxSharp.40000
:使用 RobidouxSharp 过滤器生成一个面积最多为 40000 px 的图像
-
crop={int-w}x{int-h}
:生成一个裁剪后的图像,其宽高比为{int-w}
。裁剪后的图像将居中显示。图像的宽度和高度中至少有一个将保持原始大小,这取决于图像的宽高比和请求的宽高比。例如,一个 1600x900 的图像以 1x1 的宽高比裁剪将变为 900x900。一个 1600x1100 的图像以 16x9 的宽高比裁剪将变为 1600x900。
支持的
ext
文件扩展名包括apng
、avif
、gif
、jpg
、jxl
、png
和webp
。请注意,虽然avif
和webp
可用于动画和非动画图像,但某些格式如apng
和gif
只用于提供动画,而其他格式如jpg
、jxl
和png
只用于提供静态图像。使用示例可以是
GET /image/process.jpg?src=asdf.png&thumbnail=256&blur=3.0
这将创建一个 256x256 像素的 JPEG 缩略图并将其模糊化
-
HEAD /image/process.{ext}?src={alias}
返回类似于GET
请求的头部信息。如果处理过的图像尚未生成,则返回 404。可用源参数包括
?src={alias}
此行为与之前版本相同?alias={alias}
此alias
字段与src
字段相同。重命名以提高一致性?proxy={url}
此proxy
字段可以用来获取代理图像的头部信息。
-
GET /image/process_backgrounded.{ext}?src={alias}&...
将转换队列应用于指定文件。此操作接受与process.{ext}
端点相同的参数,但不等待处理完成。可用源参数包括
?src={alias}
此行为与之前版本相同?alias={alias}
此alias
字段与src
字段相同。重命名以提高一致性
-
GET /image/details/process.{ext}?src={alias}&...
获取处理过的图像详情。返回的 JSON 格式与全分辨率详情端点列出的格式相同。可用源参数包括
?src={alias}
此行为与之前版本相同?alias={alias}
此alias
字段与src
字段相同。重命名以提高一致性?proxy={url}
此proxy
字段可以用来获取代理图像的详细信息。
-
GET /image/details/process.{ext}?alias={alias}
与上述端点相同,但使用查询而不是路径可用源参数包括
?alias={alias}
通过别名提供服务文件?proxy={url}
这个proxy
字段可以用来获取 pict-rs 中代理图像的详细信息。这些代理图像在其最后访问后的一段时间内将从 pict-rs 中删除。这个时间可以通过PICTRS__MEDIA__RETENTION__PROXY
进行配置。更多信息请参阅 ./pict-rs.toml。
-
DELETE /image/delete/{delete_token}/{alias}
或GET /image/delete/{delete_token}/{alias}
来删除文件,其中delete_token
和alias
来自/image
端点的 JSON -
GET /healthz
检查 pict-rs 服务器的健康状态。这将检查内嵌的 sled 数据库是否正常工作,以及配置的存储是否可访问
以下端点通过 X-Api-Token
标头受 API 密钥保护,并且除非将 --api-key
选项传递给二进制文件或设置 PICTRS__SERVER__API_KEY 环境变量,否则它们将禁用。
可以通过任何密码生成器生成安全的 API 密钥。
-
POST /internal/import
用于上传图像,同时保留文件名作为第一个别名。上传格式和响应格式与POST /image
端点相同。 -
POST /internal/delete?alias={alias}
无需删除令牌即可删除别名。可用的源参数有?alias={alias}
删除文件别名?proxy={url}
删除代理文件的别名
此端点返回以下 JSON
{ "msg": "ok", }
-
POST /internal/purge?alias={alias}
通过别名清除文件。这将删除与查询相关联的所有别名和文件。可用源参数包括
?alias={alias}
通过别名清除文件?proxy={url}
通过 URL 清除代理文件
此端点返回以下 JSON
{ "msg": "ok", "aliases": ["asdf.png"] }
-
GET /internal/aliases?alias={alias}
通过别名获取文件的别名可用源参数包括
?alias={alias}
通过提供的别名获取文件的全部别名?proxy={url}
通过URL获取代理文件的全部别名
此端点返回与清除端点相同的JSON
-
DELETE /internal/variants
为上传图像生成的变体排队清理。如果再次获取清理的变体,它们将重新生成。
-
GET /internal/identifier?alias={alias}
获取给定别名的图像标识符(文件路径或对象路径)。可用源参数包括
?alias={alias}
通过提供的别名获取文件的标识符?proxy={url}
通过URL获取代理文件的标识符
成功时,返回的JSON应如下所示
{ "msg": "ok", "identifier": "/path/to/object" }
-
POST /internal/set_not_found?alias={alias}
设置从原始和处理端点服务404图像。使用的图像必须已经上传并具有别名。请求应如下所示{ "alias": "asdf.png" }
成功时,返回的JSON应如下所示
{ "msg": "ok" }
如果pict-rs找不到提供的别名,它将返回以下JSON的400 Bad Request
{ "msg": "No hash associated with provided alias" }
-
POST /internal/export
将当前sled数据库导出到配置的export_path
。这对于备份正在运行的pict-rs服务器非常有用。成功时,它将返回{ "msg": "ok" }
从导出的数据库恢复就像这样
- 停止pict-rs
- 将您的当前
sled-repo
目录移动到安全位置(例如sled-repo.bak
)$ mv sled-repo sled-repo.bak
- 将导出的数据库复制到
sled-repo
$ cp -r exports/2023-07-08T22:26:21.194126713Z sled-repo
- 启动pict-rs
-
GET /internal/hashes?{query}
根据提供的查询按最新到最旧的顺序获取一页哈希值。成功时,它将返回以下JSON{ "msg": "ok", "page": { "limit": 20, "current": "some-long-slug-string", "next": "some-long-slug-string", "prev": "some-long-slug-string", "hashes": [{ "hex": "some-long-hex-encoded-hash", "aliases": [ "file-alias.png", "another-alias.png", ], "details": { "width": 1920, "height": 1080, "frames": 30, "content_type": "video/mp4", "created_at": "2022-04-08T18:33:42.957791698Z" } }] } }
请注意,此响应中的一些字段是可选的(包括
next
、prev
、current
、details
和frames
)可用查询选项
- empty:这将获取结果的第一页(例如,最新媒体)
?slug={slug}
这将获取结果页面的特定页面。字段slug
来自页面 JSON 中的current
、next
或prev
字段?timestamp={timestamp}
这将获取早于指定时间戳的结果,以便轻松搜索数据。timestamp
应根据 RFC3339 格式化?limit={limit}
指定每页返回的结果数量
-
POST /internal/prune_missing?force={force}
启动一个后台任务,该任务将检查数据库中的每个哈希值是否有相关的媒体文件,删除任何缺少媒体记录的记录。警告:此操作非常具有破坏性。请在调用之前进行备份。
此端点可以被重复调用以检查准备工作的进度。返回的
progress
值表示已标记为修剪的记录数量。可选地,可以将
force
查询参数传递给值true
,以便在当前任务似乎卡住时让 pict-rs 启动另一个任务。
此外,所有端点都支持设置截止日期,在此之后请求将停止处理。要为您的请求启用截止日期,可以将 X-Request-Deadline
标头设置为表示自 UNIX Epoch 以来的纳秒数的 i128 值。计算此值的一个简单方法是使用 time
crate 的 OffsetDateTime::unix_timestamp_nanos
方法。例如,
// set deadline of 1ms
let deadline = time::OffsetDateTime::now_utc() + time::Duration::new(0, 1_000);
let request = client
.get("http://pict-rs:8080/image/details/original/asdfghjkla.png")
.insert_header(("X-Request-Deadline", deadline.unix_timestamp_nanos().to_string())))
.send()
.await;
最后,还有一个可选的 Prometheus 抓取端点,可以通过 PICTRS__METRICS__PROMETHEUS_ADDRESS
配置启用。这将绑定到主 pict-rs 应用程序之外的一个单独端口。有关更多详细信息,请参阅 pict-rs.toml。
管理
备份
pict-rs 维护两个重要的文件夹:sled-repo
目录和 files
目录。 sled-repo
是它存储有关文件元数据的地方,例如:它们的位置、它们的别名、它们处理后的版本的位置、它们的尺寸、MIME 类型等。 files
是它将上传的文件存储在本地文件系统中的位置。
与 files
文件夹相比,sled-repo
文件夹通常很小,备份它只需将其复制到其他位置即可。我建议在 pict-rs 不运行时进行此操作。
如果您无法停止 pict-rs,但想备份数据库,则可以在 Api 中找到的内部端点 /internal/export
,用于生成当前数据库的副本,以便轻松备份。
从0.4到0.5迁移指南
注意
如果您正在运行 pict-rs 的旧版本,您需要首先更新到 0.4,然后再继续到 0.5。请参阅 0.3 到 0.4 迁移指南。
概述
在第一次启动0.5版本时,pict-rs将自动将0.4数据库格式迁移到0.5数据库格式。这个过程可能需要一些时间,尤其是如果你从0.3版本之前就开始运行pict-rs。原因是pict-rs现在要求原始文件在数据库中存储相关详细信息记录,而虽然0.3和0.4版本默认会生成这些记录,但在这一标准之前上传的图像可能从未生成过详细信息记录。
升级配置
由于升级可能需要很长时间,因此引入了新的配置选项以尝试提高其速度。
[upgrade]
concurrency = 32
或
PICTRS__UPGRADE__CONCURRENCY=32
或
$ pict-rs run --upgrade-concurrency 32
此值指定pict-rs将同时尝试迁移多少个哈希值。由于此值将增加对Repo和Store的并发连接数,以及可能增加CPU和内存使用,因此在增加之前应仔细考虑。
对于大规模部署,此值可能应该增加到128、256甚至512。默认值为32。
配置更新
以前,pict-rs只有两种文件类别:图像和视频。pict-rs 0.5添加了第三个类别:动画。由于现在显式支持动画文件类型,一些配置选项已移动。
图像更改
旧环境变量 | 新环境变量 |
---|---|
PICTRS__MEDIA__FORMAT |
PICTRS__MEDIA__IMAGE__FORMAT |
PICTRS__MEDIA__MAX_WIDTH |
PICTRS__MEDIA__IMAGE__MAX_WIDTH |
PICTRS__MEDIA__MAX_HEIGHT |
PICTRS__MEDIA__IMAGE__MAX_HEIGHT |
PICTRS__MEDIA__MAX_AREA |
PICTRS__MEDIA__IMAGE__MAX_AREA |
PICTRS__MEDIA__IMAGE__MAX_FILE_SIZE |
旧 TOML 值 | 新 TOML 值 |
---|---|
[media]format |
[media.image]format |
[media]max_width |
[media.image]max_width |
[media]max_height |
[media.image]max_height |
[media]max_area |
[media.image]max_area |
[media.image]max_file_size |
动画更改
旧环境变量 | 新环境变量 |
---|---|
PICTRS__MEDIA__GIF__MAX_WIDTH |
PICTRS__MEDIA__ANIMATION__MAX_WIDTH |
PICTRS__MEDIA__GIF__MAX_HEIGHT |
PICTRS__MEDIA__ANIMATION__MAX_HEIGHT |
PICTRS__MEDIA__GIF__MAX_AREA |
PICTRS__MEDIA__ANIMATION__MAX_AREA |
PICTRS__MEDIA__GIF__MAX_FILE_SIZE |
PICTRS__MEDIA__ANIMATION__MAX_FILE_SIZE |
PICTRS__MEDIA__GIF__MAX_FRAME_COUNT |
PICTRS__MEDIA__ANIMATION__MAX_FRAME_COUNT |
PICTRS__MEDIA__ANIMATION__FORMAT |
|
PICTRS__MEDIA__ANIMATION__MAX_FILE_SIZE |
旧 TOML 值 | 新 TOML 值 |
---|---|
[media.gif]max_width |
[media.animation]max_width |
[media.gif]max_height |
[media.animation]max_height |
[media.gif]max_area |
[media.animation]max_area |
[media.gif]max_file_size |
[media.animation]max_file_size |
[media.gif]max_frame_count |
[media.animation]max_frame_count |
[media.animation]format |
|
[media.animation]max_file_size |
视频更改
旧环境变量 | 新环境变量 |
---|---|
PICTRS__MEDIA__ENABLE_SILENT_VIDEO |
PICTRS__MEDIA__VIDEO__ENABLE |
PICTRS__MEDIA__ENABLE_FULL_VIDEO |
PICTRS__MEDIA__VIDEO__ALLOW_AUDIO |
PICTRS__MEDIA__VIDEO_CODEC |
PICTRS__MEDIA__VIDEO__VIDEO_CODEC |
PICTRS__MEDIA__AUDIO_CODEC |
PICTRS__MEDIA__VIDEO__AUDIO_CODEC |
PICTRS__MEDIA__MAX_FRAME_COUNT |
PICTRS__MEDIA__VIDEO__MAX_FRAME_COUNT |
PICTRS__MEDIA__ENABLE_FULL_VIDEO |
PICTRS__MEDIA__VIDEO__ALLOW_AUDIO |
PICTRS__MEDIA__VIDEO__MAX_WIDTH |
|
PICTRS__MEDIA__VIDEO__MAX_HEIGHT |
|
PICTRS__MEDIA__VIDEO__MAX_AREA |
|
PICTRS__MEDIA__VIDEO__MAX_FILE_SIZE |
旧 TOML 值 | 新 TOML 值 |
---|---|
[media]enable_silent_video |
[media.video]enable |
[media]enable_full_video |
[media.video]allow_audio |
[media]video_codec |
[media.video]video_codec |
[media]audio_codec |
[media.video]audio_codec |
[media]max_frame_count |
[media.video]max_frame_count |
[media]enable_full_video |
[media.video]allow_audio |
[media.video]max_width |
|
[media.video]max_height |
|
[media.video]max_area |
|
[media.video]max_file_size |
请注意,尽管每种媒体类型现在都有自己的MAX_FILE_SIZE
配置,但PICTRS__MEDIA__MAX_FILE_SIZE
值仍然存在,作为任何文件类型的全局限制。
除了上述所有配置选项之外,现在还可以为每种图像和动画类型以及视频文件配置单独的质量设置。有关更多信息,请参阅pict-rs.toml文件。
直接升级到Postgres
pict-rs支持在升级期间直接迁移到postgres repo。为了执行此操作,需要配置postgres repo并指定old_repo
。该old_repo
部分仅包含您的0.4配置中repo
部分的path
。
示例
[old_repo]
path = '/mnt/sled-repo'
[repo]
type = 'postgres'
url = 'postgres://user:password@host:5432/db'
或使用环境变量
PICTRS__OLD_REPO__PATH=/mnt/sled-repo
PICTRS__REPO__TYPE=postgres
PICTRS__REPO__URL=postgres://user:password@host:5432/db
设置这些变量后,即可启动0.5并自动执行迁移。
文件系统到对象存储迁移
在运行此命令之前,请确保备份sled-repo目录!!!将迁移到对象存储会更新数据库,如果您需要因任何原因回滚,则需要备份。
可以迁移到对象存储。如果在云环境中托管,这可能很有用,因为对象存储通常比块存储便宜得多。
对象存储需要一些配置选项。我将尝试解释。
- 端点:这是对象存储可用的URL。通常这个URL看起来像这样
https://<bucket-name>.<region>.s3.example.com
,但有时它可能看起来像https://<region>.s3.example.com
或只是https://s3.example.com
- bucket-name:这是对象将驻留的“bucket”的名称。bucket必须已经存在,迁移才能工作 - pict-rs不会自己创建bucket。您需要提前使用存储提供商创建bucket。
- region:这是bucket所在的“位置”。根据您的云提供商,这可能没有意义,但它总是必需的。
- access-key:这是云提供商将为您提供以访问bucket的秘密。
- secret-key:这是云提供商将为您提供以访问bucket的第二个秘密。
此外,还有一个命令行参数可以设置以更改迁移的默认并发级别。pict-rs将尝试一次迁移32个散列,但对于大型部署,尝试增加此值可能是有益的。将其设置为128、256甚至512可能很有用。请注意,此值越大,对对象存储提供商的并发连接就越多。
命令看起来可能如下所示
$ pict-rs \
migrate-store \
--concurrency 32 \
filesystem \
-p /path/to/files \
object-storage \
-e https://object-storage-endpoint \
-b bucket-name \
-r region \
-a access-key \
-s secret-key \
sled \
-p /path/to/sled-repo
如果您使用默认路径运行docker容器,它可以简化为以下内容
$ pict-rs \
migrate-store \
filesystem \
object-storage \
-e https://object-storage-endpoint \
-b bucket-name \
-r region \
-a access-key \
-s secret-key
此命令必须在pict-rs离线时运行。
如果您使用docker-compose运行,它可能看起来如下所示
$ sudo docker compose stop pictrs # stop the pict-rs container
$ sudo docker compose run pictrs sh # launch a shell in the pict-rs container
> pict-rs --version # verify pict-rs version is recent (should probably be 0.4.0 or later)
> pict-rs \
migrate-store \
filesystem \
object-storage \
-e endpoint \
-b bucket \
-r region \
-a -access-key \
-s secret-key
> exit
$ vi docker-compose.yml # edit the docker-compose yaml however you like to edit it, make sure all the variables described below are set
$ sudo docker compose up -d pictrs # start pict-rs again after the migration. Note that this is not 'docker compose start'. using the `up` subcommand explicitly reloads configurations
根据您的docker或docker-compose版本,您可能需要使用以下命令打开shell
$ sudo docker-compose run -i pictrs sh
以下是基于我自己的对象存储的示例,我在kubernetes上自己托管,使用garage
$ pict-rs \
migrate-store \
filesystem \
object-storage \
--use-path-style \
-e http://garage-daemon.garage.svc:3900 \
-b pict-rs \
-r garage \
-a <redacted> \
-s <redacted>
以下是基于backblaze b2用户的配置示例;
$ pict-rs \
migrate-store \
filesystem \
object-storage \
--use-path-style \
-e https://s3.us-east-005.backblazeb2.com \
-r us-east-005 \
-b SitenamePictrs \
-a redacted \
-s redacted
迁移完成后,请更新pict-rs配置以使用对象存储。如果您使用环境变量配置,请确保以下设置
PICTRS__STORE__TYPE=object_storage
PICTRS__STORE__ENDPOINT=https://object-storage-endpoint
PICTRS__STORE__BUCKET_NAME=bucket-name
PICTRS__STORE__REGION=region
PICTRS__STORE__USE_PATH_STYLE=false
(如果您的对象存储需要路径样式访问,请将其设置为true)PICTRS__STORE__ACCESS_KEY=access-key
PICTRS__STORE__SECRET_KEY=secret-key
如果您使用配置文件,它将是这样的
[store]
type = "object_storage"
endpoint = "https://object-storage-endpoint"
bucket_name = "bucket-name"
region = "region"
use_path_style = false # Set to true if your object storage requires path style access
access_key = "access-key"
secret_key = "secret-key"
迁移故障排除
如果您在尝试启动迁移时看到如下错误
0: IO error: could not acquire lock on "/mnt/sled-repo/v0.4.0-alpha.1/db": Os { code: 11, kind: WouldBlock, message: "Resource temporarily unavailable" }
这意味着pict-rs无法打开其数据库。这可能是由于另一个pict-rs副本正在运行。在迁移之前,请确保停止所有运行的pict-rs进程。
如果您尝试迁移并看到“Failed moving file. Retrying +1”,请不要取消迁移。让它达到10次重试。之后将打印出更具有意义的错误。以下是一些错误及其原因的示例
错误
0: Error in store
1: Error in object store
2: Invalid status: 400 Bad Request
2: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Error>
<Code>InvalidRequest</Code>
<Message>Authorization header's Credential is malformed</Message>
</Error>
原因:区域设置不正确。另外,使用了路径样式端点而没有传递 --use-path-style
错误
0: Error in store
1: Error in object store
2: Invalid status: 403 Forbidden
2: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Error>
<Code>InvalidAccessKeyId</Code>
<Message>Malformed Access Key Id</Message>
</Error>
原因:access key设置不正确
如果您在将现有文件迁移到对象存储之前启用了对象存储,这些迁移命令可能会无限期地重试文件迁移。为了成功解决这个多存储问题,已在 --skip-missing-files
子命令中添加了标志。这将告诉 pict-rs 如果文件返回某种形式的“未找到”错误,则不要重试迁移该文件。
$ pict-rs \
migrate-store --skip-missing-files \
filesystem -p /path/to/files \
object-storage \
-e https://object-storage-endpoint \
-b bucket-name \
-r region \
-a access-key \
-s secret-key \
sled \
-p /path/to/sled-repo
如果您在使用 pict-rs 上传到对象存储时遇到问题,请检查以下事项:您的对象存储是否需要路径风格访问?一些对象存储提供商,如 Contabo,不支持虚拟托管存储桶。以下是一个基本示例
路径风格 URL:https://region.example.com/bucket-name
虚拟主机风格 URL:https://bucket-name.region.example.com
如果确实需要使用路径风格,您的命令可能看起来像这样
$ pict-rs \
migrate-store \
filesystem -p /path/to/files \
object-storage \
--use-path-style \
-e https://object-storage-endpoint \
-b bucket-name \
-r region \
-a access-key \
-s secret-key \
sled \
-p /path/to/sled-repo
此外,一些提供商可能要求您在端点 URL 中包含 region
:例如 https://region.host.com
,而其他提供商可能只需要顶级端点:例如 https://example.com
。
请检查对象存储提供商的文档,以确保您设置了正确的值。
Sled到Postgres迁移
如果您在没有迁移到 postgres 的情况下升级到 0.5,您可以使用内置的迁移工具事后迁移到 postgres。在运行迁移之前,请确保您为 pict-rs 准备了一个 postgres 角色和数据库名称。pict-rs 连接到新数据库时,首先要做的事情是尝试添加 pgcrypto
扩展,如果为 pict-rs 创建的角色没有这个权限,则迁移将失败。
迁移命令相当简单。只需要提供现有存储库的路径和新的存储库 URL。
$ pict-rs \
migrate-repo \
sled -p /path/to-/sled-repo \
postgres -u postgres://user:password@host:5432/db
如果您使用docker-compose运行,它可能看起来如下所示
$ sudo docker compose stop pictrs # stop the pict-rs container
$ sudo docker compose run pictrs sh # launch a shell in the pict-rs container
> pict-rs --version # verify pict-rs version is recent (should probably be 0.5.0 or later)
> pict-rs \
migrate-repo \
sled -p /mnt/sled-repo \
postgres -u postgres://user:password@host:5432/db
> exit
$ vi docker-compose.yml # edit the docker-compose yaml however you like to edit it, make sure all the variables described below are set
$ sudo docker compose up -d pictrs # start pict-rs again after the migration. Note that this is not 'docker compose start'. using the `up` subcommand explicitly reloads configurations
此命令必须在pict-rs离线时运行。
这次迁移应该相当快,因为没有实际文件被移动。迁移完成后,确保 pict-rs 配置为使用 postgres 存储库,然后重新启动。
示例
[repo]
type = 'postgres'
url = 'postgres://user:password@host:5432/db'
或
PICTRS__REPO__TYPE=postgres
PICTRS__REPO__URL=postgres://user:password@host:5432/db
开发
pict-rs 有一些需要安装才能正常运行的原生依赖项。目前这些如下
- imagemagick 7.1.1(尽管 7.0 和 7.1.0 也可能工作)
- ffmpeg 6(尽管 5 也可能工作)
- exiftool 12.62(尽管 12.50 或更新版本也可能工作)
此外,pict-rs 在编译步骤需要 protobuf 编译器以支持 tokio-console,这是一个运行时调试工具。
使用您喜欢的包管理器安装这些依赖项应该足够了。以下是开发和使用 pict-rs 二进制文件的几种有趣方式。
Nix开发
我本人使用 nix 进行开发。提供的 flake.nix
文件应该足以在安装 nix 的任何 Linux 发行版上创建 pict-rs 的开发环境。
使用direnv和nix-direnv
使用这些工具,在进入 pict-rs 目录时可以自动加载 pict-rs 开发环境。
设置(仅一次)
$ echo 'use flake' > .envrc
$ direnv allow
运行
$ cargo run -- -c dev.toml run
仅使用Nix
$ nix develop
$ cargo run -- -c dev.toml run
Docker开发
以前,我已经在包含正确依赖项的容器中运行 pict-rs。下面列出的两个选项是我亲自尝试过的。
使用Arch
此选项不需要太多配置,只需在容器内编译二进制文件并运行即可
$ cargo build
$ sudo docker run --rm -it -p 8080:8080 -v "$(pwd):/mnt" archlinux:latest
> pacman -Syu imagemagick ffmepg perl-image-exiftool
> PATH=$PATH:/usr/bin/vendor_perl /mnt/target/debug/pict-rs --log-targets debug run
使用Alpine
此选项需要安装 cargo-zigbuild
。Cargo Zigbuild 是一个工具,它使用 Zig 的链接器链接 Rust 二进制文件,从而可以轻松地针对许多目标进行交叉编译。Zig 在无缝交叉编译方面投入了大量努力,能够从 Rust 中利用这些工作非常令人高兴。
$ cargo zigbuild --target=x86_64-unknown-linux-musl
$ sudo docker run --rm -it -p 8080:8080 -v "$(pwd):/mnt" alpine:3.18
> apk add imagemagick ffmpeg exiftool
> /mnt/target/x86_64-unknown-linux-musl/debug/pict-rs --log-targets debug run
贡献
如果您发现任何问题,请随时提交问题。请注意,任何贡献的代码都将根据 AGPLv3 许可。
常见问题解答
问题:pict-rs 是否无状态?
回答:可以。默认情况下,pict-rs 使用磁盘存储文件以及名为 sled
的磁盘键值存储来存储元数据。这是为了便于小型配置的部署。如果需要 pict-rs 不保留任何本地状态(除 /tmp 外),可以配置它使用对象存储来存储文件和使用 Postgres 来存储元数据。
问题:我能否使用与 pict-rs 不同的数据库?
回答:可以。pict-rs 支持 sled
和 postgres
来存储元数据。将来我也可能支持 BonsaiDB
。如果您希望 pict-rs 支持其他数据库,请随意提交更改 :)
问题:我如何提交更改?
回答:如果您想为 pict-rs 做贡献,可以将您的代码推送到您选择的公共 git 主机,并通过 matrix 或电子邮件通知我。我可以从那里拉取和合并您的更改到这个仓库中。
或者,您也可以通过电子邮件将补丁发给我。
我不会在我的 forgejo 服务器上创建额外的账户,抱歉了。
问题:我想用 yaml 而不是 toml 来配置它?
回答:这不是一个问题,但您可以使用 json、hjson、yaml、ini 或 toml 来配置 pict-rs。将配置写入其他格式是留给读者的练习。
问题:我如何捐赠给 pict-rs?
回答:您不需要。我通过做其他工作来赚钱。不要给我不需要的钱。
常见问题
在某些情况下,pict-rs 可能会崩溃并且无法重新启动。最常见的原因是文件系统达到 100%,pict-rs 无法写入磁盘,但这也可能在不幸的时刻杀死 pict-rs 时发生。如果发生这种情况,解决方案是首先为您的服务器获取更多磁盘空间,然后查找 sled-repo
目录中的 pict-rs。很可能是 pict-rs 创建了一个名为 snap.somehash.generating
的零大小文件。删除该文件并重新启动 pict-rs。
当使用提供的 docker 容器运行时,pict-rs 可能会因为权限错误而无法启动,显示“权限被拒绝”的 I/O 错误。这很可能意味着 pict-rs 的卷不是由正确的用户拥有的。将 pict-rs 卷的所有权更改为 991:991
应该解决这个问题。
许可证
版权 © 2022 Riley Trautman
pict-rs 是自由软件:您可以在自由软件基金会发布的 GNU 通用公共许可证的条款下重新分配它和/或修改它,无论是许可证的第 3 版,还是(根据您的选择)任何后续版本。
pict-rs 是希望它会有用而发布的,但没有任何保证;甚至没有关于适销性或特定用途的隐含保证。有关详细信息,请参阅 GNU 通用公共许可证。本文件是 pict-rs 的一部分。
您应该已经随 pict-rs 收到了一份 GNU 通用公共许可证的副本。如果没有,请参阅 https://gnu.ac.cn/licenses/。
依赖项
~68MB
~1.5M SLoC