# go-fastdfs: A Single-Binary Distributed File System with No Tracker Role

> go-fastdfs is a Go file server that speaks plain HTTP, syncs files between peer nodes without a central coordinator, and ships as one binary. It fits teams that want private object storage without running FastDFS's three roles, and it expects you to read the security notes before exposing it.

**sjqzhang/go-fastdfs** — go-fastdfs 是一个简单的分布式文件系统(私有云存储)，具有无中心、高性能，高可靠，免维护等优点，支持断点续传，分块上传，小文件合并，自动同步，自动修复。Go-fastdfs is a simple distributed file system (private cloud storage), with no center, high performance, high reliability, maintenance free and other advantages, support breakpoint continuation, block upload, small file merge, automatic synchronization, automatic repair.(similar fastdfs).

- Repository: https://github.com/sjqzhang/go-fastdfs
- Website: https://gitee.com/sjqzhang/go-fastdfs
- Stars: 4,141 · Forks: 769
- Language: Go
- License: Unlicense
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/sjqzhang-go-fastdfs

## The problem go-fastdfs targets: file storage without a tracker role

FastDFS splits a cluster into three roles: a tracker server, a storage server, and a client. go-fastdfs collapses that. The README states that operations are simple because there is only one role, unlike FastDFS, and that every node is a peer, so all nodes can read and write at the same time. There is no coordinator to elect, no tracker to keep alive, and no separate client library to install, because uploads and downloads go over ordinary HTTP and the README notes that wget and curl work as clients.

The intended user is a team that needs private cloud storage on its own machines: an internal image host, a file backend for an application, a backup target for small files. The README also names a migration path. It advertises one-click migration from another file system and a parallel run mode where go-fastdfs sits beside your existing storage until you are satisfied, then you move. That is a realistic adoption story for a team that cannot take a storage outage.

The design bet is that simplicity is what makes the system stable. The README makes that argument directly: because it is simple it is efficient, because it is simple it is stable. Whether that holds for your workload is something you test, not something you assume.

## How the peer-to-peer sync and single-role design actually work

Each node runs the same binary, called fileserver, and stores files under a directory the README describes as organized by day, which it says makes maintenance easier. Metadata lives in LevelDB: go.mod lists github.com/syndtr/goleveldb, and the README calls LevelDB the key-value store behind its performance claim. A node that receives a file writes it locally and then pushes it to its peers, so there is no central index that must be consulted before a write succeeds. The README describes this as automatic synchronization, with automatic repair of failures.

Two features follow from that model. Files are deduplicated automatically, and the README lists a second-level upload path it calls instant upload, where a client that already knows the file's MD5 can skip the transfer. Small files can be merged to reduce inode consumption, which matters on a filesystem holding millions of tiny objects. The README also lists breakpoint download, cross-origin access, image resizing, Google Authenticator codes, custom authentication, cluster-wide file information views, and email alerts for cluster monitoring.

The synchronization is not a consensus protocol, and the README does not present it as one. It is replication between peers. The README does not document conflict resolution for simultaneous writes of the same path, and it does not document rollback. If your application needs a single authoritative writer or strict ordering, this architecture is the wrong shape, and no amount of configuration fixes that.

## Installing go-fastdfs and uploading a first file

The README points to prebuilt binaries on the releases page of the sjqzhang/fastdfs GitHub repository. The quickest path is to download the binary, run it, and upload with curl. The README warns that running it directly in a terminal means it exits when the terminal closes, and that production use should go through the control file in the repository. The default HTTP port shown in the README examples is 8080.

Start the server:

```bash
./fileserver
```

Upload a file with a multipart form post. The README gives this exact shape, with group1 as the group name and upload as the endpoint:

```bash
curl -F file=@http-index-fs http://10.1.xx.60:8080/group1/upload
```

If you prefer the browser, open the server address on port 8080. The README adds a warning here that is easy to miss: do not use 127.0.0.1 to upload, because the node needs to be reachable by the address it advertises to peers.

For resumable uploads the project depends on tus. go.mod pins github.com/sjqzhang/tusd and github.com/eventials/go-tus, and the README lists tus as the mechanism behind breakpoint continuation. A tus-capable client points at the same server; the README does not spell out the tus endpoint path in the excerpt available here, so check the usage documentation before wiring a client.

Docker is supported. The Dockerfile builds a static binary with CGO_ENABLED=0 and places it at /usr/local/go-fastdfs/fileserver, with data under a volume driven by the GO_FASTDFS_DIR environment variable, which defaults to /usr/local/go-fastdfs/data. The container command is fileserver server with an OPTS variable appended, so extra flags go through OPTS rather than the entrypoint.

## Where go-fastdfs is the wrong tool, and what the release history shows

The release history is thin. v1.4.6, dated 2024-09-20, fixes a bug caused by deleting empty directories. v1.4.5, from 2023-04-20, adds user-defined cross-origin domains. v1.4.4, from 2023-04-08, fixes a security vulnerability in custom paths. The last push to the repository was on 2026-07-11, so the codebase is still receiving commits even though tagged releases are rare. That gap matters if you depend on tagged artifacts: between releases, fixes live on master.

Security is the sharpest limitation. A project whose own release notes include a custom-path vulnerability, and whose search traffic includes Chinese-language queries about vulnerabilities and arbitrary file upload, is telling you that the upload surface is the risk. The README describes authentication options, including Google Authenticator and custom authentication, but it does not document a hardened default posture for an internet-facing node. The practical reading is that you put this behind nginx, which the repository anticipates by shipping an nginx directory, and you do not expose port 8080 to the public internet.

There are also operational gaps. The README does not document rollback of a failed upgrade, does not document backup and restore of the LevelDB metadata, and does not describe what happens to in-flight uploads when a node restarts. The README does mention self-monitoring alerts by email, which helps with detection but not with recovery. If your team needs documented disaster recovery procedures, you will be writing them yourself.

## go-fastdfs compared with MinIO and FastDFS

FastDFS is the closest comparison and the one the README makes itself: go-fastdfs is described as fastdfs-like, but with a single role instead of tracker, storage, and client. The practical difference is operational. FastDFS gives you a tracker that knows where files live, which makes placement explicit; go-fastdfs gives every node the ability to serve any file, which removes a failure domain but also removes a single place to ask where a file is. If you already run FastDFS and know its failure modes, go-fastdfs removes a component rather than adding one.

MinIO is the other obvious alternative, and the difference is architectural. MinIO implements the S3 API, so your clients use existing SDKs and your tooling expects bucket semantics. go-fastdfs uses plain HTTP with its own upload and download endpoints and its own group naming, so an S3 client will not talk to it. The trade is that you avoid S3 semantics you may not want, and you gain features MinIO does not advertise in the same way, notably automatic small-file merging and peer-to-peer sync without a coordinator.

If your application already speaks S3, go-fastdfs is a step backwards, because you would rewrite client code. If your application just needs to POST a file and GET it back over HTTP, go-fastdfs is less machinery than an S3-compatible server.

## Licence, upgrade cost, and what to verify before rollout

The repository carries the Unlicense, a public-domain dedication rather than a permissive licence with conditions. For most teams this removes licence review friction entirely: there is no attribution requirement, no copyleft obligation, and no commercial restriction stated in the licence text. This is not legal advice, and if your organisation has a policy that only accepts named licences such as MIT or Apache-2.0, the Unlicense may need an explicit exception even though it is less restrictive.

Upgrade cost is dominated by the release cadence. Tagged releases arrive roughly yearly, so you either track master or you sit on a tag and miss fixes. The v1.4.4 security fix is the argument for tracking: a custom-path vulnerability sat in a tagged release until someone fixed it. If you pin a tag, you own the job of watching the repository for security commits between tags.

The vendor directory is committed, and the Dockerfile builds with GO111MODULE=off against that vendor tree, while go.mod declares Go 1.17. Building from source therefore depends on the vendored dependencies rather than on module resolution, which is reproducible but means dependency updates arrive only when the maintainer updates vendor. Verify the build on your target platform before committing, especially on arm64 or loong64, since the Makefile enumerates those targets but the README does not describe testing them.

## Conclusion

Adopt go-fastdfs if you want private HTTP file storage with peer sync and no tracker role, and you are willing to run behind nginx with authentication enabled. Do not adopt it if you cannot control who reaches port 8080, or if you need documented rollback and versioning. Before anything else, check the release notes for v1.4.4 and v1.4.6, confirm which upload endpoints your build exposes, and verify the token download scheme against your own threat model.

## FAQ

### How do I install go-fastdfs?

Download a prebuilt binary from the releases page of the sjqzhang/fastdfs GitHub repository, or build the Docker image from the Dockerfile in the repository. The README notes that running the binary directly in a terminal exits when the terminal closes, so production use should go through the control file.

### Can I use go-fastdfs without a dedicated client?

Yes. It uses ordinary HTTP, and the README states that wget and curl work as clients. Uploads go through a multipart POST such as curl -F file=@http-index-fs http://10.1.xx.60:8080/group1/upload.

### Does go-fastdfs support resumable uploads?

The README lists breakpoint continuation as a feature and links to tus, and go.mod pins github.com/sjqzhang/tusd and github.com/eventials/go-tus. The README excerpt does not document the tus endpoint path, so check the usage documentation before configuring a client.

### How does go-fastdfs differ from FastDFS?

The README describes go-fastdfs as fastdfs-like but with only one role, where FastDFS has three (Tracker Server, Storage Server, Client). Every node is a peer and can read and write at the same time, and configuration is generated automatically.

## Sources

- [License: Unlicense](https://github.com/sjqzhang/go-fastdfs/blob/master/LICENSE)
- [Project website](https://gitee.com/sjqzhang/go-fastdfs)
- [README](https://github.com/sjqzhang/go-fastdfs/blob/master/README.md)
- [Releases](https://github.com/sjqzhang/go-fastdfs/releases)
- [sjqzhang/go-fastdfs on GitHub](https://github.com/sjqzhang/go-fastdfs)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/sjqzhang-go-fastdfs
