Last month, Hacktoberfest 2026 had open-source contributors everywhere reaching for a place to stash build artifacts, datasets, and CI caches. The cloud bucket is the obvious answer until you remember it wants a credit card and bills you for egress. I stood up an S3-compatible bucket on my own laptop in about five minutes, no AWS account, and it speaks the exact same API my CI already used against S3. Here is the whole thing, and it works just as well in November as it did in October.
TL;DR
- RustFS is Apache 2.0 and S3-compatible, so your existing
mc,aws,boto3, andrclonecommands just work against it by changing one endpoint. - One container, ports 9000 (API) and 9001 (console), default creds
rustfsadmin/rustfsadmin. - Spin it up with a single
docker run, open the console, make a bucket, point your tooling atlocalhost:9000. - It runs as a non-root user (UID/GID 10001:10001), so bind-mounted dirs need the right owner. The compose stack fixes permissions for you if you would rather skip that step.
- Want to give back instead of just using the tool? RustFS is open to contributions; the issues and discussions boards are public.
Why a self-hosted S3 bucket
Most open-source projects are run by people who do not want to paste cloud credentials into a fork. A self-hosted S3-compatible bucket solves three real problems at once:
- No bill, no card. You store artifacts on hardware you already have. The bytes never leave your machine unless you decide they should.
- Your tooling already speaks S3. If your CI uploads to S3 today, it uploads to RustFS by changing one endpoint string. No new client, no rewrite.
- Reproducible by anyone. A teammate on a different continent can run the same three commands and get the same bucket. That matters more for an OSS project than for a closed internal one.
The catch is the one we always name out loud: a self-hosted store makes you the durability and backup owner. RustFS keeps its metadata inside the store, so your discipline is the only thing between you and data loss. For a scratch bucket that is a fine trade. For production, rehearse a restore first.
Prerequisites
- Docker installed and running.
- Enough disk for the image plus whatever you plan to store.
That is it. No Kubernetes, no cluster, no config file to edit for the basic path.
Step 1: Start RustFS
The container runs as a non-root user (rustfs, UID/GID 10001:10001). If you bind-mount host directories, they must be writable by that user, or startup fails with a permission error. The simplest path is to create the dirs and hand them over first:
mkdir -p data logs
chown -R 10001:10001 data logs
docker run -d -p 9000:9000 -p 9001:9001 \
-v $(pwd)/data:/data \
-v $(pwd)/logs:/logs \
rustfs/rustfs:latest
That is the entire "spin it up" step. The image pull is the slow part; the container is up in seconds after that. If you would rather not think about the chown, the project ships a docker-compose-simple.yml that runs an Alpine permission-helper container before RustFS starts, then brings up rustfs-server with five named volumes (four data volumes plus a logs volume) and a health check. Same result, one fewer manual step. One caveat: that helper only chowns the compose's named volumes. If you edit the compose to use host bind mounts instead, you still have to chown those host paths yourself.
Prefer not to touch Docker at all? There is also a one-line installer:
curl -O https://rustfs.com/install_rustfs.sh && bash install_rustfs.sh
Step 2: Open the console and make a bucket
Point a browser at http://localhost:9001. Log in with the documented defaults, rustfsadmin / rustfsadmin, and create a bucket from the console UI. Call it something project-shaped, like hf2026-artifacts.
Change the credentials before this touches anything real. The defaults are documented for exactly this quick-start situation, not for exposure. Set RUSTFS_ACCESS_KEY and RUSTFS_SECRET_KEY (the compose file marks them # CHANGEME) or use IAM policies once you are past the scratch phase.
Step 3: Actually use it
Because RustFS speaks S3, the MinIO client mc works unchanged. Point it at your local endpoint and push a file. (You already created hf2026-artifacts in the console in Step 2, so skip the bucket-creation command and go straight to the copy.)
mc alias set rustfs http://localhost:9000 rustfsadmin rustfsadmin
mc cp ./build.tar.gz rustfs/hf2026-artifacts/
Or from Python, with boto3, pointed at port 9000. Read the credentials from the environment so you are not pasting secrets into source:
import os
import boto3
s3 = boto3.client(
"s3",
endpoint_url="http://localhost:9000",
aws_access_key_id=os.environ["RUSTFS_ACCESS_KEY"],
aws_secret_access_key=os.environ["RUSTFS_SECRET_KEY"],
)
s3.upload_file("build.tar.gz", "hf2026-artifacts", "build.tar.gz")
If you changed the credentials in Step 2, set RUSTFS_ACCESS_KEY and RUSTFS_SECRET_KEY to those new values. If you left the defaults, they are rustfsadmin / rustfsadmin, the same ones the mc command above uses.
The same client reads a cloud bucket by swapping the endpoint and credentials. That portability is the whole point: your project keeps one storage code path whether it runs on a contributor's laptop or in CI.
Why RustFS specifically
I am not claiming RustFS is the only option. MinIO, Garage, and SeaweedFS all have their place. What makes RustFS a clean fit for this job:
- Apache 2.0, not AGPL. Unlike MinIO, which is AGPL-3.0, RustFS ships under the permissive Apache 2.0 license. That is the reason it is comfortable to drop into a forked OSS project without copyleft surprises. (SeaweedFS is also Apache 2.0, so the license is not a differentiator there. RustFS's edge is the Rust-built engine and the MinIO-shaped toolchain.)
- S3-compatible, MinIO-shaped toolchain. If you have used MinIO, the commands are the same. RustFS keeps that simplicity and rebuilds the engine in Rust for memory safety and concurrency.
- One container, no sidecar. Core S3 plus versioning, Object Lock (WORM), lifecycle, and replication are available today; the metadata lives inside the store, so there is one fewer service to run.
- Honest gaps. No FUSE or POSIX mount. You use the S3 API, not a local filesystem. And S3 Tables (the Iceberg REST catalog) is still Preview, so I would not put a production lakehouse on it yet.
Bonus: give back to RustFS (open source runs year-round)
Using the tool is one thing; contributing is another. A timing note: Hacktoberfest 2026 changed its rules, pull requests no longer count toward the event's rewards, with the focus moving to in-person Fests and online challenges. There is no event credit to chase here regardless (the repo carries no hacktoberfest topic). That is fine: the repo is Apache 2.0 and open to contributions 365 days a year. The issues and discussions boards are public:
- Issues: https://github.com/rustfs/rustfs/issues
- Discussions: https://github.com/rustfs/rustfs/discussions
If you are looking for a storage project to contribute to, filter the issues tab for good first issue or help wanted, or weigh in on an open discussion. A documentation fix or a reproducible bug report is as valuable as a feature PR, just do not expect swag for it.
FAQ
Do I need an AWS account to follow this?
No. RustFS runs locally and emulates the S3 API. The aws CLI and boto3 work against it by pointing at localhost:9000 instead of s3.amazonaws.com.
Is rustfsadmin / rustfsadmin safe to leave?
No, not past a scratch run. It is the documented default for quick starts. Set your own keys via environment variables or IAM before anything sensitive touches the bucket.
Can I use this as my CI artifact store?
For a weekend or small-scale project, yes. Point your upload step at localhost:9000 (or the host's LAN IP) and the same S3 calls you would use for cloud storage apply. For anything long-lived, add versioning and a real backup target.
What if I need a filesystem mount, not an API?
RustFS has no FUSE or POSIX mount, by design. If your tooling demands a mount, this is not the right fit. Use the S3 API path or pick a store that offers one.
A note on how this was verified
I pulled the commands, ports, default credentials, license, and Feature & Status table verbatim from the RustFS README (checked 2026-11-01). The docker run line is quoted exactly, not paraphrased. The container's non-root UID/GID (10001:10001) comes from the README, which states the server runs as a non-root user rustfs; the compose permission-helper behavior comes from the project's docker-compose-simple.yml. This is a quick-start walkthrough, not a benchmark or a production deployment report. I did not run a throughput test or stand up a multi-node cluster, and the sandbox here has no Docker daemon, so the commands were not executed locally. Validate them on your own machine before relying on them.
Sources
- RustFS GitHub README (Quickstart, Accessing RustFS, Feature & Status, License) : https://github.com/rustfs/rustfs (checked 2026-11-01)
- RustFS docker-compose-simple.yml : https://github.com/rustfs/rustfs/blob/main/docker-compose-simple.yml
- RustFS documentation, installation : https://docs.rustfs.com/en/installation
- MinIO client (
mc) documentation : https://min.io/docs/minio/linux/reference/minio-mc.html - boto3 documentation : https://boto3.amazonaws.com/v1/documentation/api/latest/
- AWS CLI documentation : https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html
- rclone S3 documentation : https://rclone.org/s3/
- Hacktoberfest 2026 rules (pull requests no longer count toward rewards) : https://hacktoberfest.com/questions/
What are you stashing your project's artifacts in: a cloud bucket, or something you control? If you stood up a local S3 bucket, what tripped you up?
Top comments (0)