SeaweedFS on Ubuntu 24.04 on Azure User Guide
Overview
This guide covers the deployment and configuration of SeaweedFS on Ubuntu 24.04 on Azure using cloudimg Azure Marketplace images. SeaweedFS is a fast, simple distributed storage system for blobs, objects and files. It exposes an S3 compatible API alongside a filer that provides a browsable web interface, so tools written for the Amazon S3 wire protocol (aws-cli, any aws-sdk, Restic, rclone, backup agents, data pipelines) work against it unchanged.
The image ships SeaweedFS 4.39 (the latest stable release, installed from the official GitHub release artefact and checksum verified). A single weed server process runs the master, volume server, filer and S3 gateway together — a complete object store on one virtual machine. Everything internal is bound to loopback; an nginx TLS front publishes exactly two endpoints:
-
S3 API on
https://<vm-ip>:8333, authenticated with AWS SigV4 access and secret keys. -
Filer web UI on
https://<vm-ip>/, protected by HTTP Basic Auth.
On every fresh customer virtual machine, seaweedfs-firstboot.service generates a per-VM S3 access key and secret key, a filer UI password, and a TLS certificate bound to the VM's IP, then records them to /root/seaweedfs-credentials.txt (mode 0600, root only). No two virtual machines ever share credentials, and there is no default login.
What is included:
-
SeaweedFS 4.39
weedbinary at/usr/local/bin/weed(master + volume + filer + S3 in one server) -
seaweedfs.servicesystemd unit auto-starting on boot, all listeners bound to 127.0.0.1 -
nginx TLS front:
:443filer web UI (Basic Auth),:8333S3 API (SigV4),:80redirect to HTTPS -
seaweedfs-firstboot.servicesystemd oneshot that generates per-VM S3 keys, filer password and TLS cert -
AWS CLI v2 preinstalled at
/usr/local/bin/awsfor command-line S3 operations -
Data directory at
/var/lib/seaweedfs -
Ubuntu 24.04 LTS base with latest security patches applied at build time
-
Azure Linux Agent for seamless cloud integration and SSH key injection
-
24/7 cloudimg support with guaranteed 24 hour response SLA
Prerequisites
-
An active Azure subscription
-
A subscription to the SeaweedFS 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 development and small workloads. Production deployments should use Standard_D2s_v3 or larger and attach one or more Premium SSD data disks mounted at /var/lib/seaweedfs for capacity and throughput.
Step 1: Deploy from the Azure Portal
Navigate to Marketplace in the Azure Portal, search for SeaweedFS, select the cloudimg publisher entry, and click Create.
On the Networking tab attach a network security group that allows inbound TCP 22 from your management IP range, TCP 443 (the filer web UI) from your admin networks, and TCP 8333 (the S3 API) from your application networks. The internal master, volume and filer ports are bound to loopback and are never exposed.
Click Review + create, wait for validation, then Create. Deployment takes around two minutes.
Step 2: Deploy from the Azure CLI
RG="seaweedfs-prod"
LOCATION="eastus"
VM_NAME="seaweedfs-01"
ADMIN_USER="azureuser"
GALLERY_IMAGE_ID="/subscriptions/<sub-id>/resourceGroups/azure-cloudimg/providers/Microsoft.Compute/galleries/cloudimgGallery/images/seaweedfs-ubuntu-24-04/versions/<version>"
SSH_KEY="$(cat ~/.ssh/id_rsa.pub)"
az group create --name "$RG" --location "$LOCATION"
az network vnet create \
--resource-group "$RG" \
--name seaweedfs-vnet --address-prefix 10.95.0.0/16 \
--subnet-name seaweedfs-subnet --subnet-prefix 10.95.1.0/24
az network nsg create --resource-group "$RG" --name seaweedfs-nsg
az network nsg rule create \
--resource-group "$RG" --nsg-name seaweedfs-nsg \
--name allow-ssh --priority 100 \
--source-address-prefixes "<your-mgmt-cidr>" \
--destination-port-ranges 22 --access Allow --protocol Tcp
az network nsg rule create \
--resource-group "$RG" --nsg-name seaweedfs-nsg \
--name allow-filer-ui --priority 110 \
--source-address-prefixes "<your-mgmt-cidr>" \
--destination-port-ranges 443 --access Allow --protocol Tcp
az network nsg rule create \
--resource-group "$RG" --nsg-name seaweedfs-nsg \
--name allow-s3-api --priority 120 \
--source-address-prefixes 10.95.0.0/16 \
--destination-port-ranges 8333 --access Allow --protocol Tcp
az vm create \
--resource-group "$RG" --name "$VM_NAME" \
--image "$GALLERY_IMAGE_ID" \
--size Standard_B2s --storage-sku StandardSSD_LRS \
--admin-username "$ADMIN_USER" --ssh-key-values "$SSH_KEY" \
--vnet-name seaweedfs-vnet --subnet seaweedfs-subnet --nsg seaweedfs-nsg \
--public-ip-sku Standard
Step 3: Connect via SSH
ssh azureuser@<vm-ip>
seaweedfs.service and nginx.service will already be running, and seaweedfs-firstboot.service will already have generated the per-VM credentials and TLS certificate.
Step 4: Verify the Services
sudo systemctl is-active seaweedfs.service nginx.service
Expected: active twice. Confirm the firstboot sentinel:
sudo test -f /var/lib/cloudimg/seaweedfs-firstboot.done && echo FIRSTBOOT_DONE
Confirm the public TLS listeners and that the internal ports are bound to loopback only:
sudo ss -tln | grep -E ':(443|8333|8888|8334|9333) '
You will see 0.0.0.0:443 and 0.0.0.0:8333 (public, TLS) while the filer 8888, S3 backend 8334 and master 9333 are bound to 127.0.0.1.

Step 5: Retrieve the Per-VM Credentials
sudo cat /root/seaweedfs-credentials.txt
You will see the per-VM S3 access key, S3 secret key, the filer UI user and password, and the two endpoint URLs:
S3_ACCESS_KEY=<S3_ACCESS_KEY>
S3_SECRET_KEY=<S3_SECRET_KEY>
FILER_UI_USER=<FILER_UI_USER>
FILER_UI_PASSWORD=<FILER_UI_PASSWORD>
S3_ENDPOINT_URL=https://<vm-ip>:8333
FILER_UI_URL=https://<vm-ip>/
Store these values in your secret store. The file is mode 0600 (root only).
sudo /usr/local/bin/weed version

Step 6: First Login to the Filer Web UI
Open https://<vm-ip>/ in your browser. The endpoint uses a per-VM self-signed certificate, so your browser will prompt you to proceed on the first visit. You will then be challenged for HTTP Basic Auth — sign in with the FILER_UI_USER and FILER_UI_PASSWORD from Step 5. The filer landing page lists the storage root:

Each S3 bucket appears as a directory under /buckets/. Click into /buckets/ to browse your buckets and their objects directly in the browser:

The filer UI can also create folders and upload files directly. Navigate into any directory and use the upload control to add objects, which are then immediately readable through the S3 API:

Step 7: Round-trip Test from the CLI
The AWS CLI is preinstalled. This reads the per-VM S3 keys straight from the credentials file and performs a full create-bucket, put, get, verify, delete round-trip through the TLS S3 endpoint:
export AWS_ACCESS_KEY_ID="$(sudo awk -F= '/^S3_ACCESS_KEY=/{print $2}' /root/seaweedfs-credentials.txt)"
export AWS_SECRET_ACCESS_KEY="$(sudo awk -F= '/^S3_SECRET_KEY=/{print $2}' /root/seaweedfs-credentials.txt)"
export AWS_DEFAULT_REGION="us-east-1"
EP="--no-verify-ssl --endpoint-url https://127.0.0.1:8333"
aws $EP s3 mb s3://cloudimg-demo
echo "cloudimg-roundtrip-ok" > /tmp/probe.txt
aws $EP s3 cp /tmp/probe.txt s3://cloudimg-demo/probe.txt
aws $EP s3 cp s3://cloudimg-demo/probe.txt /tmp/probe-back.txt
cat /tmp/probe-back.txt
aws $EP s3 rm s3://cloudimg-demo/probe.txt
aws $EP s3 rb s3://cloudimg-demo
Expected output includes make_bucket, the upload and download lines, cloudimg-roundtrip-ok, then clean removals. The --no-verify-ssl flag is only needed for the self-signed certificate on a first local connection.

Step 8: List Buckets and Objects
export AWS_ACCESS_KEY_ID="$(sudo awk -F= '/^S3_ACCESS_KEY=/{print $2}' /root/seaweedfs-credentials.txt)"
export AWS_SECRET_ACCESS_KEY="$(sudo awk -F= '/^S3_SECRET_KEY=/{print $2}' /root/seaweedfs-credentials.txt)"
export AWS_DEFAULT_REGION="us-east-1"
aws --no-verify-ssl --endpoint-url https://127.0.0.1:8333 s3 ls
To list the objects inside a bucket, add the bucket name:
export AWS_ACCESS_KEY_ID="$(sudo awk -F= '/^S3_ACCESS_KEY=/{print $2}' /root/seaweedfs-credentials.txt)"
export AWS_SECRET_ACCESS_KEY="$(sudo awk -F= '/^S3_SECRET_KEY=/{print $2}' /root/seaweedfs-credentials.txt)"
export AWS_DEFAULT_REGION="us-east-1"
aws --no-verify-ssl --endpoint-url https://127.0.0.1:8333 s3 ls s3://cloudimg-demo --recursive || true
Step 9: Connect from Application Code
Any aws-sdk works. A representative Python boto3 example, pointing at the public S3 endpoint with the per-VM keys:
python3 -c "
import boto3, urllib3
urllib3.disable_warnings()
s3 = boto3.client(
's3',
endpoint_url='https://<vm-ip>:8333',
aws_access_key_id='<S3_ACCESS_KEY>',
aws_secret_access_key='<S3_SECRET_KEY>',
region_name='us-east-1',
verify=False,
)
print(s3.list_buckets())
"
For production, install the per-VM certificate (/etc/seaweedfs/tls/seaweedfs.crt) into your client's trust store instead of disabling verification, or front SeaweedFS with a certificate from a public CA.

Step 10: Server Components
Component Path
weed binary /usr/local/bin/weed
AWS CLI v2 /usr/local/bin/aws
Data directory /var/lib/seaweedfs
S3 identities config /etc/seaweedfs/s3.json
TLS certificate + key /etc/seaweedfs/tls/seaweedfs.crt, seaweedfs.key
Filer Basic Auth file /etc/seaweedfs/filer.htpasswd
nginx site /etc/nginx/sites-available/seaweedfs
Systemd unit /etc/systemd/system/seaweedfs.service
Firstboot script /usr/local/sbin/seaweedfs-firstboot.sh
Firstboot service /etc/systemd/system/seaweedfs-firstboot.service
Credentials file /root/seaweedfs-credentials.txt
Firstboot sentinel /var/lib/cloudimg/seaweedfs-firstboot.done
Step 11: Managing the Services
Status:
sudo systemctl status seaweedfs.service --no-pager | head -n 8
Restart (both the server and the TLS front):
sudo systemctl restart seaweedfs.service
sudo systemctl restart nginx.service
View recent activity (systemd journal), filtered to the component and cluster lines:
sudo journalctl -u seaweedfs.service --no-pager -n 40 | grep -iE 'start seaweed|s3 api|filer|volume server|master' | grep -viE 'error|refused|fail' | tail -8
Drop the filters (sudo journalctl -u seaweedfs.service --no-pager -n 40) to see the full log including any warnings.
Step 12: Production Hardening
The shipped image is single-node — appropriate for development, staging, and small to medium workloads. Production deployments should:
-
Attach a dedicated data disk — add a Premium SSD, format
xfs, mount at/var/lib/seaweedfs, and set ownershipseaweedfs:seaweedfsso storage scales independently of the OS disk. -
Use a CA-signed certificate — replace
/etc/seaweedfs/tls/seaweedfs.crtandseaweedfs.keywith a certificate for your DNS name (the cloudimgnginx-ssl-certbot-ubuntu-24-04image automates Let's Encrypt), then clients no longer need--no-verify-ssl. -
Restrict the filer UI (443) — admin networks only via NSG.
-
Restrict the S3 API (8333) — to your application server subnets only via NSG.
-
Add scoped S3 identities — edit
/etc/seaweedfs/s3.jsonto add per-application access keys with least-privilegeactions(for exampleRead,Write,Liston specific buckets) instead of sharing the admin key, then restartseaweedfs.service.
Step 13: Troubleshooting
Cannot reach the filer UI on port 443
-
Confirm services running:
sudo systemctl is-active seaweedfs.service nginx.service -
Confirm listeners bound:
sudo ss -tln | grep -E ':443|:8333' -
Check the journal:
sudo journalctl -u seaweedfs.service --no-pager -n 50 -
Confirm the NSG allows TCP 443 from your client source IP
S3 client errors with "InvalidAccessKeyId" or "SignatureDoesNotMatch"
-
Confirm the access key is exactly the value of
S3_ACCESS_KEYfrom the credentials file -
Confirm the secret is exactly
S3_SECRET_KEYwith no whitespace -
Confirm
region_nameis set tous-east-1 -
Confirm the endpoint is
https://<vm-ip>:8333(S3 API), not443(the filer UI)
PutObject fails with an internal error
-
Confirm free disk on the data volume:
df -h /var/lib/seaweedfs -
Check the master can grow volumes:
curl -s http://127.0.0.1:9333/vol/status
Filer UI prompts for a password that is not accepted
-
Re-read credentials:
sudo cat /root/seaweedfs-credentials.txt -
Confirm the firstboot sentinel exists:
ls -la /var/lib/cloudimg/seaweedfs-firstboot.done
Step 14: Security Recommendations
-
Restrict both public ports — 443 (filer UI) and 8333 (S3 API) to trusted networks via NSG; never expose them to the open internet without additional controls
-
Replace the self-signed certificate with a CA-signed one before serving anything beyond a private VNet
-
Create scoped S3 identities in
/etc/seaweedfs/s3.json; never share the admin access key with applications -
Rotate the filer UI password by regenerating the
/etc/seaweedfs/filer.htpasswdentry and reloading nginx -
Keep SeaweedFS updated by replacing
/usr/local/bin/weedwith a newer release binary; data under/var/lib/seaweedfsis preserved across upgrades -
Store the credentials in your secret store and keep the 0600 file readable by root only
Step 15: Support and Licensing
SeaweedFS is open source under the Apache License 2.0, which permits commercial use, modification and redistribution. cloudimg ships the upstream Apache-2.0 build unmodified and retains the upstream license and notices.
cloudimg provides commercial support for the cloudimg image (deployment, configuration, integration with other cloudimg products) separately from the SeaweedFS project itself.
-
Email: support@cloudimg.co.uk
-
Website: www.cloudimg.co.uk
-
Support hours: 24/7 with guaranteed 24 hour response SLA
Deploy on Azure
Launch SeaweedFS on Ubuntu 24.04 with 24/7 support from cloudimg.
View on Marketplace
Need Help?
Our support team is available 24/7.
support@cloudimg.co.uk