MooseFS
Overview
MooseFS is an open-source, POSIX-compliant distributed file system. It spreads files across a cluster of chunkservers, so a MooseFS volume behaves like an ordinary directory on every client while the data underneath is distributed and, once you add chunkservers, replicated.
This guide covers the deployment and configuration of MooseFS on Ubuntu 24.04 on Azure, using SecureAnyCloud Azure Marketplace images. The image ships MooseFS 4 Community Edition, installed from the official MooseFS repository. A master server, one chunkserver and the MooseFS FUSE client all run on this single virtual machine. The filesystem is mounted and ready at /srv/moosefs the moment first boot completes. You can write to it, read from it and watch the chunks appear in the web monitor without configuring anything.
Single node by design
This image is a single-node starter cluster, not a redundant one. One virtual machine runs one chunkserver, so there is exactly one copy of every chunk and no fault tolerance. If this virtual machine or its data disk is lost, the data is lost. This is a deliberate, self-contained starting point for evaluation, development and learning MooseFS.
Real fault tolerance comes from adding chunkservers on separate machines and raising the storage goal. Step 7 walks through how to do that. Until you do, treat this virtual machine like any other single-disk server and back it up accordingly.
Security model
The image keeps everything that speaks the MooseFS protocol off the network:
- The client control port (9421), which grants access to the filesystem, and the metalogger port (9419) are bound to
127.0.0.1. - The web monitor (9425) is bound to
127.0.0.1and published only through nginx. - MooseFS refuses a loopback address for the chunkserver-to-master link, so the chunkserver ports (9420 and 9422) bind the virtual machine's private address. An
nftablestable then drops ports 9419 to 9425 on every non-loopback interface. The whole MooseFS protocol surface is therefore unreachable from off the machine, regardless of how your network security group is configured. mfsexports.cfgpermits mounts only from127.0.0.1/32.
The only published endpoints are TCP 443 (the web monitor, TLS with HTTP Basic Auth) and TCP 80 (a redirect to HTTPS).
On every fresh customer virtual machine, moosefs-firstboot.service generates a per-VM web monitor password and a TLS certificate bound to the machine. It records both in /root/moosefs-credentials.txt (mode 0600, root only). The captured image ships an empty password file, so no two virtual machines share credentials and there is no default login at any point.
What you get:
- MooseFS 4 Community Edition: master, chunkserver, CLI tools and the FUSE client
moosefs-master,moosefs-chunkserver,moosefs-guiandmoosefs-mountsystemd units that start automatically on boot- A dedicated 40 GiB data volume mounted at
/var/lib/mfs, holding both the master metadata and the chunk storage - The MooseFS filesystem mounted at
/srv/moosefs - An nginx TLS front that publishes the web monitor on
:443with HTTP Basic Auth, and:80redirecting to HTTPS - An
nftablesguard that restricts every MooseFS port to this machine - Ubuntu 24.04 LTS base with the latest security patches applied at build time
- Azure Linux Agent for cloud integration and SSH key injection
- 24/7 SecureAnyCloud support with guaranteed 24 hour response SLA
Prerequisites
Before you deploy, prepare the following:
- An active Azure subscription
- A subscription to the MooseFS on Ubuntu 24.04 listing on Azure Marketplace
- An SSH public key for VM authentication
- A virtual network and subnet in the target region
Recommended virtual machine size: Standard_B2s (2 vCPU, 4 GB RAM) for evaluation and small workloads.
The MooseFS master keeps its entire metadata set in RAM, so size the machine by file count rather than by capacity. Budget roughly 300 bytes of master RAM per file. Production deployments should use Standard_D2s_v3 or larger and attach additional data disks for chunk storage.
Deploy from the Azure Portal
In the Azure Portal, open the Marketplace, search for MooseFS, select the SecureAnyCloud publisher entry, and select Create.
On the Networking tab, attach a network security group that allows inbound TCP 22 from your management IP range and TCP 443 (the web monitor) from your admin networks. You do not need to open any MooseFS protocol port, because the image binds them to loopback or firewalls them to this machine.
Select Review + create, wait for validation, then select Create. Deployment takes around two minutes.
Connect and confirm the services are running
Connect over SSH using the key you supplied at deployment:
ssh azureuser@<vm-ip>Confirm that every MooseFS component and the TLS front are active:
sudo systemctl is-active moosefs-master moosefs-chunkserver moosefs-gui moosefs-mount nginxExpected output: five lines, all active.
active active active active activeConfirm the listening sockets. The client control port and the web monitor are on loopback, and only nginx is published:
sudo ss -H -lnt "( sport = :9421 or sport = :9425 or sport = :443 )" | awk '{print $4}'Expected output:
127.0.0.1:9421 127.0.0.1:9425 0.0.0.0:443Retrieve the per-VM monitor credentials
First boot generates the web monitor password on this virtual machine and writes it to a root-only file. List the file:
sudo ls -l /root/moosefs-credentials.txtExpected output: mode 0600, owned by root.
-rw------- 1 root root 1322 Jul 19 23:34 /root/moosefs-credentials.txtView the credential keys. The file also records the monitor URL and the mount point.
sudo grep -o '^[A-Z_]*=' /root/moosefs-credentials.txtExpected output:
GUI_USER= GUI_PASSWORD= <set-at-first-boot>= MOOSEFS_MOUNT_POINT=Read the full file when you need the actual values.
sudo cat /root/moosefs-credentials.txtConfirm the MooseFS version:
sudo mfsmaster -vExpected output:
version: 4.59.2-1 ; build: 2106Note on the monitor URL. Azure Instance Metadata returns an empty public-IP field for Standard SKU addresses, so MOOSEFS_MONITOR_URL may show this machine's private address. If you connect from outside the virtual network, substitute the public IP shown on the virtual machine's Overview blade in the Azure portal. The monitor is served on port 443 either way.
Use the filesystem
The MooseFS volume is already mounted. Confirm that it is a genuine MooseFS mount rather than an ordinary directory. The source is mfs# followed by the master address:
findmnt -no SOURCE,FSTYPE,TARGET /srv/moosefsExpected output:
mfs#127.0.0.1:9421 fuse /srv/moosefsWrite a file and read it back, then verify that the content survived the round trip byte for byte:
sudo mkdir -p /srv/moosefs/demo head -c 4194304 /dev/urandom > ~/demo.bin
sudo cp ~/demo.bin /srv/moosefs/demo/demo.bin sync
sudo sha256sum ~/demo.bin /srv/moosefs/demo/demo.binExpected output: the two checksums are identical.
369cd7031892eabed30550a0e2c5c979d660fbbbda357fa223209246f5949851 /home/azureuser/demo.bin 369cd7031892eabed30550a0e2c5c979d660fbbbda357fa223209246f5949851 /srv/moosefs/demo/demo.binConfirm that the data is stored as MooseFS chunks, and see which chunkserver holds each copy:
sudo mfsfileinfo /srv/moosefs/demo/demo.binExpected output:
/srv/moosefs/demo/demo.bin: chunk 0: 000000000000000F_00000001 / (id:15 ver:1) ; mtime:1784504501 (2026-07-19 23:41:41) copy 1: 10.0.0.28:9422 ; status:VALIDcopy 1 is the single copy of this chunk on the single chunkserver. On a multi-node cluster, you also see copy 2, copy 3 and so on.
Inspect the cluster from the command line
List the registered chunkservers:
sudo mfscli -H 127.0.0.1 -SCSConfirm the capacity of the MooseFS volume and of the dedicated data disk beneath it.
df -h /srv/moosefs /var/lib/mfsExpected output:
Filesystem Size Used Avail Use% Mounted on mfs#127.0.0.1:9421 38G 302M 37G 1% /srv/moosefs /dev/sda 40G 46M 38G 1% /var/lib/mfsThe chunks themselves live on the dedicated data volume:
sudo find /var/lib/mfs/chunks -name 'chunk_*.mfs' -type f > ~/mfs-chunks.txt head -3 ~/mfs-chunks.txtOpen the web monitor
Browse to https://<vm-ip>/ and sign in with the GUI_USER and GUI_PASSWORD values from /root/moosefs-credentials.txt. The certificate is self-signed and bound to this virtual machine, so your browser warns you on the first visit.
From the command line, verify that the monitor refuses anonymous access and accepts the per-VM credential:
curl -k -s -o /dev/null -w 'anonymous: %{http_code}\n' https://127.0.0.1/
curl -k -s -o /dev/null -w 'authenticated: %{http_code}\n' -u '<GUI_USER>:<GUI_PASSWORD>' https://127.0.0.1/mfs.cgiExpected output:
anonymous: 401 authenticated: 200The Info tab shows the cluster summary: master version and state, total and available space, and the file and chunk counts.
Why the chunk matrix shows chunks as "endangered". On the Info tab, the redundancy matrix reports every chunk at redundancy level 0 and colours the count orange. This is correct and expected on a single-node cluster. With one chunkserver there is exactly one copy of each chunk, so MooseFS is reporting accurately that no chunk could survive losing that server. The indicator turns green once you add a second chunkserver and raise the goal, as described in Step 7.
The Chunkservers tab lists each registered chunkserver with its address, version, chunk count, and used and total space.
The Disks tab shows the individual storage directories behind each chunkserver. Here it shows the chunk directory on the dedicated data volume, with its chunk count, error status and capacity.
The Exports tab shows which clients may mount the filesystem. Both entries are restricted to 127.0.0.1, which is the loopback-only export policy this image ships with.
Growing into a real cluster
Genuine fault tolerance needs chunkservers on separate virtual machines, so that losing one machine cannot lose the only copy of a chunk. The outline below is the standard MooseFS procedure. Apply your own network and security review before you use it in production.
On this master virtual machine, allow the new chunkserver's private address through the nftables guard:
sudo nft insert rule inet sac_moosefs input ip saddr <chunkserver-private-ip> tcp dport 9420 acceptPersist that rule by adding it to /etc/nftables.d/moosefs.nft above the drop rule. Also allow TCP 9420 from the new machine in your Azure network security group.
On each new virtual machine, install the chunkserver from the same official repository. Point MASTER_HOST in /etc/mfs/mfschunkserver.cfg at this master's private address, list its storage directories in /etc/mfs/mfshdd.cfg, then start moosefs-chunkserver.
Once the new chunkservers appear on the Chunkservers tab, raise the storage goal so that MooseFS keeps more than one copy of each chunk:
sudo mfssetgoal -r 2 /srv/moosefsMooseFS then replicates existing chunks in the background until every chunk meets the new goal, and the redundancy matrix on the Info tab turns green.
To mount the filesystem from other machines, you must also widen the export list. Add an entry to /etc/mfs/mfsexports.cfg scoped to the specific client network and protected with a password. Then widen MATOCL_LISTEN_HOST in /etc/mfs/mfsmaster.cfg from 127.0.0.1 to the private address, and open port 9421 to those clients only:
10.0.0.0/24 / rw,alldirs,maproot=0,password=<your-secret>Reload the master to apply the export changes:
sudo mfsmaster reloadDo not widen MATOCL_LISTEN_HOST without setting a password. The client control port grants access to the whole filesystem, which is why this image keeps it on loopback by default.
Backing up the metadata
The master's metadata is the index of the entire filesystem. If you lose it, the chunks are unusable. The metadata lives on the dedicated data volume at /var/lib/mfs:
sudo ls -l /var/lib/mfs/metadata.mfs.back /var/lib/mfs/metadata.crcWhile the master is running, the current metadata image on disk is metadata.mfs.back, accompanied by the changelog.*.mfs files that hold changes since the last save. A plain metadata.mfs appears only while the master is cleanly stopped, so do not treat its absence on a running system as a fault.
For production, run a moosefs-metalogger on a separate machine. The metalogger keeps a continuously updated copy of the master metadata and is the supported way to recover a failed master.
This image binds the metalogger port (9419) to loopback. Widen MATOML_LISTEN_HOST in /etc/mfs/mfsmaster.cfg and allow 9419 from the metalogger's address only, as for the chunkserver in Step 7.
Azure disk snapshots of the data volume are a useful complement. Take them consistently, and treat them as a point-in-time copy rather than a substitute for a metalogger.
Troubleshooting
The web monitor returns 401 with the correct password. First boot regenerates the password. Make sure you read the current value from /root/moosefs-credentials.txt on this machine, not a value copied from another virtual machine.
The mount is missing after a reboot. Check the mount unit and the master:
sudo systemctl status moosefs-mount --no-pager findmnt -no SOURCE,FSTYPE /srv/moosefsThe mount unit uses mfsdelayedinit, so it succeeds and connects in the background even if the master is still starting.
Writes fail with "no space left on device" while df shows free space. MooseFS reserves space per chunkserver. Check the Disks tab in the web monitor for the per-directory capacity and error status.
A chunkserver shows as disconnected. Confirm that the master is reachable from the chunkserver on port 9420. Both the nftables guard on this machine and your Azure network security group must allow the chunkserver's address.
The machine did not come up as expected. Check the first-boot log:
sudo cat /var/log/moosefs-firstboot.logLicensing
MooseFS Community Edition is distributed under the GNU General Public License, version 2. There is no per-node or per-capacity fee. The SecureAnyCloud charge covers packaging, security patching, image maintenance and 24/7 support.
Support
SecureAnyCloud provides 24/7 support with a guaranteed 24 hour response SLA. For questions or help with your deployment, contact sales@secureanycloud.com.
Deploy on Azure
Launch MooseFS on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.
View this image
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com
Overview
This image runs MooseFS Community Edition, the open source POSIX compliant distributed file system. MooseFS spreads files across a cluster of chunkservers, so a MooseFS volume behaves like an ordinary directory on every client while the data underneath is distributed and, once you add chunkservers, replicated.
The image is a complete, self contained MooseFS starter node. A master server, one chunkserver and the MooseFS FUSE client all run on the single instance, and the MooseFS volume is mounted and ready at /srv/moosefs the moment first boot completes. You can write to it, read from it, and watch the chunks appear in the web monitor without configuring anything.
Because a single instance holds one copy of every chunk, this image on its own is an evaluation and starter topology, not a redundant one. Real fault tolerance comes from adding chunkservers on separate instances and raising the storage goal; the last section of this guide walks through exactly how to do that.
MooseFS keeps both the master metadata and the chunk storage on a dedicated EBS data volume mounted at /var/lib/mfs, separate from the operating system disk and independently resizable. The chunk storage lives at /var/lib/mfs/chunks.
The image is secure by default. The MooseFS master control port, the chunkserver port and the web monitor are bound to the loopback interface, and an nftables guard drops the entire MooseFS protocol port range on every other interface, so nothing that speaks the MooseFS protocol is reachable from off the instance regardless of your security group. The only published endpoint is the web monitor, served over TLS by nginx on port 443 behind HTTP Basic Auth, with port 80 redirecting to 443. On the first boot of every deployed instance a one shot service generates a per instance monitor password and a TLS certificate bound to the instance, and records the credentials in /root/moosefs-credentials.txt with mode 0600. No shared or default credentials ship in the image.
Prerequisites
Before you deploy this image you need:
- An Amazon Web Services account where you can launch EC2 instances
- IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
- An EC2 key pair in the target Region for SSH access to the instance
- A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network and inbound port 443 (and optionally port 80, which only redirects to 443) from where you will reach the web monitor
- The AWS CLI (version 2) installed locally if you plan to deploy from the command line
Launch the Instance from the AWS Marketplace
Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for MooseFS. Select the SecureAnyCloud listing and choose Select, then Continue on the subscription summary.
Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network and inbound port 443 from where you will reach the web monitor. Leave the root volume at the default size or larger; the image adds a separate 40 GiB data volume for the MooseFS metadata and chunk storage automatically.
Select Launch instance. First boot initialisation takes under a minute after the instance state becomes Running and the status checks pass.
Launch the Instance from the AWS CLI
The following block launches an instance from the SecureAnyCloud MooseFS Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 and port 443 as described above.
aws ec2 run-instances \
--image-id <ami-id> \
--instance-type m5.large \
--key-name <key-name> \
--subnet-id <subnet-id> \
--security-group-ids <security-group-id> \
--block-device-mappings '[{"DeviceName":"/dev/sda1","Ebs":{"VolumeSize":20,"VolumeType":"gp3"}}]' \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=moosefs-01}]'The command prints a JSON document on success. Note the instance ID, then retrieve its public address once it is running with aws ec2 describe-instances --instance-ids <instance-id> --query "Reservations[].Instances[].PublicIpAddress" --output text.
Connecting to Your Instance
Connect over SSH with the key pair you selected and the instance's public IP address. The SSH login user depends on the operating system of the AMI variant you launched:
AMI variant SSH login user
MooseFS 4 CE on Ubuntu 24.04 ubuntu
Retrieve the Web Monitor Credentials
On the first boot of the instance, moosefs-firstboot.service generates a per instance web monitor password, regenerates a TLS certificate bound to the instance, brings the MooseFS stack up, mounts the filesystem, and writes the credentials to /root/moosefs-credentials.txt (readable only by root). Connect over SSH and read that file:
ssh <login-user>@<public-ip>
sudo cat /root/moosefs-credentials.txtThe file contains GUI_USER, GUI_PASSWORD, MOOSEFS_MONITOR_URL (the https://<instance-public-ip>/ address of the web monitor) and MOOSEFS_MOUNT_POINT (/srv/moosefs). Note the user and password for the next step.
Sign In to the Web Monitor
Open the MOOSEFS_MONITOR_URL from the credentials file in a browser, for example https://<public-ip>/. The certificate is self signed and bound to the instance, so your browser warns on the first visit; accept the warning to continue. When prompted for HTTP Basic Auth, sign in with the GUI_USER and GUI_PASSWORD values from the credentials file.
The monitor opens on the Status dashboard, showing total and free space, cluster health, usage and live throughput for the master server and the chunkserver.
The Info tab shows the cluster summary, the master metadata server and the chunk redundancy matrix. On a fresh single node instance you will see the health reported as "all in danger" and chunks at redundancy level 1 (RL=1): this is expected and simply means every chunk currently has a single copy because there is one chunkserver. It is not an error; see the last section for how to add redundancy.
The Chunkservers tab lists each chunkserver with its version, chunk count and the used and total space on the dedicated data volume.
The Mounts tab shows the active MooseFS FUSE client mounted at /srv/moosefs, ready to read and write files.
Verify the Stack
From an SSH session on the instance, confirm every service is running:
systemctl is-active moosefs-master moosefs-chunkserver moosefs-gui moosefs-mount nginxConfirm the web monitor backend answers on the loopback interface and the MooseFS filesystem is mounted:
curl -sS -o /dev/null -w 'monitor backend HTTP %{http_code}\n' http://127.0.0.1:9425/mfs.cgi findmnt --noheadings --output SOURCE,FSTYPE,TARGET /srv/moosefsThe mount source reads mfs#127.0.0.1:9421 with filesystem type fuse, which confirms the mount is genuinely MooseFS and not an ordinary directory. Inspect the cluster with the MooseFS command line client, which talks to the master on loopback:
mfscli -H 127.0.0.1 -SIN mfscli -H 127.0.0.1 -SCS-SIN prints the cluster information summary and -SCS lists the chunkservers with their state and free space.
Use the Filesystem
The MooseFS volume at /srv/moosefs behaves like any other directory. Write a file, read it back, and confirm the bytes really landed in MooseFS chunk storage:
echo "hello from sac MooseFS" > /srv/moosefs/hello.txt cat /srv/moosefs/hello.txt mfsfileinfo /srv/moosefs/hello.txt rm -f /srv/moosefs/hello.txtmfsfileinfo reports the chunk backing the file and the chunkserver copy holding it (copy 1: with status:VALID). Applications write to /srv/moosefs exactly as they would to a local path; MooseFS transparently stores the data as distributed chunks. To make the volume available to other machines you widen the MooseFS export list and open the chunkserver port to those peers, which is the same operation as adding a chunkserver described below.
Security Model
The image is hardened so the MooseFS protocol is never exposed to the network:
- The client control port (9421), the metalogger port (9419) and the web monitor (9425) are bound to
127.0.0.1.
- MooseFS refuses a loopback address for the chunkserver to master link, so the master's chunkserver port (9420) and the chunkserver's own port (9422) bind the instance's private IP. An nftables table then drops ports 9419 to 9425 on every non loopback interface, so even those private IP bound ports are unreachable from off the instance regardless of your security group.
- The MooseFS export list permits mounts only from
127.0.0.1/32.
- The only published listener is nginx: port 443 serves the web monitor over TLS behind HTTP Basic Auth, and port 80 redirects to 443.
You can see the published listener and the firewall guard directly:
ss -H -lnt 'sport = :443'
sudo nft list table inet sac_moosefsBecause the monitor password and the TLS certificate are generated per instance on first boot, no two instances share credentials and the captured image contains no valid credential at all.
Adding Chunkservers for Redundancy
A single instance holds one copy of every chunk, so on its own this image provides no fault tolerance. To get real redundancy, add one or more chunkservers on separate instances and raise the storage goal so each chunk is copied to more than one chunkserver.
At a high level:
- Launch additional instances (any Linux host with the MooseFS chunkserver package installed) in the same VPC, each with their own storage disk for chunks.
- On the master instance, allow the new peer to reach the master's chunkserver port (9420) by inserting an accept rule ahead of the drop rule in the nftables guard and opening 9420 to that peer in your AWS security group. For example, to allow a peer at a private address:
sudo nft insert rule inet sac_moosefs input ip saddr <private-ip> tcp dport 9420 accept- Point each new chunkserver at the master's private IP (
MASTER_HOSTin/etc/mfs/mfschunkserver.cfg) and start it; it registers with the master and appears on the Chunkservers tab.
- Raise the goal on the directories or files that need redundancy so MooseFS keeps more than one copy of each chunk:
# run this once a second chunkserver at <private-ip> has registered with the master mfssetgoal -r 2 /srv/moosefsWith two chunkservers and a goal of 2, MooseFS keeps a copy of every chunk on each chunkserver, and the health on the Info tab moves from "all in danger" to stable. To widen filesystem access to other clients, add a scoped entry with a password= option to /etc/mfs/mfsexports.cfg and open the client control port to those peers in the same way.
Maintenance and Backup
The MooseFS master metadata and the chunk storage live on the dedicated data volume at /var/lib/mfs, so you can grow storage by resizing that EBS volume and extending the filesystem. To take a consistent copy of the master metadata for backup, snapshot the EBS data volume through the EC2 console or the AWS CLI, or copy /var/lib/mfs/metadata.mfs to <backup-dir> after briefly stopping the master. Security updates are applied to the base operating system at build time, and you can keep the instance current with the usual apt update workflow.
Support
This image is provided by SecureAnyCloud with 24/7 technical support by email and chat, with a guaranteed 24 hour response. We can help with deployment, adding chunkservers for redundancy, configuring TLS and access control, storage and upgrade planning, and troubleshooting. Contact details are on the AWS Marketplace listing and at secureanycloud.com.
Deploy on AWS
Launch MooseFS on AWS with 24/7 support from SecureAnyCloud.
View on Marketplace
Need Help?
Our support team is available 24/7.
sales@secureanycloud.com