Download index.html from getreadystack/seaweedfs-migration-lint: direct link, hf CLI and curl.
- Browser
- Download file 42.5 kB
-
https://huggingface.co/spaces/getreadystack/seaweedfs-migration-lint/resolve/main/index.html
- Command line
-
hf download hf://spaces/getreadystack/seaweedfs-migration-lint/index.html
-
curl -L -o index.html https://huggingface.co/spaces/getreadystack/seaweedfs-migration-lint/resolve/main/index.html
42.5 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8"> | |
| <meta name="viewport" content="width=device-width,initial-scale=1"> | |
| <title>SeaweedFS MinIO Migration — check your files for free</title> | |
| <meta name="description" content="This free tool flags MinIO images, settings and mc features in Compose, Kubernetes, environment files and scripts, with SeaweedFS fixes."> | |
| <style> | |
| :root{color-scheme:light}body{margin:0;font:15px/1.55 system-ui,-apple-system,"Segoe UI",sans-serif;background:#faf9f5;color:#1a1512} | |
| .wrap{max-width:960px;margin:0 auto;padding:28px 18px 60px}h1{font-size:26px;margin:0 0 6px}.lede{color:#4a403a;margin:0 0 16px} | |
| textarea{width:100%;min-height:260px;font:13px/1.45 ui-monospace,Menlo,Consolas,monospace;padding:12px;border:1px solid #d9d0c4;border-radius:8px;box-sizing:border-box} | |
| .bar{display:flex;gap:10px;align-items:center;margin:12px 0}button{font:600 15px system-ui;padding:10px 18px;border:0;border-radius:8px;background:#1a1512;color:#fff;cursor:pointer} | |
| input[type=date]{font:14px system-ui;padding:8px;border:1px solid #d9d0c4;border-radius:6px} | |
| table{border-collapse:collapse;width:100%;font-size:14px;margin-top:10px}th,td{text-align:left;padding:8px 10px;border-bottom:1px solid #eee;vertical-align:top}th{font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:#7a6e65} | |
| .sev.error{color:#a8551f;font-weight:700}.sev.warn,.sev.warning{color:#96691f}.ok{color:#2a6446;font-weight:600}.sum{font-weight:600} | |
| .note{font-size:13px;color:#7a6e65;margin-top:18px}#paid{margin-top:22px;padding:14px 16px;border:1px solid #e2d8cb;border-radius:10px;background:#fffdfa} | |
| </style> | |
| <script defer data-auto-init src="https://cdn.jsdelivr.net/npm/@polar-sh/checkout@latest/dist/embed.global.js"></script> | |
| <script data-grow-initializer="">!(function(){window.growMe||((window.growMe=function(e){window.growMe._.push(e);}),(window.growMe._=[]));var e=document.createElement("script");(e.type="text/javascript"),(e.src="https://faves.grow.me/main.js"),(e.defer=!0),e.setAttribute("data-grow-faves-site-id","U2l0ZTphZjljMzgyMC0yMmU5LTRhYjgtYTIxNS03OTRhMGY1N2ExYzM=");var t=document.getElementsByTagName("script")[0];t.parentNode.insertBefore(e,t);})();</script> | |
| <!--yj-canon-s101--><link rel="canonical" href="https://getreadystack.com/tools/seaweedfs-migration-lint"><style data-yj-mfit="1">#out{max-width:100%}#out td,#out th{overflow-wrap:anywhere}#out pre,#out code{white-space:pre-wrap;overflow-wrap:anywhere}@media (max-width:640px){table{display:block;max-width:100%;overflow-x:auto}pre{max-width:100%;overflow-x:auto}code,a{overflow-wrap:anywhere}img,svg,video,canvas,iframe{max-width:100%}textarea,input,select{max-width:100%;box-sizing:border-box}.yj-lgbar{position:static;justify-content:flex-end;margin:0 0 10px}#out table:not(:has(tr>:nth-child(4))){display:table;table-layout:fixed;width:100%}#out table:has(tr>:nth-child(4)),#out table:has(tr>:nth-child(4)) tbody,#out table:has(tr>:nth-child(4)) tr,#out table:has(tr>:nth-child(4)) td{display:block;width:auto;overflow:visible}#out table:has(tr>:nth-child(4)) thead{display:none}#out table:has(tr>:nth-child(4)) tr{padding:10px 0;border-bottom:1px solid rgba(128,128,128,.28)}#out table:has(tr>:nth-child(4)) td{border:0;padding:1px 0}#out table:has(tr>:nth-child(4)) td:nth-child(-n+3){display:inline-block;margin-right:10px;font-size:12px;opacity:.78}}</style> | |
| </head> | |
| <body> | |
| <div class="wrap"> | |
| <h1>SeaweedFS MinIO Migration — check your files for free</h1> | |
| <p class="lede">SeaweedFS migration check for MinIO docker-compose, Kubernetes, .env and mc scripts: flags the archived minio/minio image, MINIO_* settings and mc features SeaweedFS lacks, with the SeaweedFS fix. Runs entirely in your browser — nothing is uploaded.</p> | |
| <textarea id="src" spellcheck="false">services: | |
| minio: | |
| image: quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z | |
| command: server /data --console-address ":9001" | |
| ports: | |
| - "9000:9000" | |
| - "9001:9001" | |
| environment: | |
| MINIO_ROOT_USER: admin | |
| MINIO_ROOT_PASSWORD: change-me-now | |
| MINIO_DOMAIN: s3.acme.internal | |
| MINIO_NOTIFY_WEBHOOK_ENABLE_THUMBS: "on" | |
| MINIO_NOTIFY_WEBHOOK_ENDPOINT_THUMBS: http://thumbs:8080/events | |
| MINIO_KMS_KES_ENDPOINT: https://kes:7373 | |
| volumes: | |
| - minio-data:/data | |
| healthcheck: | |
| test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] | |
| interval: 30s | |
| createbuckets: | |
| image: minio/mc | |
| depends_on: | |
| - minio | |
| entrypoint: > | |
| /bin/sh -c " | |
| mc alias set local http://minio:9000 admin change-me-now; | |
| mc mb -p local/uploads; | |
| mc admin user add local app app-secret-123; | |
| mc event add local/uploads arn:minio:sqs::THUMBS:webhook --event put; | |
| mc ilm rule add local/uploads --transition-days 30 --transition-tier COLD; | |
| " | |
| app: | |
| image: ghcr.io/acme/web:2.4.1 | |
| environment: | |
| S3_ENDPOINT: http://minio:9000 | |
| S3_BUCKET: uploads | |
| volumes: | |
| minio-data:</textarea> | |
| <div class="bar"><button id="go">Check</button><label>as of <input type="date" id="today"></label></div> | |
| <div id="out" aria-live="polite"></div> | |
| <div id="paid"><strong>Free here:</strong> Every finding in the open file, with the MinIO line that blocks SeaweedFS and the SeaweedFS fix, free and offline. <strong>In the editor:</strong> Scan the whole workspace in one pass and export one migration report for the change ticket. — that part asks for a licence key. <a href="https://getreadystack.com/api/buy/cl/polar_cl_RUMPJtqxgGuqV9WMomFKo1YHdM1cfxvYx6tOb1A28Rl" data-polar-checkout data-polar-checkout-theme="light">Full version: workspace sweep + migration report — $29 once</a></div> | |
| <p class="note">Same engine as the VS Code extension, byte for byte.</p> | |
| </div> | |
| <script>var SW_RULES = [ | |
| {"id": "minio-image", "sev": "error", "pats": [{"re": "(image:|FROM)\\s+[\"']?[\\w.:/-]*\\b(minio/minio|bitnami/minio)(?![\\w-])"}], | |
| "msg": "MinIO server image. The minio/minio GitHub repository is archived and its README says it is no longer maintained; the last community release is RELEASE.2025-10-15T17-29-55Z and the community edition is now source-only, so this image gets no updates.", | |
| "fix": "image: chrislusf/seaweedfs:4.48 (Apache-2.0, released 2026-09-28) with entrypoint weed."}, | |
| {"id": "minio-source-build", "sev": "error", "pats": [{"re": "go\\s+install\\s+github\\.com/minio/minio\\b"}, {"re": "git\\s+clone\\s+\\S*github\\.com/minio/minio(\\.git)?(\\s|$)"}], | |
| "msg": "Builds MinIO from source, the only community path left. MinIO is AGPL-3.0 since the commit \"update license change for MinIO\" of 2021-04-23, and its README says all usage requires validation against AGPLv3 obligations, including release of modified code.", | |
| "fix": "Build or pull SeaweedFS instead (Apache-2.0): chrislusf/seaweedfs:4.48, or go install github.com/seaweedfs/seaweedfs/weed@latest."}, | |
| {"id": "minio-server-cmd", "sev": "warn", "pats": [{"re": "\\bminio\\s+server\\b"}, {"re": "command:\\s*\\[?\\s*[\"']?server[\"']?[\\s,]+[\"']?(/|https?://|\\$\\{)"}], | |
| "msg": "minio server command. SeaweedFS has no minio binary; one process can run master, volume server, filer and the S3 gateway.", | |
| "fix": "entrypoint: weed · command: server -dir=/data -s3 (or weed s3 -filer=filer:8888 for a split setup)."}, | |
| {"id": "minio-console", "sev": "warn", "pats": [{"re": "--console-address"}, {"re": "\\bMINIO_BROWSER\\b"}], | |
| "msg": "MinIO Console setting. SeaweedFS has no MinIO Console; its web admin is a separate process.", | |
| "fix": "weed admin -masters=master:9333 (Admin UI, default port 23646) and drop the 9001 port mapping."}, | |
| {"id": "minio-root-credentials", "sev": "warn", "pats": [{"re": "\\bMINIO_(ROOT_USER|ROOT_PASSWORD|ACCESS_KEY|SECRET_KEY)(_FILE)?\\b"}], | |
| "msg": "MinIO root credentials. SeaweedFS does not read MINIO_* variables, so the gateway starts without these keys.", | |
| "fix": "AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (read only when no -config is given), or an s3.json identity with actions [\"Admin\",\"Read\",\"Write\"] passed as -s3.config."}, | |
| {"id": "minio-port-9000", "sev": "warn", "pats": [{"re": "(^|[\\s\"'-])(\\d+\\.\\d+\\.\\d+\\.\\d+:)?\\d{2,5}:9000\\b"}, {"re": "(containerPort|targetPort):\\s*9000\\b"}], | |
| "msg": "Port 9000 is MinIO's S3 API port. The SeaweedFS S3 gateway listens on 8333 by default.", | |
| "fix": "Map 8333:8333, or start with -s3.port=9000 to keep the old client port."}, | |
| {"id": "minio-endpoint", "sev": "info", "pats": [{"re": "https?://[^\\s\"']*minio[^\\s\"']*"}, {"re": "\\bMINIO_(ENDPOINT|SERVER_URL|URL)\\b"}], | |
| "msg": "Client endpoint points at the MinIO service.", | |
| "fix": "Point it at http://seaweedfs:8333 and keep path-style addressing unless the gateway runs with -domainName."}, | |
| {"id": "mc-admin-iam", "sev": "warn", "pats": [{"re": "\\bmc\\s+admin\\s+(user|policy|group|accesskey|service)\\b"}], | |
| "msg": "mc admin calls the MinIO admin API, which SeaweedFS does not implement.", | |
| "fix": "SeaweedFS implements the IAM API on the S3 endpoint: aws iam create-user --endpoint-url http://seaweedfs:8333, or list identities in s3.json."}, | |
| {"id": "bucket-notification", "sev": "warn", "pats": [{"re": "\\bMINIO_NOTIFY_\\w+"}, {"re": "\\bmc\\s+event\\s+add\\b"}], | |
| "msg": "Bucket notification. SeaweedFS lists GetBucketNotificationConfiguration and PutBucketNotificationConfiguration as not supported, so this consumer stops receiving events.", | |
| "fix": "Move the consumer to SeaweedFS filer metadata events (weed filer.meta.tail -pathPrefix=/buckets/\u003cbucket\u003e) or a ListObjectsV2 poll, and test it before cutover."}, | |
| {"id": "bucket-replication", "sev": "warn", "pats": [{"re": "\\bmc\\s+(admin\\s+)?replicate\\b"}], | |
| "msg": "MinIO replication. SeaweedFS lists GetBucketReplication, PutBucketReplication and DeleteBucketReplication as not supported.", | |
| "fix": "weed filer.sync -a=\u003cfilerA\u003e:8888 -b=\u003cfilerB\u003e:8888 (resumable continuous sync between two clusters)."}, | |
| {"id": "lifecycle-transition", "sev": "warn", "pats": [{"re": "\\bmc\\s+ilm\\s+tier\\b"}, {"re": "--transition-(days|tier)\\b"}], | |
| "msg": "Lifecycle transition to a remote tier. SeaweedFS supports PutBucketLifecycleConfiguration, but transition rules are not supported.", | |
| "fix": "Keep expiry rules only (--expire-days) and plan cold-tier moves outside the S3 lifecycle API."}, | |
| {"id": "s3-select", "sev": "warn", "pats": [{"re": "\\bmc\\s+sql\\b"}, {"re": "\\b(select_object_content|SelectObjectContent)\\b"}], | |
| "msg": "S3 Select. SeaweedFS lists SelectObjectContent as not supported.", | |
| "fix": "GET the object and filter it in the job (DuckDB, pandas, jq)."}, | |
| {"id": "minio-kms", "sev": "warn", "pats": [{"re": "\\bMINIO_KMS_\\w+"}], | |
| "msg": "MinIO KMS/KES setting. SeaweedFS SSE-KMS talks to AWS KMS, Google Cloud KMS or OpenBao/Vault, not to KES.", | |
| "fix": "Point SSE-KMS at OpenBao/Vault and copy encrypted objects through the S3 API (read from MinIO, write to SeaweedFS), never the drive folders."}, | |
| {"id": "minio-domain", "sev": "info", "pats": [{"re": "\\bMINIO_DOMAIN\\b"}], | |
| "msg": "MINIO_DOMAIN turns on virtual-host style bucket URLs.", | |
| "fix": "weed s3 -domainName=\u003csuffix\u003e (or -s3.domainName with weed server) for {bucket}.{domainName} URLs."}, | |
| {"id": "minio-identity", "sev": "info", "pats": [{"re": "\\bMINIO_IDENTITY_(OPENID|LDAP)_\\w+"}], | |
| "msg": "MinIO OpenID or LDAP identity provider.", | |
| "fix": "SeaweedFS STS supports AssumeRoleWithWebIdentity and AssumeRoleWithLDAPIdentity; configure it in the advanced IAM file passed as -iam.config."}, | |
| {"id": "minio-healthcheck", "sev": "info", "pats": [{"re": "/minio/health/(live|ready|cluster)"}], | |
| "msg": "MinIO health endpoint; SeaweedFS serves its health check on /healthz and /status instead.", | |
| "fix": "GET /healthz (or /status) on the S3 port 8333."}, | |
| {"id": "minio-disk-format", "sev": "info", "pats": [{"re": "\\.minio\\.sys\\b"}, {"re": "\\bxl\\.meta\\b"}], | |
| "msg": "MinIO on-disk format (.minio.sys, xl.meta). SeaweedFS cannot read MinIO data folders.", | |
| "fix": "Copy through the S3 API with rclone sync or mc mirror from MinIO to the SeaweedFS endpoint, then compare object counts."} | |
| ] | |
| ;</script> | |
| <script>/* SeaweedFS migration lint: one engine for VS Code and the free web page. */ | |
| (function () { | |
| var RULES = (typeof module !== 'undefined') ? require('./rules.json') : window.SW_RULES; | |
| var COMPILED = RULES.map(function (r) { | |
| return { rule: r, pats: (r.pats || []).map(function (p) { return new RegExp(p.re); }) }; | |
| }); | |
| function check(text, opts) { | |
| var lines = String(text || '').split(/\r?\n/); | |
| var findings = []; | |
| for (var i = 0; i < lines.length; i++) { | |
| var line = lines[i]; | |
| if (/^\s*(#|\/\/)/.test(line)) continue; | |
| for (var k = 0; k < COMPILED.length; k++) { | |
| var r = COMPILED[k].rule; | |
| for (var p = 0; p < COMPILED[k].pats.length; p++) { | |
| if (COMPILED[k].pats[p].test(line)) { | |
| findings.push({ check: r.id, sev: r.sev, msg: r.msg + ' Fix: ' + r.fix, line: i + 1 }); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| return { findings: findings }; | |
| } | |
| var api = { engine: { check: check }, RULES: RULES, RULE_COUNT: RULES.length }; | |
| if (typeof module !== 'undefined') module.exports = api; | |
| if (typeof window !== 'undefined') window.SWENGINE = api; | |
| })(); | |
| </script> | |
| <script>// ⛔뼈대 — kit/scaffold.py 가 찍는다 (s143). findings [{check,sev,msg,line?}] → 글/HTML. 같은 파일이 Node 와 브라우저에서 산다. | |
| ; | |
| function escapeHtml(s) { return String(s == null ? '' : s).replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"'); } | |
| function summaryLine(res) { | |
| const f = (res && res.findings) || []; const e = f.filter(function (x) { return String(x.sev || 'error').toLowerCase().startsWith('err'); }).length; | |
| return f.length ? (f.length + ' finding' + (f.length === 1 ? '' : 's') + ' (' + e + ' error' + (e === 1 ? '' : 's') + ')') : 'Clean — no findings.'; | |
| } | |
| function toText(res, label) { | |
| const f = (res && res.findings) || []; | |
| const lines = ['== ' + (label || '') + ' — ' + summaryLine(res)]; | |
| f.forEach(function (x) { lines.push(' ' + String(x.sev || 'error').toUpperCase().slice(0, 4) + ' ' + (x.line ? 'L' + x.line + ' ' : '') + (x.check || x.id || '') + ' ' + (x.msg || x.message || '')); }); | |
| return lines.join('\n'); | |
| } | |
| function toHtml(res) { | |
| const f = (res && res.findings) || []; | |
| if (!f.length) return '<p class="ok">' + escapeHtml(summaryLine(res)) + '</p>'; | |
| const rows = f.map(function (x) { return '<tr><td class="sev ' + escapeHtml(String(x.sev || 'error')) + '">' + escapeHtml(String(x.sev || 'error')) + '</td><td>' + (x.line ? 'L' + escapeHtml(x.line) : '') + '</td><td><code>' + escapeHtml(x.check || x.id || '') + '</code></td><td>' + escapeHtml(x.msg || x.message || '') + '</td></tr>'; }).join(''); | |
| return '<p class="sum">' + escapeHtml(summaryLine(res)) + '</p><table><thead><tr><th>Level</th><th>Line</th><th>Check</th><th>What</th></tr></thead><tbody>' + rows + '</tbody></table>'; | |
| } | |
| var SWREPORT = { escapeHtml: escapeHtml, summaryLine: summaryLine, toText: toText, toHtml: toHtml }; | |
| if (typeof module !== 'undefined' && module.exports) module.exports = SWREPORT; | |
| else window.SWREPORT = SWREPORT; | |
| </script> | |
| <script> | |
| (function(){ | |
| var src=document.getElementById('src'), out=document.getElementById('out'), go=document.getElementById('go'), today=document.getElementById('today'); | |
| today.value=new Date().toISOString().slice(0,10); | |
| function run(){ try { var res=window.SWENGINE.engine.check(src.value,{today:today.value}); out.innerHTML=window.SWREPORT.toHtml(res); } catch(e){ out.innerHTML='<p class="sev error">Could not run: '+String(e.message||e)+'</p>'; } } | |
| go.onclick=run; if (src.value.trim()) run(); | |
| })(); | |
| </script> | |
| <section data-yj-install="free" style="margin:2rem auto 1rem;max-width:46rem;padding:1.25rem 1.25rem;border:1px solid #cfe3d6;border-radius:12px;background:#f6fbf8;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .4rem;font-size:1.2rem">Install free</h2><p style="margin:0 0 .8rem;color:#41505f">Free for the file open in your editor - no key, no limit. The workspace sweep and the report ask for a key.</p><a href="https://open-vsx.org/extension/readystack/seaweedfs-migration-lint" rel="noopener" data-yj-install-door="ovsx" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'seaweedfs-migration-lint',src:'ovsx',path:location.pathname})],{type:'application/json'}))}catch(e){}" style="display:inline-block;margin:0 .5rem .5rem 0;padding:.6rem 1rem;border-radius:8px;background:#0f7b3f;color:#fff;text-decoration:none;font-weight:600">Open VSX (Cursor, VSCodium)</a><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://getreadystack.com/api/buy/team" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section> | |
| <section data-yj-alert="rule" style="margin:1rem auto 1.5rem;max-width:46rem;padding:1.1rem 1.25rem;border:1px solid #d9dee6;border-radius:12px;background:#fbfcfd;font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif"><b style="font-size:1.05rem">Get one email when this rule changes</b><div style="opacity:.78;margin:.35rem 0 .8rem">We watch the regulation and vendor sources behind SeaweedFS Migration Lint — MinIO Compose & K8s every day. When a rule changes, you get a single email with what changed and the updated check. No newsletter.</div><div style="display:flex;gap:8px;flex-wrap:wrap"><input id="yjae" type="email" placeholder="you@example.com" style="flex:1;min-width:210px;padding:11px 13px;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:#fff;color:inherit"><button id="yjab" style="padding:11px 18px;border-radius:8px;border:0;cursor:pointer;background:#0f7b3f;color:#fff;font:600 15px system-ui,sans-serif">Notify me</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">You're on the list. One email when it changes.</div><script>(function(){var b=document.getElementById("yjab"),e=document.getElementById("yjae");if(!b||!e)return;b.addEventListener("click",function(){var v=e.value.trim();if(!/.+@.+\..+/.test(v))return;try{localStorage.setItem("yj_em","1");}catch(_){}fetch(location.origin+"/api/subscribe",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:v,slug:"seaweedfs-migration-lint",lang:"en",source:"rule_alert"+((b.closest&&b.closest("section")&&b.closest("section").getAttribute("data-yj-moved"))?"_at_result":"")})}).then(function(r){var o=document.getElementById("yjao");o.hidden=false;if(!r.ok){o.textContent="Could not save - please try again.";}}).catch(function(){var o=document.getElementById("yjao");o.hidden=false;o.textContent="Could not save - please try again.";});});})();</script><script>(function(){var e=document.getElementById("yjae"),s=e&&e.closest?e.closest("section"):null,o=document.getElementById("out");if(!s||!o)return;var d=false;function mv(ev){if(d)return;if(ev&&ev.target&&s.contains(ev.target))return;d=true;var b=o;while(b.parentNode&&b.parentNode!==document.body&&b.parentNode.tagName!=="MAIN"&&b.parentNode.tagName!=="ARTICLE")b=b.parentNode;if(!b.parentNode||b===s||b.contains(s))return;try{b.parentNode.insertBefore(s,b.nextSibling);s.setAttribute("data-yj-moved","1");}catch(_){}}document.addEventListener("input",mv,true);document.addEventListener("change",mv,true);document.addEventListener("click",function(ev){var b=ev.target&&ev.target.closest?ev.target.closest("button,input[type=submit]"):null;if(b&&!b.closest("[data-yj],[data-yj-cta],[data-yj-install],[data-yj-alert],.yj-find,.yj-related,#yj-ask,.yjp"))mv(ev);},true);})();</script></section> | |
| <section data-yj-cta="paid" style="margin:3rem auto;max-width:46rem;padding:1.5rem 1.25rem;border:1px solid #d8dee9;border-radius:12px;background:#fbfcfe;font:16px/1.6 system-ui,-apple-system,Segoe UI,sans-serif"><h2 style="margin:0 0 .5rem;font-size:1.25rem">Get the full version <span class="yj-price">$29</span></h2><p class="yj-cta-paid" style="margin:.25rem 0 .6rem;color:#1f2a37">Scan the whole workspace in one pass and export one migration report for the change ticket (every file, line, rule and fix in one Markdown report), $29 once, one licence key per person or team seat.</p><p class="yj-cta-pay" style="margin:.25rem 0 1rem;color:#5b6b7c;font-size:.94rem">One payment, one licence key for this tool. The key is shown right after payment.</p><p class="yj-cta-anchor" style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">DOJ's Fitzpatrick Matrix rates a 15-year litigator at $851/hour for billing year 2026, which is one hour of counsel reading MinIO's AGPL-3.0 obligations.</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_RUMPJtqxgGuqV9WMomFKo1YHdM1cfxvYx6tOb1A28Rl" rel="nofollow" style="display:inline-block;padding:.7rem 1.3rem;border-radius:8px;background:#1b64f2;color:#fff;text-decoration:none;font-weight:600">Buy the full version — $29</a></section> | |
| <!--yj-share-s101--><div style="margin:28px 0 8px;text-align:center"><button id="yjcp" type="button" style="font:inherit;padding:10px 18px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Copy link</button><button id="yjimg" type="button" style="font:inherit;padding:10px 18px;margin-left:8px;border:1px solid #8884;border-radius:10px;background:transparent;cursor:pointer">Save result as image</button></div><script>(function(){var b=document.getElementById("yjimg");if(!b)return;b.addEventListener("click",function(){var o=document.getElementById("out");var txt=(o&&(o.innerText||o.textContent)||"").trim();if(!txt){b.textContent="(no result yet)";setTimeout(function(){b.textContent="Save result as image";},1500);return;}var lines=txt.split(String.fromCharCode(10)).filter(function(x){return x.trim();}).slice(0,10);var W=1200,P=56,c=document.createElement("canvas");c.width=W;var lh=38,H=P*2+70+lines.length*lh+60;c.height=H;var x=c.getContext("2d");x.fillStyle="#1a1512";x.fillRect(0,0,W,H);x.fillStyle="#f3e9d2";x.font="600 34px system-ui,Segoe UI,Arial";var t=(document.title||"").split("|")[0].trim();x.fillText(t.slice(0,54),P,P+34);x.font="22px ui-monospace,Menlo,Consolas,monospace";x.fillStyle="#e8dcc4";for(var i=0;i<lines.length;i++){x.fillText(lines[i].slice(0,88),P,P+70+i*lh+22);}x.font="600 22px system-ui,Segoe UI,Arial";x.fillStyle="#c9a227";var d=location.hostname.replace("www.","");x.fillText(d,W-P-x.measureText(d).width,H-P+6);c.toBlob(function(bl){var u=URL.createObjectURL(bl),a=document.createElement("a");a.href=u;a.download=(t||"result").replace(/[^a-z0-9]+/gi,"-").toLowerCase()+"-"+d+".png";document.body.appendChild(a);a.click();setTimeout(function(){URL.revokeObjectURL(u);a.remove();},2000);},"image/png");});})();</script><script>(function(){var b=document.getElementById("yjcp");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var u=location.href.split("#")[0];function d(){b.textContent="Link copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(u).then(d,function(){prompt("",u);});}else{prompt("",u);}});})();</script> | |
| <script data-yj="yj-view-beacon">(function(){try{var p=location.pathname;var k='yjv:'+p;if(sessionStorage.getItem(k))return;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",ref:(document.referrer||''),src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}catch(e){}})();</script> | |
| <script data-yj="yj-use-beacon">(function(){try{var o=document.getElementById('out');if(!o)return;var p=location.pathname,k='yju:'+p,sent=false;function fire(){if(sent||sessionStorage.getItem(k))return;if(!(o.textContent||'').replace(/\s+/g,'').length)return;sent=true;sessionStorage.setItem(k,'1');fetch('/api/ev',{method:'POST',keepalive:true,headers:{'Content-Type':'application/json'},body:JSON.stringify({path:p,lang:"en",t:'use',src:(function(){try{return (new URLSearchParams(location.search).get('ref')||'').replace(/[^a-z_]/g,'').slice(0,12)}catch(e){return ''}})()})}).catch(function(){});}var mo=new MutationObserver(function(){fire();if(sent)mo.disconnect();});mo.observe(o,{childList:true,characterData:true,subtree:true});}catch(e){}})();</script><div class="yj-home-find"><div class="yj-lgbar"><a href="/" class="yj-lg on">EN</a><a href="/de/" class="yj-lg">DE</a><a href="/ja/" class="yj-lg">JA</a><a href="/es/" class="yj-lg">ES</a><a href="/pt/" class="yj-lg">PT</a></div><section class="yj-find"><h2>Find a tool</h2><input id="yjq" type="search" autocomplete="off" placeholder="Type a product name, format or task"><div id="yjr"></div></section><style>.yj-lgbar{position:absolute;top:14px;right:18px;display:flex;gap:6px;z-index:60}.yj-lg{font:600 12px/1 system-ui,sans-serif;padding:6px 9px;border-radius:4px;text-decoration:none;color:#8b96a3;border:1px solid rgba(140,150,165,.28)}.yj-lg:hover{color:#e8eaed;border-color:rgba(160,175,195,.6)}.yj-lg.on{color:#0e1116;background:#cfd6de;border-color:#cfd6de}.yj-find{max-width:760px;margin:34px auto 8px;padding:0 20px}.yj-find h2{font:600 20px/1.3 system-ui,sans-serif;margin:0 0 10px}#yjq{width:100%;box-sizing:border-box;padding:13px 15px;font:400 15.5px system-ui,sans-serif;border:1px solid rgba(140,150,165,.34);border-radius:8px;background:rgba(255,255,255,.04);color:inherit}#yjq:focus{outline:none;border-color:#7FD1C4}#yjr{margin-top:10px;display:flex;flex-direction:column;gap:6px}#yjr a{display:flex;justify-content:space-between;gap:12px;padding:11px 14px;border:1px solid rgba(140,150,165,.22);border-radius:6px;text-decoration:none;font:400 14.5px/1.4 system-ui,sans-serif;color:inherit}#yjr a:hover{border-color:#7FD1C4}#yjr .pr{font:600 13px system-ui,sans-serif;color:#5fbf9a;white-space:nowrap}</style><script>(function(){var q=document.getElementById("yjq"),r=document.getElementById("yjr"),D=null;function load(){if(D)return Promise.resolve(D);return fetch("/search-index.json").then(function(x){return x.json();}).then(function(j){D=j;return j;}).catch(function(){D=[];return D;});}function esc(t){return String(t).replace(/[&<>"]/g,function(c){return {"&":"&","<":"<",">":">",'"':"""}[c];});}function run(){var v=q.value.trim().toLowerCase();if(v.length<2){r.innerHTML="";return;}load().then(function(j){var w=v.split(/\s+/),o=[];for(var i=0;i<j.length&&o.length<12;i++){var t=j[i].t.toLowerCase();var ok=true;for(var k=0;k<w.length;k++){if(t.indexOf(w[k])<0){ok=false;break;}}if(ok)o.push(j[i]);}r.innerHTML=o.length?o.map(function(x){return "<a href=\""+esc(x.u)+"\">"+"<span>"+esc(x.t)+"</span>"+(x.p?"<span class=\"pr\">$"+x.p+"</span>":"")+"</a>";}).join(""):"";});}q.addEventListener("input",run);q.addEventListener("focus",load);})();</script></div><section data-yj="yj-facts-v1" style="max-width:920px;margin:48px auto 0;padding:0 20px;font-family:system-ui,sans-serif"><style>.yj-article p{font:400 15.5px/1.7 system-ui,sans-serif;color:#26313b;margin:0 0 12px;max-width:72ch}.yj-article h2,.yj-article h3,.yj-article h4{font:600 17px/1.35 system-ui,sans-serif;color:#1b1f24;margin:22px 0 8px}.yj-article table{border-collapse:collapse;margin:10px 0 16px;font:14px/1.45 system-ui,sans-serif}.yj-article th,.yj-article td{border:1px solid #e2e6ea;padding:6px 10px;text-align:left}.yj-article th{background:#f4f6f8}.yj-article pre{background:#0f1720;color:#e6edf3;padding:12px 14px;border-radius:8px;overflow:auto;font:13px/1.5 ui-monospace,Menlo,monospace}.yj-article code{font:13px ui-monospace,Menlo,monospace;background:#f1f3f5;padding:1px 4px;border-radius:3px}.yj-article pre code{background:none;padding:0}.yj-article ul,.yj-article ol{font:15px/1.6 system-ui,sans-serif;color:#26313b}</style><p style="font:400 13px/1.5 system-ui,sans-serif;color:#6b7680;margin:0 0 14px"><time datetime="2026-09-30">Updated 2026-09-30</time> · ReadyStack</p><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","dateModified":"2026-09-30","author":{"@type":"Organization","name":"ReadyStack"}}</script><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Worked example</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 16px;color:#5b6570">Real numbers from this tool, line by line.</p><div class="yj-article"><p><img src="https://getreadystack.com/img/promo/sku401366_result_card.jpg" alt="SeaweedFS Migration Lint — MinIO Compose & K8s" loading="lazy" style="max-width:100%;border-radius:6px"></p> | |
| <p>Migrate from MinIO to SeaweedFS: the sample 41-line docker-compose.yml returns 17 findings (1 error, 11 warnings, 5 info) for DevOps, platform and SRE engineers who run MinIO in Docker Compose or Kubernetes.</p> | |
| <p>Why now. MinIO moved from Apache 2.0 to AGPL-3.0 with the commit "update license change for MinIO" on 2021-04-23. The minio/minio GitHub repository is now archived, and its README opens with "THIS REPOSITORY IS NO LONGER MAINTAINED". The community edition is distributed as source code only; the last community release is RELEASE.2025-10-15T17-29-55Z, and the README says legacy binaries will not receive updates. The same README says all usage requires validation against AGPLv3 obligations, including the release of modified code. SeaweedFS is Apache-2.0, and SeaweedFS 4.48 was released on 2026-09-28.</p> | |
| <p>What breaks is the glue around the buckets. SeaweedFS speaks S3, so the SDK calls in your app mostly keep working. The compose file does not. A grep for "minio" matches every line and ranks none, and a chatbot tends to call SeaweedFS a drop-in replacement.</p> | |
| <p>The sample file has one error and it is the image: quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z. That tag will not be patched. The fix is chrislusf/seaweedfs:4.48 with entrypoint weed and command server -dir=/data -s3, which starts master, volume server, filer and the S3 gateway in one process.</p> | |
| <p>The warnings are the lines that fail quietly after cutover:</p> | |
| <ul><li>MINIO_ROOT_USER and MINIO_ROOT_PASSWORD: SeaweedFS does not read them. Use AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or an s3.json identity with actions Admin, Read and Write passed as -s3.config.</li><li>"9000:9000": the SeaweedFS S3 gateway listens on 8333. Map 8333:8333 or start with -s3.port=9000.</li><li>--console-address: there is no MinIO Console. weed admin runs the Admin UI on port 23646.</li><li>MINIO_NOTIFY_WEBHOOK_*: SeaweedFS lists GetBucketNotificationConfiguration and PutBucketNotificationConfiguration as not supported. Your thumbnail worker stops getting events. weed filer.meta.tail -pathPrefix=/buckets/uploads is the SeaweedFS way to follow changes.</li><li>MINIO_KMS_KES_ENDPOINT: SeaweedFS SSE-KMS talks to AWS KMS, Google Cloud KMS or OpenBao/Vault, not KES.</li><li>mc admin user add: the MinIO admin API is not there. SeaweedFS implements the IAM API on the S3 endpoint, so aws iam create-user --endpoint-url http://seaweedfs:8333 works.</li><li>mc ilm rule add --transition-days 30: lifecycle configuration is supported, transition rules are not. Keep expiry rules.</li></ul> | |
| <p>The info lines are renames: MINIO_DOMAIN becomes -s3.domainName, /minio/health/live becomes /healthz, and every http://minio:9000 endpoint becomes http://seaweedfs:8333 with path-style addressing.</p> | |
| <p>What the 17 rules cover. Besides the lines above: MinIO source builds (go install github.com/minio/minio, the AGPL path), mc replicate (use weed filer.sync), mc sql and S3 Select, MINIO_IDENTITY_OPENID and LDAP settings (SeaweedFS STS supports AssumeRoleWithWebIdentity and AssumeRoleWithLDAPIdentity), and MinIO disk folders such as .minio.sys, which SeaweedFS cannot read. Copy data through the S3 API with rclone sync instead.</p> | |
| <p>The clean 23-line compose on chrislusf/seaweedfs:4.48 gives 0 findings.</p> | |
| <p>Try it. Paste your docker-compose.yml, Kubernetes manifest or mc script into the free web version at https://getreadystack.com/tools/seaweedfs-migration-lint or install the VS Code extension. Every finding in the open file is free and runs offline. A licence adds one sweep of the whole workspace and a Markdown migration report for the change ticket.</p></div><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:30px 0 10px;color:#1b1f24">15 seconds — what it actually does</h2><video controls muted playsinline preload="none" poster="/img/promo/sku401366_result_card.jpg" style="width:100%;max-width:360px;border-radius:10px;display:block;margin:0 auto"><source src="/media/sku401366_short.mp4" type="video/mp4"></video><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:34px 0 6px;color:#1b1f24">Questions people ask</h2><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does SeaweedFS Migration Lint check in my MinIO files?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads docker-compose and Kubernetes YAML, .env files, shell scripts and Dockerfiles line by line against 17 rules and marks every line that ties the setup to MinIO: the minio/minio image, the minio server command, MINIO_* credentials, port 9000, mc admin calls, bucket notifications, replication, lifecycle transitions, S3 Select and KES settings. Each finding names the SeaweedFS fix.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Who is SeaweedFS Migration Lint for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">DevOps, platform and SRE engineers who run MinIO in Docker Compose or Kubernetes and are moving the same S3 store to SeaweedFS, because the minio/minio repository is archived, the last community release is RELEASE.2025-10-15T17-29-55Z, and MinIO is AGPL-3.0. It also suits agencies and MSPs that ship compose files to clients.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">Why not just grep for minio or ask a chatbot?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A grep for minio matches every line and ranks none. A chatbot usually says SeaweedFS is a drop-in S3 replacement, but SeaweedFS lists bucket notifications, bucket replication, S3 Select and lifecycle transition rules as not supported, listens on 8333 instead of 9000, and ignores MINIO_ROOT_USER. Those lines fail quietly after cutover.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What is free and what does the licence add?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free: every finding in the open file, with the line and the SeaweedFS fix, in VS Code and in the web version, offline, no account. The sample 41-line docker-compose.yml gives 17 findings for free. The licence, $29 once, adds a sweep of the whole workspace in one pass and one exported Markdown migration report for the change ticket.</p></details><details style="border-bottom:1px solid #e6e9ed;padding:10px 0"><summary style="cursor:pointer;font:600 15px/1.4 system-ui,sans-serif;color:#1b1f24">What does the alternative cost?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">The MinIO licence question is legal work: DOJ's Fitzpatrick Matrix rates a 15-year litigator at $851/hour for billing year 2026, which is one hour of counsel reading MinIO's AGPL-3.0 obligations. MinIO's own commercial path is AIStor Enterprise, sold by quote only, with no public price.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does SeaweedFS Migration Lint check in my MinIO files?", "acceptedAnswer": {"@type": "Answer", "text": "It reads docker-compose and Kubernetes YAML, .env files, shell scripts and Dockerfiles line by line against 17 rules and marks every line that ties the setup to MinIO: the minio/minio image, the minio server command, MINIO_* credentials, port 9000, mc admin calls, bucket notifications, replication, lifecycle transitions, S3 Select and KES settings. Each finding names the SeaweedFS fix."}}, {"@type": "Question", "name": "Who is SeaweedFS Migration Lint for?", "acceptedAnswer": {"@type": "Answer", "text": "DevOps, platform and SRE engineers who run MinIO in Docker Compose or Kubernetes and are moving the same S3 store to SeaweedFS, because the minio/minio repository is archived, the last community release is RELEASE.2025-10-15T17-29-55Z, and MinIO is AGPL-3.0. It also suits agencies and MSPs that ship compose files to clients."}}, {"@type": "Question", "name": "Why not just grep for minio or ask a chatbot?", "acceptedAnswer": {"@type": "Answer", "text": "A grep for minio matches every line and ranks none. A chatbot usually says SeaweedFS is a drop-in S3 replacement, but SeaweedFS lists bucket notifications, bucket replication, S3 Select and lifecycle transition rules as not supported, listens on 8333 instead of 9000, and ignores MINIO_ROOT_USER. Those lines fail quietly after cutover."}}, {"@type": "Question", "name": "What is free and what does the licence add?", "acceptedAnswer": {"@type": "Answer", "text": "Free: every finding in the open file, with the line and the SeaweedFS fix, in VS Code and in the web version, offline, no account. The sample 41-line docker-compose.yml gives 17 findings for free. The licence, $29 once, adds a sweep of the whole workspace in one pass and one exported Markdown migration report for the change ticket."}}, {"@type": "Question", "name": "What does the alternative cost?", "acceptedAnswer": {"@type": "Answer", "text": "The MinIO licence question is legal work: DOJ's Fitzpatrick Matrix rates a 15-year litigator at $851/hour for billing year 2026, which is one hour of counsel reading MinIO's AGPL-3.0 obligations. MinIO's own commercial path is AIStor Enterprise, sold by quote only, with no public price."}}]}</script><div id="yj-ask" style="margin:36px 0 0;padding:18px 18px 16px;border:1px solid #e2e6ea;border-radius:10px;background:#fbfbfc"><h2 style="font:600 19px/1.3 system-ui,sans-serif;margin:0 0 4px;color:#1b1f24">Ask about this tool</h2><p style="font:400 13.5px/1.5 system-ui,sans-serif;margin:0 0 12px;color:#5b6570">One question, answered by the person who built it. Your email only if you want the answer sent.</p><form onsubmit="return yjAsk(event)" style="display:grid;gap:8px"><textarea name="question" required minlength="10" maxlength="2000" rows="3" placeholder="Your question" style="font:14px/1.5 system-ui,sans-serif;padding:10px;border:1px solid #cfd6dd;border-radius:6px"></textarea><div style="display:flex;gap:8px;flex-wrap:wrap"><input type="email" name="email" placeholder="Email (optional)" style="flex:1;min-width:200px;font:14px system-ui,sans-serif;padding:9px 10px;border:1px solid #cfd6dd;border-radius:6px"><button type="submit" style="font:600 14px system-ui,sans-serif;padding:9px 18px;border:0;border-radius:6px;background:#1b1f24;color:#fff;cursor:pointer">Send</button></div><p id="yj-ask-msg" style="font:13px system-ui,sans-serif;margin:2px 0 0;color:#0a6238;min-height:1em"></p></form><script>function yjAsk(e){e.preventDefault();var f=e.target,m=document.getElementById("yj-ask-msg");m.style.color="#0a6238";fetch(location.origin+"/api/ask",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sku:401366,slug:"seaweedfs-migration-lint",lang:"en",question:f.question.value,email:f.email.value,page:location.pathname})}).then(function(r){if(!r.ok)throw 0;m.textContent="Thanks \u2014 noted. Answers land on this page and, if you left an email, in your inbox.";f.question.value="";}).catch(function(){m.style.color="#a8551f";m.textContent="Could not send. Please try again in a minute.";});return false;}</script></div></section><section class="yj-related" style="max-width:920px;margin:56px auto 40px;padding:0 20px"><h2 style="font:600 21px/1.3 system-ui,sans-serif;margin:0 0 6px;color:#1b1f24">Same job, next tool</h2><p style="font:400 14.5px/1.5 system-ui,sans-serif;margin:0 0 20px;color:#5b6570">Free in the browser. The full version is a one-time licence.</p><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:14px"><a class="yj-rel-c" href="https://getreadystack.com/tools/cloud-cost-landmine-lint"><span class="yj-rel-t">Cloud Cost Landmine Lint for Terraform, CloudFormation and Kubernetes</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/cron-schedule-lint"><span class="yj-rel-t">Cron Schedule Lint for crontab, Kubernetes CronJob, GitHub Actions, Spring and</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/k8s-removed-api-lint"><span class="yj-rel-t">Kubernetes Removed API Lint</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/podman-migration-check"><span class="yj-rel-t">Podman Migration Check — Docker Desktop ties</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/robots-txt-ai-crawler-audit"><span class="yj-rel-t">AI Crawler Rules - robots.txt Audit for AI Search</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/almalinux-migration-lint"><span class="yj-rel-t">AlmaLinux Migration Lint — CentOS 7/8</span><span class="yj-rel-p">$29</span></a></div><style>.yj-rel-c{display:flex;flex-direction:column;gap:8px;padding:15px 16px;border:1px solid #e2e6ea;border-radius:6px;text-decoration:none;background:#fff}.yj-rel-c:hover{border-color:#b9c2cb;background:#fafbfc}.yj-rel-t{font:500 14.5px/1.42 system-ui,sans-serif;color:#1b1f24}.yj-rel-p{font:600 13px system-ui,sans-serif;color:#0a6238}</style></section></body> | |
| </html> | |