Lemmy 0.19.21 Docker Compose 部署指南
在一台 Ubuntu 服务器上以官方 Docker Compose 形态从 0 到 1 部署 Lemmy 0.19.21 联邦社区站(lemmy 后端 + lemmy-ui 前端 + Nginx 反向代理 + PostgreSQL + pict-rs 图片服务),完成配置、启动、自动建站与功能验证。
Lemmy 0.19.21 Docker Compose 部署指南
目标:在一台 Ubuntu 服务器上以官方 Docker Compose 形态从 0 到 1 部署 Lemmy 0.19.21 联邦社区站(lemmy 后端 + lemmy-ui 前端 + Nginx 反向代理 + PostgreSQL + pict-rs 图片服务),完成配置、启动、自动建站与功能验证。已在 Ubuntu 24.04 / Docker 29.9.2 环境实测通过。
一、环境信息
- 操作系统:Ubuntu 24.04.5 LTS(x86_64,6 核 CPU / 19GB 内存)
- Docker Engine:Docker version 29.9.2, build a82e528
- Docker Compose:Docker Compose version v5.6.1
- Lemmy 后端:dessalines/lemmy:0.19.21(当前最新稳定版,GitHub Releases Latest,2026-10-27 实查)
- Lemmy 前端:dessalines/lemmy-ui:0.19.21(与后端同版本号发布,需严格匹配)
- 图片服务:asonix/pictrs:0.5.16
- 数据库:pgautoupgrade/pgautoupgrade:16-alpine(PostgreSQL 16)
- 反向代理:nginx:1-alpine
- 部署目录:/opt/lemmy(本文统一使用该目录)
- 对外端口:8137(Web 入口)、127.0.0.1:8136(pict-rs 本机调试端口)
- 站点标识(hostname):lemmy.local(本地验证用占位域名,生产环境替换为你的真实域名)
二、镜像选型说明
官方部署模板(LemmyNet/lemmy 仓库 docker/ 目录)使用的五个镜像与版本如下:
| 镜像 | 版本 | 作用 | 选型依据 |
|---|---|---|---|
| dessalines/lemmy | 0.19.21 | 后端:REST API + ActivityPub | 官方主镜像,与前端同版本发布 |
| dessalines/lemmy-ui | 0.19.21 | 前端:服务端渲染 Web 界面 | 必须与后端版本一致,否则界面与 API 不匹配 |
| nginx:1-alpine | 1-alpine 滚动 tag | 统一入口反向代理 | 官方模板默认选择 |
| pgautoupgrade/pgautoupgrade | 16-alpine | PostgreSQL 数据库 | 官方模板默认选择,小版本自动升级特性 |
| asonix/pictrs | 0.5.16 | 图片上传/缩略图/图片代理 | 官方模板指定版本,0.5.x 支持图片代理模式 |
💡 技术拓展:PostgreSQL 官方镜像有
postgres:16-alpine与pgautoupgrade/pgautoupgrade:16-alpine两种常见选择——前者升级大版本需手工 dump/restore,后者启动时自动完成大版本数据目录升级。Lemmy 官方模板采用后者,本文沿用官方选择,避免数据库升级时的手工迁移。
⚠️ 注意:前后端版本必须成对升级(同 tag 拉取);混用不同版本(如后端 0.19.21 配前端 0.19.20)可能导致界面请求的 API 字段缺失。
三、前置条件
- 服务器已安装 Docker Engine 与 Compose 插件(本文实测版本见环境信息节);
- 服务器 8137 端口空闲、可访问(或自行选择其他空闲端口):
实测回显(部署机上 8137 未被占用):
ss -ltn | grep 8137 || echo "8137 空闲"8137 空闲 - 已规划站点域名:本地验证可用
lemmy.local占位并在访问机做 hosts 解析;生产环境用真实域名 + TLS 证书(tls_enabled改 true 后联邦才能跨实例工作); - 磁盘余量充足(本文实测五个镜像合计约 2.3GB,数据库与图片数据随使用增长);
- 如服务器在国内网络且拉取 Docker Hub 镜像缓慢,先阅读「十一、常见问题」11.5 的镜像拉取降级方案。
四、部署步骤
本节按官方模板的四个配置文件 + 一个编排文件组织,目录结构为:
/opt/lemmy/
├── docker-compose.yml
├── lemmy.hjson
├── nginx.conf
├── customPostgresql.conf
└── volumes/
├── pictrs/ # 图片数据
└── postgres/ # 数据库数据
4.1 创建目录与数据目录
mkdir -p /opt/lemmy/volumes/pictrs /opt/lemmy/volumes/postgres
chown -R 991:991 /opt/lemmy/volumes/pictrs
pict-rs 容器内以 UID 991 运行(官方模板 user: 991:991),数据目录必须提前赋予该属主,否则图片服务启动即报权限错误(排障实录见 11.4)。执行后确认:
ls -la /opt/lemmy/volumes/
实测回显:
total 16
drwxr-xr-x 4 root root 4096 Oct 27 00:35 .
drwxr-xr-x 3 root root 4096 Oct 27 00:35 ..
drwxr-xr-x 2 systemd-resolve systemd-resolve 4096 Oct 27 00:35 pictrs
drwxr-xr-x 2 root root 4096 Oct 27 00:35 postgres
💡 说明:
systemd-resolve是宿主机恰好占用 UID 991 的系统账号,与 pict-rs 容器内991:991是同一数字身份,属正常现象。
4.2 编排文件 docker-compose.yml
创建 /opt/lemmy/docker-compose.yml(官方模板形态,固定项目名与网段):
x-logging: &default-logging
driver: "json-file"
options:
max-size: "50m"
max-file: "4"
name: lemmy-0.19.21-stack
networks:
lemmy-net:
driver: bridge
ipam:
config:
- subnet: 10.89.66.0/24
services:
proxy:
image: nginx:1-alpine
container_name: lemmy-0.19.21-proxy
ports:
# 对外唯一入口:宿主 8137 -> 反向代理 1236
- "8137:1236"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
restart: unless-stopped
depends_on:
- pictrs
- lemmy-ui
networks:
- lemmy-net
logging: *default-logging
lemmy:
image: dessalines/lemmy:0.19.21
container_name: lemmy-0.19.21-api
hostname: lemmy
restart: unless-stopped
environment:
- RUST_LOG=warn
volumes:
- ./lemmy.hjson:/config/config.hjson:ro
depends_on:
- postgres
- pictrs
networks:
- lemmy-net
logging: *default-logging
lemmy-ui:
image: dessalines/lemmy-ui:0.19.21
container_name: lemmy-0.19.21-ui
environment:
# 与 lemmy 服务的 hostname 保持一致
- LEMMY_UI_LEMMY_INTERNAL_HOST=lemmy:8536
# 对外访问地址:访问者实际使用的地址+端口
- LEMMY_UI_LEMMY_EXTERNAL_HOST=localhost:8137
# 本地无 TLS 时必须为 false,否则登录态 Cookie 无法在 HTTP 下保存
- LEMMY_UI_HTTPS=false
depends_on:
- lemmy
restart: unless-stopped
init: true
networks:
- lemmy-net
logging: *default-logging
pictrs:
image: asonix/pictrs:0.5.16
container_name: lemmy-0.19.21-pictrs
hostname: pictrs
environment:
- PICTRS__SERVER__API_KEY=q1w2e3r4
- PICTRS__MEDIA__VIDEO_CODEC=vp9
- PICTRS__MEDIA__GIF__MAX_WIDTH=256
- PICTRS__MEDIA__GIF__MAX_HEIGHT=256
- PICTRS__MEDIA__GIF__MAX_AREA=65536
- PICTRS__MEDIA__GIF__MAX_FRAME_COUNT=400
- RUST_LOG=info
user: 991:991
ports:
# 调试用可选映射:仅本机可直连 pictrs 原生接口(0.5.x 原生端口 8080)
- "127.0.0.1:8136:8080"
volumes:
- ./volumes/pictrs:/mnt
restart: unless-stopped
networks:
- lemmy-net
logging: *default-logging
postgres:
image: pgautoupgrade/pgautoupgrade:16-alpine
container_name: lemmy-0.19.21-postgres
hostname: postgres
command: postgres -c config_file=/etc/postgresql.conf
environment:
- POSTGRES_USER=lemmy
- POSTGRES_PASSWORD=q1w2e3r4
- POSTGRES_DB=lemmy
volumes:
- ./volumes/postgres:/var/lib/postgresql/data
- ./customPostgresql.conf:/etc/postgresql.conf:ro
restart: unless-stopped
networks:
- lemmy-net
logging: *default-logging
关键点解读:
name: lemmy-0.19.21-stack显式固定 Compose 项目名,避免与其他项目目录同名导致互相覆盖;- 网段显式声明
10.89.66.0/24(按服务器实际空闲网段调整,避免与已有网络冲突,排障见 11.1); - 对外只暴露 proxy 的 8137 一个端口;数据库与 pict-rs 均不对外,pict-rs 仅绑定本机回环 8136 供调试;
restart: unless-stopped兜底后端启动时数据库未就绪的重试(见 11.3)。
4.3 站点配置 lemmy.hjson
创建 /opt/lemmy/lemmy.hjson:
{
setup: {
admin_username: "admin"
admin_password: "q1w2e3r4adm"
site_name: "Lemmy 0.19.21 实测站"
}
database: {
host: postgres
password: "q1w2e3r4"
}
hostname: "lemmy.local"
bind: "0.0.0.0"
port: 8536
tls_enabled: false
pictrs: {
url: "http://pictrs:8080/"
api_key: "q1w2e3r4"
image_mode: StoreLinkPreviews
}
}
逐项说明:
setup:仅首次启动生效。站点未创建时,后端启动过程中自动以该账号创建管理员(admin)与站点(site_name),等价于在网页上完成「创建站点向导」;admin_password:Lemmy 密码策略为 10–60 字符(官方defaults.hjson注释原文),不足 10 位注册与建站均被拒(实测报invalid_password,见 11.8);database.host: postgres:即编排内的 postgres 服务名;password与编排文件POSTGRES_PASSWORD一致;hostname:站点对外标识,决定生成的对象地址(实测站点actor_id为http://lemmy.local/、社区地址形如http://lemmy.local/c/technews),生产环境必须替换为真实域名;tls_enabled: false:本地 HTTP 验证场景;生产启用 HTTPS 后改为true(联邦要求 true);pictrs.url指向 pict-rs 服务名与原生端口 8080;api_key与编排文件PICTRS__SERVER__API_KEY一致,删除图片时需要;image_mode: StoreLinkPreviews为外链帖子生成并持久化缩略图。
4.4 反向代理配置 nginx.conf
创建 /opt/lemmy/nginx.conf(与官方模板 docker/nginx.conf 一致):
worker_processes 1;
events {
worker_connections 1024;
}
http {
upstream lemmy {
# this needs to map to the lemmy (server) docker service hostname
server "lemmy:8536";
}
upstream lemmy-ui {
# this needs to map to the lemmy-ui docker service hostname
server "lemmy-ui:1234";
}
server {
# this is the port inside docker, not the public one yet
listen 1236;
listen 8536;
# change if needed, this is facing the public web
server_name localhost;
server_tokens off;
gzip on;
gzip_types text/css application/javascript image/svg+xml;
gzip_vary on;
# Upload limit, relevant for pictrs
client_max_body_size 20M;
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
# frontend general requests
location / {
# distinguish between ui requests and backend
# don't change lemmy or lemmy-ui here, they refer to the upstream definitions on top
set $proxpass "http://lemmy-ui";
if ($http_accept = "application/activity+json") {
set $proxpass "http://lemmy";
}
if ($http_accept = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"") {
set $proxpass "http://lemmy";
}
if ($request_method = POST) {
set $proxpass "http://lemmy";
}
proxy_pass $proxpass;
rewrite ^(.+)/+$ $1 permanent;
# Send actual client IP upstream
proxy_set_header X-Forwarded-For $remote_addr;
}
# backend
location ~ ^/(api|pictrs|feeds|nodeinfo|version|.well-known) {
proxy_pass "http://lemmy";
# proxy common stuff
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Send actual client IP upstream
proxy_set_header X-Forwarded-For $remote_addr;
}
}
}
分流逻辑解读:普通页面请求交给前端(lemmy-ui:1234);带 application/activity+json 头的请求(联邦抓取)、POST 请求与 /api、/pictrs、/feeds、/nodeinfo、/version、/.well-known 前缀请求转给后端(lemmy:8536)。client_max_body_size 20M 限制图片上传体积。
4.5 数据库配置 customPostgresql.conf
创建 /opt/lemmy/customPostgresql.conf(与官方模板一致,保持极简):
# You can use https://pgtune.leopard.in.ua to tune this for your system.
# Listen address
listen_addresses = '*'
# Logging
session_preload_libraries = auto_explain
auto_explain.log_min_duration = 5ms
auto_explain.log_analyze = true
auto_explain.log_triggers = true
track_activity_query_size = 1048576
说明:listen_addresses = '*' 允许编排网络内其他服务连接;auto_explain 系列把超过 5ms 的慢查询连同执行计划记入日志,track_activity_query_size 扩大查询文本追踪长度,均服务于慢查询排障,可按官方注释引导用 pgtune 做机型化调优。
4.6 启动与自动建站
cd /opt/lemmy
docker compose up -d
实测回显(首次启动,数据库需初始化):
[+] Running 7/7
✔ Network lemmy-01921-stack_lemmy-net Created
✔ Container lemmy-0.19.21-postgres Healthy
✔ Container lemmy-0.19.21-pictrs Started
✔ Container lemmy-0.19.21-api Started
✔ Container lemmy-0.19.21-ui Started
✔ Container lemmy-0.19.21-proxy Started
后端首次启动会自动执行数据库迁移并按 setup 段建站,日志可见(docker logs lemmy-0.19.21-api):
Lemmy v0.19.21
Federation enabled, host is lemmy.local
Starting HTTP server at 0.0.0.0:8536
4.7 部署验证
服务状态:
docker compose ps
实测回显:
NAME STATUS PORTS
lemmy-0.19.21-api Up 45 seconds 8536/tcp
lemmy-0.19.21-pictrs Up 46 seconds 6669/tcp, 127.0.0.1:8136->8080/tcp
lemmy-0.19.21-postgres Up 46 seconds (healthy) 5432/tcp
lemmy-0.19.21-proxy Up 6 seconds 80/tcp, 0.0.0.0:8137->1236/tcp, [::]:8137->1236/tcp
lemmy-0.19.21-ui Up 6 seconds (healthy) 1234/tcp
首页探活:
curl -s -o /dev/null -w 'GET / -> %{http_code}\n' http://localhost:8137/
实测回显:
GET / -> 200
站点 API 自检(确认自动建站成功、返回站点名与联邦开关):
curl -s http://localhost:8137/api/v3/site | python3 -c "import json,sys;s=json.load(sys.stdin)['site_view'];print('name=',s['site']['name'],'actor_id=',s['site']['actor_id']);ls=s['local_site'];print('federation_enabled=',ls['federation_enabled'],'registration_mode=',ls['registration_mode'])"
实测回显:
name= Lemmy 0.19.21 实测站 actor_id= http://lemmy.local/
federation_enabled= True registration_mode= RequireApplication
版本自检(/version 会 307 跳转到 nodeinfo,跟随重定向取版本):
curl -sL http://localhost:8137/version | python3 -c "import json,sys;d=json.load(sys.stdin);print(d['software']['name'],d['software']['version'])"
实测回显:
lemmy 0.19.21
前端版本自检:
docker logs lemmy-0.19.21-ui 2>&1 | head -1
实测回显:
Lemmy-ui v0.19.21 started listening on http://0.0.0.0:1234
浏览器访问 http://服务器IP:8137,用 admin 与 lemmy.hjson 中的 admin_password 登录即可进入管理界面。
五、数据持久化说明
全部状态数据落在编排目录的 volumes/ 子目录(bind mount 到宿主机):
| 目录 | 内容 | 备份方式 |
|---|---|---|
| volumes/postgres | 全部业务数据(用户/社区/帖子/评论/投票/联邦状态) | pg_dump 或停机拷贝目录 |
| volumes/pictrs | 用户上传的图片与缩略图 | 直接 rsync/tar 目录 |
数据库逻辑备份(推荐日常执行):
docker exec lemmy-0.19.21-postgres pg_dump -U lemmy lemmy > /opt/lemmy/backup/lemmy-$(date +%F).sql
重建站点时,删除两个 volumes 子目录即可回到初始状态(首次启动重新迁移建站)。
六、环境变量表
编排文件中可通过环境变量调整的运行参数(全部为实测使用的取值):
| 变量 | 所属服务 | 实测取值 | 说明 |
|---|---|---|---|
| RUST_LOG | lemmy | warn | 后端日志级别,排障时可改 debug |
| LEMMY_UI_LEMMY_INTERNAL_HOST | lemmy-ui | lemmy:8536 | 前端访问后端的内网地址(服务名:端口) |
| LEMMY_UI_LEMMY_EXTERNAL_HOST | lemmy-ui | localhost:8137 | 浏览器实际访问的地址:端口,影响界面生成的链接与登录跳转 |
| LEMMY_UI_HTTPS | lemmy-ui | false | 与站点实际 TLS 一致;HTTP 部署必须 false,否则登录 Cookie 不保存 |
| PICTRS__SERVER__API_KEY | pictrs | q1w2e3r4 | pict-rs 管理 API 口令,需与 lemmy.hjson 的 pictrs.api_key 一致 |
| PICTRS__MEDIA__VIDEO_CODEC | pictrs | vp9 | 视频缩略图编码 |
| PICTRS__MEDIA__GIF__MAX_WIDTH/HEIGHT/AREA/MAX_FRAME_COUNT | pictrs | 256/256/65536/400 | GIF 转码上限(官方模板默认值) |
| RUST_LOG(pictrs) | pictrs | info | pict-rs 日志级别 |
| POSTGRES_USER / POSTGRES_PASSWORD / POSTGRES_DB | postgres | lemmy / q1w2e3r4 / lemmy | 数据库初始化凭据,需与 lemmy.hjson 的 database 段一致 |
💡 技术拓展:pictrs 环境变量采用「双下划线表示层级」的约定(如
PICTRS__SERVER__API_KEY对应配置树server.api_key),这是 Rust config 库的通用风格,与 Lemmy 自身的LEMMY_UI_*平铺风格不同,配置时注意区分。
七、配置参数说明
lemmy.hjson 是 Lemmy 的主配置文件(挂载到后端 /config/config.hjson),本节仅列部署必需项,全部参数的逐项详解在配置篇展开。
| 参数 | 部署阶段取值 | 作用 |
|---|---|---|
| hostname | lemmy.local(生产换真实域名) | 站点对外标识,决定全部对象 URL 与 webfinger |
| setup.* | admin / q1w2e3r4adm / 站点名 | 仅首次启动建站生效 |
| database.host / password | postgres / q1w2e3r4 | 数据库连接 |
| bind / port | 0.0.0.0 / 8536 | 后端监听(编排内) |
| tls_enabled | false(生产 true) | 是否按 HTTPS 生成链接;联邦要求 true |
| pictrs.url / api_key / image_mode | http://pictrs:8080/ / q1w2e3r4 / StoreLinkPreviews | 图片服务对接 |
修改配置后需重启后端服务生效(重启方式见部署形态对应的运维命令节)。
八、配置文件挂载
| 宿主文件 | 挂载点 | 读写 |
|---|---|---|
| /opt/lemmy/lemmy.hjson | /config/config.hjson(lemmy) | ro 只读 |
| /opt/lemmy/nginx.conf | /etc/nginx/nginx.conf(proxy) | ro 只读 |
| /opt/lemmy/customPostgresql.conf | /etc/postgresql.conf(postgres) | ro 只读 |
| /opt/lemmy/volumes/pictrs | /mnt(pictrs) | 读写(属主 991:991) |
| /opt/lemmy/volumes/postgres | /var/lib/postgresql/data(postgres) | 读写 |
核对挂载是否生效:
docker compose config | grep -A2 'source: /opt/lemmy'
⚠️ 注意:四个配置文件均为只读挂载,修改宿主文件后必须重启对应服务才能生效;数据目录为读写挂载,禁止在服务运行时手工移动或改属主(pictrs 属主问题见 11.4)。
九、等价 docker run
以下给出与编排文件等价的逐服务启动命令(仅供理解组件关系或临时调试,推荐仍用 Compose 管理)。先创建网络:
docker network create --subnet 10.89.66.0/24 lemmy-net
数据库(先启动,供后端连接):
docker run -d --name lemmy-0.19.21-postgres --hostname postgres --network lemmy-net \
-v /opt/lemmy/volumes/postgres:/var/lib/postgresql/data \
-v /opt/lemmy/customPostgresql.conf:/etc/postgresql.conf:ro \
-e POSTGRES_USER=lemmy -e POSTGRES_PASSWORD=q1w2e3r4 -e POSTGRES_DB=lemmy \
--restart unless-stopped \
pgautoupgrade/pgautoupgrade:16-alpine postgres -c config_file=/etc/postgresql.conf
图片服务:
docker run -d --name lemmy-0.19.21-pictrs --hostname pictrs --network lemmy-net \
--user 991:991 \
-v /opt/lemmy/volumes/pictrs:/mnt \
-p 127.0.0.1:8136:8080 \
-e PICTRS__SERVER__API_KEY=q1w2e3r4 \
-e RUST_LOG=info \
--restart unless-stopped \
asonix/pictrs:0.5.16
后端(挂载主配置):
docker run -d --name lemmy-0.19.21-api --hostname lemmy --network lemmy-net \
-v /opt/lemmy/lemmy.hjson:/config/config.hjson:ro \
-e RUST_LOG=warn \
--restart unless-stopped \
dessalines/lemmy:0.19.21
前端(指向后端与对外地址):
docker run -d --name lemmy-0.19.21-ui --network lemmy-net --init \
-e LEMMY_UI_LEMMY_INTERNAL_HOST=lemmy:8536 \
-e LEMMY_UI_LEMMY_EXTERNAL_HOST=localhost:8137 \
-e LEMMY_UI_HTTPS=false \
--restart unless-stopped \
dessalines/lemmy-ui:0.19.21
反向代理入口(对外唯一端口):
docker run -d --name lemmy-0.19.21-proxy --network lemmy-net \
-v /opt/lemmy/nginx.conf:/etc/nginx/nginx.conf:ro \
-p 8137:1236 \
--restart unless-stopped \
nginx:1-alpine
十、常用运维命令
以下命令均在 /opt/lemmy 目录执行。
服务状态与资源:
docker compose ps
docker compose top
日志查看(排障首选):
docker compose logs --tail 100 lemmy
docker compose logs -f lemmy-ui
重启单个服务(改配置后):
docker compose restart lemmy
整体停止与启动:
docker compose stop
docker compose start
彻底拆除(保留 volumes 数据目录):
docker compose down
版本升级(示例从 0.19.21 升级到未来版本,先备份再升级):
# 1. 备份数据库与图片目录
# 2. 修改 docker-compose.yml 与镜像 tag(前后端同步改新版本号)
# 3. 拉取新镜像并滚动升级
docker compose pull
docker compose up -d
十一、常见问题(实测排障实录)
以下问题均在本机部署实测中真实发生,现象与解决照录。
11.1 编排网段冲突
现象:docker compose up 报错:
failed to create network lemmy-01921-stack_lemmy-net: Error response from daemon: invalid pool request: Pool overlaps with other one on this address space
定位与解决:查看现有网络占用网段,改用空闲网段(本例原计划 10.89.65.0/24 已被其他业务占用,改为 10.89.66.0/24):
docker network inspect $(docker network ls -q) --format '{{.Name}} {{range .IPAM.Config}}{{.Subnet}}{{end}}'
修改 docker-compose.yml 的 subnet 后重新 docker compose up -d。
11.2 对外端口被占用
现象:proxy 启动失败:
Error response from daemon: failed to set up container networking: ... Bind for 0.0.0.0:8135 failed: port is already allocated
解决:用 ss -ltn 排查宿主机端口占用,换一个空闲端口(本例从 8135 改为 8137),同步修改 ports 映射与 LEMMY_UI_LEMMY_EXTERNAL_HOST 后 docker compose up -d 重建 proxy。
11.3 后端首启报数据库连接失败
现象:docker logs lemmy-0.19.21-api 首次启动出现:
Lemmy v0.19.21
Error: LemmyError { message: Unknown("Error connecting to database"), inner: Error connecting to database
Caused by:
connection to server at "postgres" (10.89.66.2), port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
原因:首次启动时 PostgreSQL 需要初始化数据目录,后端早于数据库就绪发起连接。处理:restart: unless-stopped 会自动重启后端,几秒后日志出现 Federation enabled, host is lemmy.local 与 Starting HTTP server at 0.0.0.0:8536 即为正常;无需人工干预。
11.4 pictrs 图片目录权限错误
现象:把 volumes/pictrs 目录改为 root 属主后重启 pictrs,服务启动失败,日志末尾:
Error:
0: Error in database
1: IO error: Permission denied (os error 13)
原因:pictrs 以 user: 991:991 运行,数据目录(含其内部数据库文件)必须归 991 所有。解决:
docker compose stop pictrs
chown -R 991:991 /opt/lemmy/volumes/pictrs
docker compose up -d pictrs
修复后健康检查通过:
curl -s http://127.0.0.1:8136/healthz -w ' http_code=%{http_code}\n'
实测回显:
http_code=200
11.5 镜像拉取缓慢或超时
实测现象:docker pull 长时间停在 Pulling fs layer(550 秒超时无进度);切换国内镜像加速器后部分镜像返回 this image is not in the allowlist(不在该加速器白名单)。处理链路:官方源超时 → 更换加速器 → 仍失败则改用 HTTP 代理手动下载镜像层再 docker load 导入(本机代理环境变量示例 export https_proxy=http://<代理地址>:<端口>,按实际网络填写)。导入成功后 docker images 可见目标镜像,再正常 docker compose up -d。
11.6 HTTP 部署无法保持登录
原因:lemmy-ui 的登录 Cookie 依 LEMMY_UI_HTTPS 生成 Secure 属性。本地 HTTP 验证环境必须设 LEMMY_UI_HTTPS=false(本文 4.2 编排文件已如此配置,实测 admin 登录正常);生产启用 HTTPS 时改回 true。
11.7 访问地址与前端配置不一致
现象:浏览器打不开页面或界面请求 404。定位:LEMMY_UI_LEMMY_EXTERNAL_HOST 必须与「浏览器实际访问的地址:端口」一致(本文为 localhost:8137)。若用服务器 IP 或域名访问,需相应修改该变量并重建前端服务。
11.8 管理员密码不足 10 位
现象:把 setup.admin_password 设为 8 位口令(如 q1w2e3r4),注册与建站被拒,API 返回:
{"error":"invalid_password"}
解决:密码取 10–60 字符(官方 defaults.hjson 中 admin_password 注释原文约定),本文实测采用 q1w2e3r4adm(10 位)。
十二、参考链接
- 官方 Docker 安装文档:https://join-lemmy.org/docs/en/administration/install_docker.html
- 官方编排模板(0.19.21 标签):https://github.com/LemmyNet/lemmy/blob/0.19.21/docker/docker-compose.yml
- 官方 Nginx 模板:https://github.com/LemmyNet/lemmy/blob/0.19.21/docker/nginx.conf
- pict-rs 项目仓库:https://git.asonix.dog/asonix/pict-rs
- pgautoupgrade 镜像说明:https://github.com/ruanbekker/pgautoupgrade
- Lemmy 配置文档:https://join-lemmy.org/docs/en/administration/configuration.html