Ubuntu 22.04 安装 DittoFS 指南
在 Ubuntu 22.04 上通过 APT 官方仓库、install.sh 脚本与源码编译三种方式安装 DittoFS v0.34.1 模块化虚拟文件系统,覆盖用户/存储/共享/适配器配置、systemd 自启动与 NFS/SMB 挂载验证。
Ubuntu 22.04 安装 DittoFS 指南
目标:在 Ubuntu 22.04 服务器上安装 DittoFS v0.34.1 模块化虚拟文件系统,掌握用户、元数据存储、块存储、共享与 NFS/SMB 协议适配器的完整配置流程,并配置为 systemd 服务随系统自启动。已按官方安装方式在 Ubuntu 22.04 LTS(x86_64)实测通过。
DittoFS 是一个用 Go 编写的模块化虚拟文件系统(Modular Virtual File System),核心思路是把「文件访问协议」与「底层存储后端」解耦:一个服务进程可以同时通过 NFS、SMB 等协议对外提供文件访问,而底层数据可以来自内存、本地磁盘、S3 等不同存储。它完全运行在用户空间,不依赖 FUSE 或内核模块,部署不需要特殊权限,调试也更直接。
DittoFS 提供两个核心二进制:dfs(服务器守护进程,负责协议适配器与控制面 API)和 dfsctl(REST 客户端,用于管理用户、存储、共享与适配器)。默认端口:NFS 12049、SMB 12445、控制面 REST API 8080(默认仅监听回环)、Prometheus 指标 9090。
⚠️ 注意:DittoFS 目前处于 pre-1.0 实验阶段。官方明确声明:未经正式安全审计、API 与磁盘格式可能在不通知的情况下变化、不建议用于无法承受数据丢失的生产场景。本文面向开发测试与原型验证环境。
一、环境信息
- 操作系统:Ubuntu 22.04.5 LTS(x86_64)
- DittoFS 版本:0.34.1(
dfs+dfsctl双二进制) - Go 工具链(源码编译方案):go1.26.0
- 默认端口:NFS 12049 / SMB 12445 / REST API 8080(仅回环)/ Prometheus 9090 / 内嵌 portmapper 10111
- 配置文件:
/etc/dittofs/config.yaml - 控制面数据库:SQLite(默认
~/.config/dittofs/controlplane.db) - 系统服务:
dfs.service(systemd)
二、前置条件
- 使用 root 或具备 sudo 权限的账号执行安装。
- 服务器可访问 GitHub(
github.com/marmos91/dittofsReleases)与官方软件仓库s3.cubbit.eu。 - 若使用源码编译方案,需安装 Go 工具链与
git。
三、版本选型说明
- 官方仓库:
https://github.com/marmos91/dittofs - 版本核实命令:
dfs version或dfsctl version。 - 撰写本文时最新版本为 v0.34.1(构建于 2026-10-02,
Built: 2026-10-02T15:31:29Z,Go 1.26.0)。 - 版本输出(实测):
dfs 0.34.1
Commit: ebd28f1be2d743b3e3b6aff38b4f6658a170f5d9
Built: 2026-10-02T15:31:29Z
Go version: go1.26.0
OS/Arch: linux/amd64
- DittoFS 处于 pre-1.0 阶段,发布节奏较快;API 与磁盘格式可能变化,升级前先阅读 Release Notes,并备份控制面数据库与 journal 目录。
- 安装方式三选一:官方 APT 仓库(推荐)、install.sh 一键脚本、源码编译。三种方式安装的版本一致(均为当前 Release)。
四、部署步骤
4.1 方案 A:APT 官方仓库安装(推荐)
添加官方 APT 源并安装:
curl -fsSL https://s3.cubbit.eu/dittofs-binaries/apt/dittofs.gpg.key \
| gpg --dearmor --yes | sudo tee /usr/share/keyrings/dittofs.gpg > /dev/null
echo "deb [signed-by=/usr/share/keyrings/dittofs.gpg] https://s3.cubbit.eu/dittofs-binaries/apt stable main" \
| sudo tee /etc/apt/sources.list.d/dfs.list
sudo apt update
sudo apt install -y dfs
安装完成后查看版本:
dfs version
# dfs 0.34.1
# Commit: ebd28f1be2d743b3e3b6aff38b4f6658a170f5d9
# Built: 2026-10-02T15:31:29Z
# Go version: go1.26.0
# OS/Arch: linux/amd64
dfsctl version
# dfsctl 0.34.1
# Commit: ebd28f1be2d743b3e3b6aff38b4f6658a170f5d9
# Built: 2026-10-02T15:31:29Z
# Go version: go1.26.0
# OS/Arch: linux/amd64
4.2 方案 B:install.sh 一键脚本安装
下载官方安装脚本并执行(脚本从 GitHub Releases 拉取 .deb/.rpm/.pkg.tar.zst 对应包并安装):
curl -fsSL https://github.com/marmos91/dittofs/releases/latest/download/install.sh -o install-dittofs.sh
bash install-dittofs.sh
脚本默认安装当前最新 Release 的 dfs 与 dfsctl。安装完成后同样以 dfs version 验证。
4.3 方案 C:源码编译安装
适用:需要自行定制编译、或服务器无法访问官方仓库的场景。需要 Go 1.22+ 工具链与 git:
sudo apt-get update
sudo apt-get install -y gcc git curl
# 安装 Go 工具链(示例为官方二进制安装)
curl -fsSL https://go.dev/dl/go1.26.0.linux-amd64.tar.gz -o /tmp/go.tar.gz
sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf /tmp/go.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' | sudo tee /etc/profile.d/go.sh
source /etc/profile.d/go.sh
go version
# go version go1.26.0 linux/amd64
git clone https://github.com/marmos91/dittofs.git /usr/local/src/dittofs
cd /usr/local/src/dittofs
go build -o /usr/local/bin/dfs ./cmd/dfs
go build -o /usr/local/bin/dfsctl ./cmd/dfsctl
💡 说明:源码编译产物与 Release 二进制功能一致。本文以方案 A(APT)为后续配置步骤的基础,方案 B/C 安装完成后配置流程完全相同。
4.4 初始化配置文件
首次启动前必须先创建配置文件。无配置文件时启动会报错:
Error: configuration file not found: /config/config.yaml
Please create the configuration file:
dittofs init --config /config/config.yaml
生成配置文件(建议放到 /etc/dittofs/):
sudo mkdir -p /etc/dittofs
sudo dfs init --config /etc/dittofs/config.yaml
输出(实测):
Configuration file created at: /etc/dittofs/config.yaml
Next steps:
1. Edit the configuration file to customize your setup
2. Start the server with: dfs start
3. Or specify custom config: dfs start --config /etc/dittofs/config.yaml
Security note:
A random JWT secret has been generated for development use.
For production, generate a secure secret and use an environment variable:
# Generates a 64-character hex string (32 bytes of entropy)
export DITTOFS_CONTROLPLANE_SECRET=$(openssl rand -hex 32)
校验配置:
sudo dfs config validate --config /etc/dittofs/config.yaml
# Configuration file: /etc/dittofs/config.yaml
# Validation: OK
#
# Configuration summary:
# Database type: sqlite
# API host: 127.0.0.1
# API port: 8080
# API TLS: false
# Log level: INFO
4.5 设置管理员初始密码并首次启动
DittoFS 首次启动时控制面数据库会创建引导 admin 用户。若未通过环境变量预设密码,服务会自动生成随机密码——在 systemd 下 stdout 不是终端,自动生成的密码不会显示在服务日志中,无法找回。因此必须在首次启动前设置 DITTOFS_ADMIN_INITIAL_PASSWORD。
APT 安装的 dfs 服务通过 systemd 环境变量注入:
sudo mkdir -p /etc/systemd/system/dfs.service.d
cat > /etc/systemd/system/dfs.service.d/password.conf <<'EOF'
[Service]
Environment=DITTOFS_ADMIN_INITIAL_PASSWORD=Your-Strong-Pass-123!
EOF
前台手动启动验证(可选,便于直接观察输出):
sudo DITTOFS_ADMIN_INITIAL_PASSWORD=Your-Strong-Pass-123! dfs start --foreground --config /etc/dittofs/config.yaml
另开终端确认状态:
dfs status --config /etc/dittofs/config.yaml
# DittoFS Server Status
# =====================
#
# Status: ● Running
# PID: 115
# Started: Tue Oct 6 16:37:00 2026
# Uptime: 3s
# CP DB: reachable
#
# Server is running and healthy
健康检查(根路径返回健康 JSON,/healthz 为 404):
curl -s http://127.0.0.1:8080/
# {"status":"healthy","timestamp":"2026-10-06T16:41:45.142413272Z","data":{"control_plane_db":"reachable","service":"dittofs","started_at":"2026-10-06T16:37:00Z","uptime":"4m44s","uptime_sec":284}}
4.6 创建用户、存储、共享与协议适配器
服务启动后,先登录管理面:
dfsctl login --server http://localhost:8080 --username admin
# Logging in to http://localhost:8080 as admin...
# Logged in successfully as admin
# Context: default
# Credentials saved to: ~/.config/dfsctl/config.json
创建数据用户(--host-uid --host-gid 表示用户 UID/GID 对应宿主系统身份):
dfsctl user create --username root --password 'Strong-Pass-123!' --host-uid --host-gid
# User 'root' created successfully
创建元数据存储与块存储(元数据用 BadgerDB 落盘,块内容用内存,适合开发测试):
dfsctl store metadata add --name default --type badger --db-path /var/lib/dittofs/meta
# Metadata store 'default' (type: badger) created successfully
dfsctl store block add --name mem --type memory
# Block store 'mem' (type: memory) created successfully
创建共享并授予权限:
dfsctl share create --name /export --metadata default --block-store mem
# Share '/export' created successfully
dfsctl share permission grant /export --user root --level read-write
# Granted 'read-write' permission to user 'root' on '/export'
启用 NFS 与 SMB 协议适配器:
dfsctl adapter enable nfs
# Adapter 'nfs' enabled on port 12049
dfsctl adapter enable smb --port 12445
# Adapter 'smb' enabled on port 12445
确认监听端口:
ss -tlnp | grep dfs
# tcp 127.0.0.1:8080 LISTEN dfs # 控制面 REST API(默认仅回环)
# tcp :::12445 LISTEN dfs # SMB
# tcp :::12049 LISTEN dfs # NFS
💡 说明:Prometheus 指标端口 9090 默认不监听,需在配置中启用
observability后才会监听,详见《DittoFS 配置参数详解》。
4.7 systemd 服务托管(源码编译/脚本安装时)
APT 安装已自带 dfs.service。源码编译或脚本安装时手动创建单元文件:
cat > /etc/systemd/system/dfs.service <<'EOF'
[Unit]
Description=DittoFS Server
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/dfs start --foreground --config /etc/dittofs/config.yaml
Restart=on-failure
RestartSec=5
EnvironmentFile=-/etc/dittofs/dfs.env
[Install]
WantedBy=multi-user.target
EOF
# 首次启动密码放环境文件
echo 'DITTOFS_ADMIN_INITIAL_PASSWORD=Your-Strong-Pass-123!' > /etc/dittofs/dfs.env
chmod 600 /etc/dittofs/dfs.env
systemctl daemon-reload
systemctl enable dfs
# Created symlink /etc/systemd/system/multi-user.target.wants/dfs.service → /etc/systemd/system/dfs.service.
systemctl start dfs
systemctl status dfs
# ● dfs.service - DittoFS Server
# Loaded: loaded (/etc/systemd/system/dfs.service; enabled; vendor preset: enabled)
# Active: active (running) since Tue 2026-10-06 16:37:00 UTC; 2s ago
# Main PID: 115 (dfs)
⚠️ 注意:systemd 托管必须使用
--foreground前台运行(dfs start默认后台守护会自行 detach,systemd 无法跟踪进程)。
4.8 挂载验证(NFS / SMB)
NFSv4.1 挂载(推荐,锁定走协议内、无需 portmapper):
mkdir -p /mnt/dittofs
sudo mount -t nfs -o vers=4.1,tcp,port=12049 127.0.0.1:/export /mnt/dittofs
⚠️ 注意:NFS 内核挂载需要具备内核 NFS 客户端的 Linux 真机 + root 权限(依赖
mount.nfshelper 与 nfs-utils,apt install -y nfs-common),并确认防火墙放行 12049 端口。DittoFS 默认使用非特权端口 12049;若需使用标准端口 2049,请参考《DittoFS 配置参数详解》中的标准端口配置(需释放系统自带 nfs-server 占用并授予CAP_NET_BIND_SERVICE)。
SMB 挂载:
mkdir -p /mnt/dittofs-smb
sudo mount -t cifs //127.0.0.1/export /mnt/dittofs-smb -o port=12445,username=root,password=你的密码,vers=3.1.1
⚠️ 注意:SMB 挂载需要
cifs-utils(apt install -y cifs-utils),同样需要 Linux 真机 + root 权限,并放行 12445 端口。
五、配置说明
DittoFS 采用两层配置模型:
- 进程级配置(
config.yaml):控制日志、控制面 API、数据库连接、blockstore journal、适配器端口等;所有键均可通过DITTOFS_前缀的环境变量覆盖(如DITTOFS_LOGGING_LEVEL=DEBUG)。 - 控制面数据库(SQLite/PostgreSQL):存放用户、组、共享、权限与存储定义,可通过
dfsctl动态管理,无需重启服务。
常用配置键(dfs init 生成的默认值):
| 配置键 | 默认值 | 说明 |
|---|---|---|
logging.level | INFO | 日志级别:DEBUG/INFO/WARN/ERROR |
logging.output | stdout | 日志输出:stdout/stderr/文件路径 |
database.type | sqlite | 控制面数据库:sqlite(单机)/ postgres(HA) |
controlplane.host | 127.0.0.1 | API 绑定地址(默认仅回环,多主机部署改 0.0.0.0 并加 TLS) |
controlplane.port | 8080 | API 端口 |
controlplane.jwt.secret | 自动生成 | JWT 签名密钥(生产用 DITTOFS_CONTROLPLANE_SECRET) |
controlplane.jwt.access_token_duration | 15m | 访问令牌有效期 |
controlplane.jwt.refresh_token_duration | 168h | 刷新令牌有效期(7 天) |
controlplane.require_initial_password_change | true | 引导 admin 首次登录强制改密 |
shutdown_timeout | 30s | 优雅停机最大等待时间 |
blockstore.journal.path | 状态目录下的 blocks | journal(写前日志)根目录 |
adapters.nfs.port | 12049 | NFS 监听端口 |
adapters.smb.port | 12445 | SMB 监听端口 |
⚠️ 注意:
DITTOFS_ADMIN_INITIAL_PASSWORD与DITTOFS_CONTROLPLANE_SECRET仅在首次启动时生效——前者用于创建引导 admin 密码,后者用于替换配置中的随机 JWT 密钥。生产环境务必在首次启动前设置,且应生成强密钥:openssl rand -hex 32。
六、注意事项
- 实验阶段软件:DittoFS pre-1.0,未经安全审计,API/磁盘格式可能变化。生产环境请等待稳定版 1.0,评估前做好数据备份。
- 首次启动必须预设 admin 密码:
DITTOFS_ADMIN_INITIAL_PASSWORD未设置时自动生成的随机密码在 systemd 下无法查看(stdout 非终端),等于无法登录。 - 控制面 API 默认仅监听回环:多主机/远程管理需改
controlplane.host: 0.0.0.0并配置 TLS(controlplane.tls.cert_file/key_file),否则管理面暴露在网络上不安全。 - blockstore 无文件系统类型:块存储只有
s3与memory两种,任何共享的持久化数据都依赖 S3 后端 + 本地 journal;memory 块存储在重启后数据即失。生产持久化必须指向真实 S3 bucket。 - 首次启动前必须 init 配置:无
config.yaml时dfs start直接报错退出。 - systemd 托管用
--foreground:dfs start默认后台守护,systemd 请使用前台模式。 - 防火墙:对外提供 NFS/SMB 服务时,按端口放行(12049/12445,标准端口方案为 2049/445/111)。Ubuntu 默认启用 ufw 时执行
sudo ufw allow 12049/tcp && sudo ufw allow 12445/tcp。
七、常见问题(FAQ)
Q1:dfs start 报 configuration file not found?
未初始化配置。执行 sudo dfs init --config /etc/dittofs/config.yaml 生成后再启动。
Q2:首次启动后 dfsctl login 用预设密码登录失败?
确认密码已通过 DITTOFS_ADMIN_INITIAL_PASSWORD 在首次启动前注入;若服务已启动过,该变量不再生效。可通过 dfsctl login 后用 dfsctl user get admin 查看 Must Change Password 状态,首次登录可能被要求强制改密(require_initial_password_change 默认 true)。
Q3:dfsctl user create 报 Failed to hash password?
密码强度不足。DittoFS 对密码有复杂度要求,实测弱密码(如 secret)会被拒绝,需使用包含大小写与数字/符号的强密码(如 Strong-Pass-123!)。
Q4:NFS 挂载报 mount.nfs: Protocol not supported?
内核 NFS 客户端或 nfs-utils 缺失/受限。确认真机已安装 nfs-common(apt install -y nfs-common)且内核已加载 NFS 模块(lsmod | grep nfs),使用 vers=4.1 并显式指定 port=12049;若宿主环境不具备内核挂载能力,mount.nfs 会报错,属宿主环境限制。
Q5:NFSv3 挂载后 flock/fcntl 锁卡住?
NFSv3 的字节范围锁走 NLM 协议,需要 portmapper(默认 10111)可达且 NFS 使用 TCP。开发测试建议直接 -o vers=4.1(协议内锁定,无需 NLM);或挂载时加 nolock 跳过锁定。
Q6:重启后共享里的文件不见了?
块存储用了 memory 类型(数据仅存内存 + journal,journal 有回收机制)。持久化需将块存储指向真实 S3 bucket(dfsctl store block add --type s3 --bucket ...)。
八、卸载方式
# 停止并禁用服务
sudo systemctl stop dfs
sudo systemctl disable dfs
sudo rm -f /etc/systemd/system/dfs.service
sudo rm -rf /etc/systemd/system/dfs.service.d
sudo systemctl daemon-reload
# 卸载软件包(APT 安装)
sudo apt remove -y dfs
# 删除配置、数据与状态(按需,注意先备份)
sudo rm -rf /etc/dittofs /var/lib/dittofs
sudo rm -f /usr/local/bin/dfs /usr/local/bin/dfsctl
rm -rf ~/.config/dittofs ~/.config/dfsctl ~/.local/state/dittofs
# 删除官方 APT 源与密钥(按需)
sudo rm -f /etc/apt/sources.list.d/dfs.list /usr/share/keyrings/dittofs.gpg
# 源码编译环境(按需)
sudo rm -rf /usr/local/src/dittofs /usr/local/go
九、参考链接
- 官方仓库:
https://github.com/marmos91/dittofs - 官方文档:
https://dittofs.io/ - Docker 镜像:
https://hub.docker.com/r/marmos91c/dittofs - NFS 协议规范:
https://datatracker.ietf.org/doc/html/rfc7530 - SMB 协议(Microsoft Open Specifications):
https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/