Kinto 26.5.0 Docker Compose 部署指南

Kinto 26.5.0 Docker Compose 部署指南:web+PostgreSQL+Memcached 三服务栈的部署文件、kinto.ini 定制、启动与健康验证、admin 账号与 Admin UI、数据持久化备份,及监听地址等排障实录。

KintoKinto文件传输文件服务器2026/10/30

Kinto 26.5.0 Docker Compose 部署指南

一、部署形态与环境规划

1.1 形态决策

Kinto 官方提供三种安装路径:Docker 镜像(kinto/kinto-server)、Python 包(pip install kinto)与源码构建。本文按官方推荐的 Docker Compose 范式部署——官方仓库的 docker-compose.yml 样例由三个服务组成:web(Kinto 本体)、db(PostgreSQL 14,持久化存储)、cache(Memcached,缓存后端)。默认镜像内置配置把存储/权限/缓存都指向内存后端,重启即丢数据,因此生产可用形态必须外接 PostgreSQL 与 Memcached,这正是官方 compose 样例的存在意义。

💡 技术拓展:Kinto 的三后端指 storage(记录持久化)、cache(缓存与会话状态)、permission(权限 ACL 存储)三类可插拔组件,见《Kinto 26.5.0 介绍与选型指南》第二节。三后端可以各自指向不同实现,本文按官方样例统一收敛到"PostgreSQL 存数据 + Memcached 做缓存 + PostgreSQL 存权限"。

1.2 环境前置

本次实测环境(2026-10-30):

项值
操作系统Linux(5.15 内核)
Docker29.9.2
Docker Composev5.6.1
Kinto 镜像kinto/kinto-server:26.5.0(351MB)
PostgreSQL 镜像postgres:14(629MB)
Memcached 镜像memcached:1(129MB)
对外端口8149(映射服务 8888 端口,部署前用 ss -ltn 确认空闲)
专用网络kinto-26.5.0-net,显式子网 10.89.57.0/24,与宿主机上其他业务网段隔离

版本口径说明:镜像 tag 为 26.5.0,对应 GitHub Releases 上的 26.5.0(查询日期 2026-10-30);官方镜像内 pip show kinto 与 kinto version 显示 0.0.0,这是官方镜像构建流程不回填版本元数据的已知现象,不影响功能,以镜像 tag 为准。

镜像拉取(Docker Hub 直连慢时挂代理):

docker pull kinto/kinto-server:26.5.0
docker pull postgres:14
docker pull memcached:1

⚠️ 网络说明:本环境直连 Docker Hub 超时,实测走代理 192.168.1.72:7897 后三个镜像均正常拉取;若代理地址不可用,可换用国内镜像加速器。

二、编写部署文件

2.1 项目目录结构

/opt/kinto/
├── docker-compose.yml      # 部署栈定义
├── config/
│   └── kinto.ini           # 自定义服务配置(挂载进 web 服务)
└── data/
    └── db/                 # PostgreSQL 数据落盘目录(自动生成)

2.2 docker-compose.yml 全文

name: kinto-26.5.0-stack

services:
  db:
    image: postgres:14
    container_name: kinto-26.5.0-db
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: postgres
    volumes:
      - ./data/db:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "postgres"]
      interval: 5s
      timeout: 5s
      retries: 5
    restart: unless-stopped

  cache:
    image: memcached:1
    container_name: kinto-26.5.0-cache
    command: -m 64
    restart: unless-stopped

  web:
    image: kinto/kinto-server:26.5.0
    container_name: kinto-26.5.0-web
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    ports:
      - "8149:8888"
    volumes:
      - ./config:/etc/kinto
    environment:
      KINTO_INI: /etc/kinto/kinto.ini
    restart: unless-stopped

networks:
  default:
    name: kinto-26.5.0-net
    driver: bridge
    ipam:
      config:
        - subnet: 10.89.57.0/24

逐段解说:

  • 显式项目名 name: kinto-26.5.0-stack:官方 Dockerfile 定义 web 服务的启动命令为 kinto migrate && kinto start,首次启动自动建表;显式项目名避免与其他 compose 项目冲突,也便于按名整栈管理;
  • db 健康检查:pg_isready 就绪后才启动 web,防止 Kinto 先于数据库启动导致迁移失败;数据通过 ./data/db 实现宿主机持久化;
  • cache 限内存:-m 64 把 Memcached 内存上限压到 64MB,缓存服务按官方样例不落盘、重启可丢;
  • web 端口映射:宿主机 8149 → 服务 8888(Kinto 默认监听端口);
  • 自定义配置注入:./config:/etc/kinto 加 KINTO_INI 环境变量,这是官方文档给出的"Custom configuration file"标准做法——镜像默认配置有监听地址陷阱,必须替换(见 2.3 与第七节排障实录)。

2.3 生成并定制 kinto.ini

Kinto 的配置是单个 INI 文件。用官方镜像自带 CLI 生成一份针对 PostgreSQL + Memcached 的初始配置(在 compose 项目目录执行,生成结果落到宿主机 ./config/):

docker compose run --rm -v "$PWD/config:/out" --entrypoint sh web -c 'kinto init --ini /out/kinto.ini --host 0.0.0.0 --backend postgresql --cache-backend memcached'

实测回显:

INFO   Created config /out/kinto.ini

kinto init 各参数:--host 0.0.0.0 让服务监听所有网卡(必须显式指定,默认值 127.0.0.1 会导致端口映射后无法访问,见第七节);--backend postgresql 指定存储/权限后端;--cache-backend memcached 指定缓存后端。生成后需要手工改三处:

# 1. 存储后端指向 compose 网络内的 db 服务(默认模板写的是 localhost)
kinto.storage_url = postgresql://postgres:postgres@db/postgres
# 2. 权限后端同样指向 db
kinto.permission_url = postgresql://postgres:postgres@db/postgres
# 3. 缓存后端:模板把 Memcached 地址写进了 kinto.cache_url 键,
#    但 Memcached 后端实际读取的是 kinto.cache_hosts,必须手工改名
kinto.cache_hosts = cache:11211

完整配置文件关键段落(kinto init 生成的原文节选,# 注释保留):

[server:main]
use = egg:waitress#main
host = 0.0.0.0
port = %(http_port)s

[app:main]
use = egg:kinto

# Plugins
kinto.includes = kinto.plugins.default_bucket
                 kinto.plugins.admin
                 kinto.plugins.accounts
#                kinto.plugins.history

# Backends
kinto.storage_backend = kinto.core.storage.postgresql
kinto.storage_url = postgresql://postgres:postgres@db/postgres
kinto.cache_backend = kinto.core.cache.memcached
kinto.cache_hosts = cache:11211
kinto.permission_backend = kinto.core.permission.postgresql
kinto.permission_url = postgresql://postgres:postgres@db/postgres

# Authentication
kinto.userid_hmac_secret = 21a00c06abffd4d4d161ff762a8dc42b48b5e1f32a5462a1892d1013cd95eb53
multiauth.policies = account

# Bucket ID salt
kinto.default_bucket_hmac_secret = b4bd4fcf4bfd2b04e003117c27eef6b8e80fa5c8bcf873a58c6d08f71f8236fc

# Accounts API configuration
multiauth.policy.account.use = kinto.plugins.accounts.AccountsPolicy
# Allow anyone to create accounts.
kinto.account_create_principals = system.Everyone
# Set user 'account:admin' as the administrator.
kinto.account_write_principals = account:admin
# Allow administrators to create buckets
kinto.bucket_create_principals = account:admin

两个 *_hmac_secret 是 kinto init 随机生成的密钥(分别用于用户 ID 哈希与默认桶 ID 派生),一经投入使用不可更换,否则旧用户身份与默认桶映射全部错位;多实例部署时所有实例必须使用同一份密钥。配置文件所有参数域的逐一解释见《Kinto 26.5.0 配置参数详解》。

三、启动部署栈

3.1 启动

docker compose up -d

实测回显(-d 后台启动,db 等待健康检查通过后 web 才启动):

[+] Running 5/5
 ✔ Network kinto-26.5.0-net         Created
 ✔ Container kinto-26.5.0-cache     Started
 ✔ Container kinto-26.5.0-db        Healthy
 ✔ Container kinto-26.5.0-web       Started

3.2 状态核验

docker compose ps

实测回显:

NAME                 IMAGE                       COMMAND                  SERVICE   CREATED         STATUS                   PORTS
kinto-26.5.0-cache   memcached:1                 "docker-entrypoint.s…"   cache     8 minutes ago   Up 8 minutes             11211/tcp
kinto-26.5.0-db      postgres:14                 "docker-entrypoint.s…"   db        8 minutes ago   Up 8 minutes (healthy)   5432/tcp
kinto-26.5.0-web     kinto/kinto-server:26.5.0   "sh -c 'kinto migrat…"   web       8 minutes ago   Up 8 minutes             0.0.0.0:8149->8888/tcp, [::]:8149->8888/tcp

三个服务全部 Up,db 带 (healthy) 标记,web 的 8149→8888 映射就绪。PostgreSQL 与 Memcached 端口未对宿主机暴露,仅在专用网络内部可达,这是有意为之。

3.3 启动日志解读

docker compose logs web

实测回显(节选,已略去无害警告行):

INFO   Running kinto 0.0.0.
INFO   Detected PostgreSQL storage schema version 26.
INFO   PostgreSQL storage schema is up-to-date.
INFO   Detected PostgreSQL permission schema version 2.
INFO   PostgreSQL permission schema is up-to-date.
Running kinto 0.0.0. rid=None
Starting server in PID 9.
Serving on http://0.0.0.0:8888 rid=None
"GET   /v1?" 200 (1 ms)  agent=curl/8.5.0 errno=0 rid=3635a67e-8af8-416e-88b2-602b08990d6c time=2026-10-30T08:06:53.707000

要点:web 服务每次启动先自动执行 kinto migrate——首次启动把 PostgreSQL 存储模式建到 schema version 26、权限模式建到 schema version 2,之后启动显示 up-to-date;随后 waitress 监听 0.0.0.0:8888 并开始记录访问日志(每行含请求 ID、耗时、User-Agent)。

四、服务健康验证

4.1 根视图(hello)

curl -s http://127.0.0.1:8149/v1/

实测回显:

{
    "project_name": "kinto",
    "project_version": "0.0.0",
    "http_api_version": "1.23",
    "project_docs": "https://kinto.readthedocs.io/",
    "url": "http://127.0.0.1:8149/v1/",
    "config": {
        "path": "/etc/kinto/kinto.ini",
        "hash": "502807b704fb0a4ae64d3efd4295394432775c5da9fe2140f564f19fd788ad39",
        "modified": "2026-10-30T08:06:08.215283"
    },
    "settings": {
        "explicit_permissions": true,
        "batch_max_requests": 25,
        "readonly": false
    },
    "capabilities": {
        "default_bucket": {"description": "The default bucket is an alias for a personal bucket where collections are created implicitly.", "url": "https://kinto.readthedocs.io/en/latest/api/1.x/buckets.html#personal-bucket-default"},
        "admin": {"description": "Serves the admin console.", "url": "https://github.com/Kinto/kinto-admin/", "version": "6.6.0"},
        "accounts": {"description": "Manage user accounts.", "url": "https://kinto.readthedocs.io/en/latest/api/1.x/accounts.html", "validation_enabled": false},
        "permissions_endpoint": {"description": "The permissions endpoint can be used to list all user objects permissions.", "url": "https://kinto.readthedocs.io/en/latest/configuration/settings.html#activating-the-permissions-endpoint"}
    }
}

根视图同时是能力自描述文档:capabilities 列出当前启用的插件(default_bucket/admin/accounts),http_api_version: 1.23 是 API 契约版本。返回的 url 字段即服务自认的对外地址,反代部署后若该值异常,需配置 kinto.http_scheme/kinto.http_host(见配置详解篇)。

4.2 心跳端点

curl -s http://127.0.0.1:8149/v1/__heartbeat__

实测回显:

{
    "storage": true,
    "permission": true,
    "cache": true
}

三个后端全部 true 才算健康,负载均衡健康检查建议直接指向此端点。

五、管理账号与 Admin UI

5.1 创建 admin 账号

默认配置启用了 accounts 插件,首个管理员账号通过 API 创建(密码哈希后入库,接口返回的是 bcrypt 串):

curl -s -X PUT http://127.0.0.1:8149/v1/accounts/admin -d '{"data": {"password": "q1w2e3r4"}}' -H "Content-Type:application/json"

实测回显:

{
    "permissions": {
        "write": ["account:admin"]
    },
    "data": {
        "password": "$2b$12$jrSO7FtobNAfYOWyQVS6GenoSjl0cWOtyIHWsebxcKbPw1OPeLBTe",
        "id": "admin",
        "last_modified": 1793347628888
    }
}

默认配置中 kinto.account_write_principals = account:admin 意味着只有 admin 能增删账号,kinto.account_create_principals = system.Everyone 允许匿名自助注册(生产收紧时改掉,见配置详解篇)。

5.2 鉴权核验

用 Basic 认证访问根视图,确认身份与主体(principals):

curl -s http://127.0.0.1:8149/v1/ -u admin:q1w2e3r4

实测回显(节选 user 字段):

{
  "user": {
    "id": "account:admin",
    "principals": ["account:admin", "system.Authenticated", "system.Everyone"],
    "bucket": "deaec1ea-8c0a-4584-d5fb-2ad9942e9161"
  }
}

bucket 字段是该用户个人默认桶的派生 ID(由 kinto.default_bucket_hmac_secret 对用户 ID 做 HMAC 得出)。

5.3 Admin UI

浏览器访问 http://<服务器地址>:8149/v1/admin/ 即打开内置的 Kinto Admin 管理界面(版本 6.6.0),以 admin/q1w2e3r4 登录后可视化操作桶/集合/记录与权限。Admin 资源由 web 服务直接托管,无需单独部署前端。

六、数据持久化与日常运维

6.1 数据落盘与备份

全部业务数据在 PostgreSQL 中,库内共 5 张表(存储/权限/元数据/时间戳/用户主体),实测 psql -U postgres -c "\dt":

                 List of relations
 Schema |          Name          | Type  |  Owner
--------+------------------------+-------+----------
 public | access_control_entries | table | postgres
 public | metadata               | table | postgres
 public | objects                | table | postgres
 public | timestamps             | table | postgres
 public | user_principals        | table | postgres
(5 rows)

数据经 bind mount 落在宿主机 ./data/db/,备份用标准 pg_dump 即可:

docker compose exec db pg_dump -U postgres postgres > kinto-backup-$(date +%F).sql

恢复时先 docker compose down,清空 ./data/db/ 后重启空库,再 psql -f 导入备份。

6.2 生命周期命令

docker compose stop      # 停栈(保留网络与存储)
docker compose start     # 复启
docker compose down      # 删栈(数据仍在 ./data/db/)
docker compose up -d     # 再建栈

升级版本:改 docker-compose.yml 中镜像 tag(如 26.5.0 → 下一版本),docker compose up -d 滚动重建,web 启动时自动执行 kinto migrate 完成数据库模式升级——Kinto 的 schema migration 是内置于启动流程的,无需手工跑迁移。

七、排障实录

7.1 端口映射后 Connection reset by peer

现象:docker compose up -d 后 curl http://127.0.0.1:8149/v1/ 返回 Recv failure: Connection reset by peer,但 docker compose logs web 显示 Serving on http://127.0.0.1:8888。

根因:镜像在构建期执行 kinto init 时未传 --host,内置配置文件监听地址为默认值 127.0.0.1(容器内回环地址);端口映射把宿主机 8149 转发到服务网卡 8888,但服务只接受来自容器内回环的连接,内核直接重置。CLI 的 --host 参数只属于 kinto init(决定写进 ini 的监听地址),kinto start 没有 host 参数。

处置:按官方"自定义配置文件"范式,kinto init --host 0.0.0.0 重新生成配置并挂载覆盖 /etc/kinto/kinto.ini(见 2.3),重启后日志变为 Serving on http://0.0.0.0:8888,访问恢复。

7.2 模板生成的 cache_url 键对 Memcached 无效

现象:kinto init --cache-backend memcached 生成的配置里,Memcached 地址写在了 kinto.cache_url;服务启动后缓存读写异常。

根因:Memcached 缓存后端实现读取的是 kinto.cache_hosts(源码 settings[prefix + "hosts"]),cache_url 是文档/模板间的历史残留键名,只对 PostgreSQL/Redis 类 URL 型后端有效。

处置:把该行改为 kinto.cache_hosts = cache:11211(多节点空格分隔),重启生效。

7.3 挂载目录写权限(uid 10001)

现象:用一次性执行生成配置到挂载目录时报 PermissionError: [Errno 13] Permission denied。

根因:官方镜像以非 root 用户 app(uid 10001)运行,向宿主机挂载目录写文件要求该目录对 uid 10001 可写。

处置:chmod 777 ./config(或 chown 10001)后再执行生成;运行期 web 只需读配置文件,正常权限即可。

7.4 时区警告

启动日志出现 WARNI Database timezone is not UTC (ETC/UTC)——Kinto 期望数据库时区为 UTC,宿主机时区为 Asia/Shanghai 时连接串落到 Etc/UTC 之外的本地时区即触发。记录时间戳仍以毫秒整数返回,功能无碍;对时区敏感的部署可在 PostgreSQL 侧统一 timezone = 'UTC' 消除该警告。