13 KiB
OpenList + Iron Local Deployment SOP
This SOP is for a single-machine deployment where:
- OpenList runs locally and mounts Aliyun Drive
- OpenList exposes WebDAV
- Iron runs locally and uses OpenList WebDAV as a remote backend
- Iron also keeps its built-in local backend for local reads and recovery
The result is:
Aliyun Drive
-> OpenList mount
-> OpenList WebDAV
-> Iron WebDAV backend
-> Iron file namespace + policies + replicas
1. What This SOP Assumes
- You want a practical local deployment first, not a public Internet deployment.
- OpenList is used as the cloud-drive access layer.
- Iron is used as the file namespace, replica policy, and repair layer.
- Aliyun Drive data used by Iron should stay inside a dedicated folder, not the cloud-drive root.
This SOP uses:
- OpenList on
127.0.0.1:5244 - Iron on
127.0.0.1:8000 - Docker for OpenList
- local Python +
uvfor Iron
Repository deployment assets used in this SOP:
deploy/openlist/docker-compose.ymldeploy/openlist/.env.exampledeploy/iron/iron.env.exampledeploy/iron/start_iron.shdeploy/systemd/iron.service.example
OpenList also supports manual installation if you prefer not to use Docker.
2. Prerequisites
Prepare these first:
- Docker
- Python 3.11+
- Node.js 20+
uv- a local checkout of this repository
Recommended local ports:
5244for OpenList8000for Iron
3. Recommended Directory Layout
Create a deployment working directory outside the Git repo for runtime data:
mkdir -p ~/iron-deploy/openlist
mkdir -p ~/iron-deploy/iron-data
mkdir -p ~/iron-deploy/iron-temp
mkdir -p ~/iron-deploy/iron-cache
Recommended meaning:
~/iron-deploy/openlist: OpenList runtime data~/iron-deploy/iron-data: Iron local storage root~/iron-deploy/iron-temp: Iron upload temp files~/iron-deploy/iron-cache: Iron remote-read cache
4. Install And Start OpenList
This SOP uses Docker Compose because it is the shortest path to a repeatable local deployment.
Prepare the OpenList env file:
mkdir -p ~/iron-deploy/openlist
cp deploy/openlist/.env.example deploy/openlist/.env
Edit deploy/openlist/.env and set:
OPENLIST_BIND_HOST=127.0.0.1OPENLIST_PORT=5244OPENLIST_DATA_DIR=$HOME/iron-deploy/openlist
Start OpenList:
docker compose -f deploy/openlist/docker-compose.yml --env-file deploy/openlist/.env up -d
Check logs:
docker compose -f deploy/openlist/docker-compose.yml logs -f
On first start, OpenList prints the initial admin password in the logs.
Open the admin UI:
http://127.0.0.1:5244
Log in with the OpenList admin account shown on first boot, then immediately change it to a password you control.
5. Create An OpenList User For Iron
Do not let Iron use the OpenList admin account.
In OpenList:
- go to
Users - create a dedicated user, for example
iron - give it a strong password
- enable the permissions needed for WebDAV write access
For Iron write access through WebDAV, enable at least:
Webdav ReadWebdav ManageMake dir or uploadDeleteRenameMoveCopy
Without these, Iron health checks may pass partially but upload or directory creation can fail.
6. Prepare A Dedicated Aliyun Drive Folder
Create a dedicated folder in Aliyun Drive for Iron, for example:
IronGateway
Do not mount the whole cloud-drive root for Iron unless you explicitly want that.
OpenList supports mounting a specific Aliyun folder by Root Folder ID. The OpenList Aliyundrive Open docs describe using root for the drive root, or a folder file_id if you only want a specific folder exposed.
Recommended approach:
- create
IronGatewayin Aliyun Drive - open that folder in the Aliyun Drive Web UI
- copy the folder
file_idfrom the URL - use that
file_idas the OpenListRoot Folder ID
That gives you one isolation layer in OpenList. Later, Iron will also use its own root_path inside that mount, giving you a second isolation layer.
7. Mount Aliyun Drive In OpenList
In OpenList:
- go to
Storage - click
Add Storage - choose driver
AliYun Drive (Oauth2)/Aliyundrive Open - set mount path to something stable, for example:
/aliyun-iron
- set
Root Folder IDto the dedicated Aliyun folderfile_id - fill the refresh token from the OpenList Aliyundrive Open authorization flow
- save the storage
Important notes from the OpenList docs:
- normal users can leave
Client IDandSecretblank and use the values provided by OpenList - the refresh token used here must come from the Aliyundrive Open flow intended for OpenList
- the docs warn about request rate limiting and advise not to abuse the API
Operational note:
This means the current local-operator path does not require your own Aliyun developer app. That is based on the latest OpenList docs and may change if OpenList or Aliyun changes upstream behavior.
8. Verify OpenList WebDAV Before Touching Iron
OpenList exposes WebDAV at:
http://127.0.0.1:5244/dav/
Before configuring Iron, verify all three things:
- the
ironOpenList user can log in - the mounted path
/aliyun-ironis visible in the OpenList Web UI - the
ironuser has WebDAV write permissions
The practical target for Iron is:
http://127.0.0.1:5244/dav
Iron will then use root_path to place its own dedicated subtree under the OpenList mount.
9. Install Iron
From the repository root:
UV_CACHE_DIR=.uv-cache uv venv .venv
UV_CACHE_DIR=.uv-cache uv pip install --python .venv/bin/python -e '.[dev]'
npm install
npm run build
Apply database migrations:
./.venv/bin/alembic upgrade head
10. Configure Iron Runtime Environment
Iron reads configuration from environment variables. For repeatable deployment, use the provided env template instead of one-off shell exports.
Create the runtime directories and env file:
mkdir -p ~/iron-deploy/runtime/temp
mkdir -p ~/iron-deploy/runtime/local
mkdir -p ~/iron-deploy/runtime/cache
cp deploy/iron/iron.env.example deploy/iron/iron.env
Edit deploy/iron/iron.env and set:
IRON_DATABASE_URL="sqlite+aiosqlite:////Users/your-user/iron-deploy/iron.db"
IRON_BOOTSTRAP_USERNAME="admin"
IRON_BOOTSTRAP_PASSWORD="replace-this-now"
IRON_SECRET_KEY="replace-with-a-long-random-stable-secret"
IRON_UPLOAD_TEMP_DIR="/Users/your-user/iron-deploy/runtime/temp"
IRON_LOCAL_STORAGE_DIR="/Users/your-user/iron-deploy/runtime/local"
IRON_CACHE_DIR="/Users/your-user/iron-deploy/runtime/cache"
IRON_JOB_POLL_INTERVAL_SECONDS="2"
IRON_JOB_BATCH_SIZE="10"
Important:
IRON_SECRET_KEYmust be stable after deployment begins, or stored backend passwords become unreadable.- the bootstrap user is only auto-created when the database has no users yet
- changing
IRON_BOOTSTRAP_PASSWORDlater does not rotate the existing account password
11. Start Iron
Start the service:
./deploy/iron/start_iron.sh
Open:
http://127.0.0.1:8000/app
Log in with:
- username:
IRON_BOOTSTRAP_USERNAME - password:
IRON_BOOTSTRAP_PASSWORD
Health endpoints:
http://127.0.0.1:8000/api/system/health
http://127.0.0.1:8000/api/system/ready
For a background service on Linux, adapt deploy/systemd/iron.service.example into /etc/systemd/system/iron.service.
12. Confirm The Built-In Local Backend
On first startup, Iron auto-creates the default local backend:
- name:
local-default - type:
Local Directory - policy class:
Local
Keep this enabled.
This is the local durable copy that gives you:
- fast reads
- local recovery
- a safe fallback if OpenList or Aliyun is temporarily unavailable
13. Add OpenList As A WebDAV Backend In Iron
In Iron:
- open
Storage - click
Add Backend - choose
OpenList / WebDAV - use a stable backend name, for example
openlist-aliyun - choose policy class
Stable - use read and write priority appropriate for your setup, for example
80
Use config JSON like this:
{
"endpoint_url": "http://127.0.0.1:5244/dav",
"username": "iron",
"password": "your-openlist-iron-password",
"root_path": "aliyun-iron/iron-data",
"verify_ssl": false
}
Meaning:
endpoint_url: OpenList WebDAV rootusername/password: the dedicated OpenList user created for Ironroot_path: Iron's dedicated subtreeverify_ssl:falseonly because this SOP uses local plain HTTP; usetruewhen you switch to HTTPS
Recommended path layering:
Aliyun folder: IronGateway
OpenList mount path: /aliyun-iron
Iron root_path: aliyun-iron/iron-data
This keeps Iron away from both:
- the Aliyun drive root
- the rest of the OpenList namespace
After saving, click Run Check.
Expected result:
- status becomes
Healthy - detail points to the configured WebDAV path
14. Configure Replica Policies
Open Policies in Iron and configure at least these defaults:
Recommended first production baseline:
Require local replica = onStable replicas = 1Opportunistic replicas = 0
Interpretation:
- Iron's default target is 2 total replicas
- every file keeps one local copy
- every file also gets one stable remote copy on OpenList/Aliyun
For each file class (document, image, video, other):
- save the policy
- confirm the OpenList backend is not excluded
- keep the local backend available
Saving a policy automatically enqueues a full reconcile job.
15. First End-To-End Acceptance Test
Use this exact sequence:
- in Iron, upload a small text file
- open the file detail drawer and check the
Storagetab - confirm the desired backend list includes:
- local backend
- OpenList WebDAV backend
- wait for the replica to become ready, or go to
Jobsand run pending jobs - in OpenList, browse the mount path and confirm the file exists under:
/aliyun-iron/iron-data/...
- in Aliyun Drive, verify the file appears under the dedicated
IronGatewayfolder
Expected outcome:
- Iron can upload locally
- Iron can replicate to OpenList WebDAV
- OpenList writes into the dedicated Aliyun subtree
After the first manual upload check, run the real acceptance suite:
./.venv/bin/python scripts/real_openlist_suite.py
Useful focused runs:
./.venv/bin/python scripts/real_openlist_acceptance.py
./.venv/bin/python scripts/real_openlist_chaos_acceptance.py
./.venv/bin/python scripts/real_openlist_multi_backend_acceptance.py
./.venv/bin/python scripts/real_openlist_multi_backend_chaos.py
The suite covers:
- baseline upload, reconcile, download, and direct WebDAV read
- large-file range reads
- forced remote recovery after local file deletion
- OpenList stop/start recovery
- multi-backend placement, avoidance, re-enable, and replica healing
- recycle-bin delete and restore with replica validation
Current remote object layout note:
- Iron stores backend replicas under a structured application object tree such as
objects/file/sha256/73/35/<hash>.blob - this is intentional application storage layout, not an attempt to disguise replicas as user-authored media files
- keep Iron inside a dedicated OpenList mount subtree rather than mixing it with personal root folders
- because the project is still in active development, this layout is treated as the current source of truth rather than a backward-compatible migration target
- reserved subtrees include
objects/preview/...,objects/export/metadata/..., andobjects/manifest/...for future generated artifacts and control files
16. What To Check If It Fails
OpenList backend check fails in Iron
Check:
- OpenList is reachable on
127.0.0.1:5244 - WebDAV URL is exactly
/dav - the OpenList
ironuser password is correct - WebDAV permissions include write-related permissions
root_pathstarts with the OpenList mount path, for examplealiyun-iron/iron-data
Iron uploads succeed locally but remote replica never appears
Check:
Jobspage for failed reconcile or replication jobs- OpenList user permissions
- placement policy excludes or preferred backend settings
- whether the WebDAV backend is enabled
Files land in the wrong Aliyun location
Check:
- OpenList
Root Folder ID - OpenList mount path
- Iron
root_path
Usually this is a path-scoping mistake, not a storage corruption issue.
17. Recommended Ongoing Operations
For a stable local deployment:
- keep OpenList and Iron on localhost unless you add a reverse proxy and auth hardening
- keep
IRON_SECRET_KEYunchanged - back up:
iron.db~/iron-deploy/openlist~/iron-deploy/runtime/local~/iron-deploy/runtime/cache
- run backend health checks from the Iron
Storagepage after OpenList upgrades - review the Iron
Jobspage when replicas lag or a cloud drive is rate-limited
18. Source References
- OpenList install guide: docs.openlist.team/guide/install
- OpenList manual install guide: docs.openlist.team/guide/install/manual
- OpenList WebDAV guide: docs.openlist.team/guide/webdav
- OpenList Aliyundrive Open guide: doc.openlist.team/guide/drivers/aliyundrive_open
- Iron quick start and env vars: README
- Iron API backend types and WebDAV notes: API
- Iron storage architecture notes: Architecture