File size: 39,398 Bytes
0fea8ad d753b97 0fea8ad | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | <!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Docker Desktop alternatives — check your files for free</title>
<meta name="description" content="This free tool flags Docker Desktop-specific lines in Compose, Dockerfiles and CI that need changes for Podman.">
<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 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/podman-migration-check"><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!important;justify-content:flex-end;margin:0 0 10px}h1,h2,h3,h4,p,li,dd,dt,blockquote,figcaption,summary,label,.res,.lead{overflow-wrap:anywhere}label{max-width:100%;box-sizing:border-box}#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>Docker Desktop alternatives — check your files for free</h1>
<p class="lede">Podman migration check: flags Docker Desktop-only lines (docker.sock, host.docker.internal, credsStore desktop, desktop-linux context, docker scout, ports below 1024, short image names) in compose, Dockerfile and CI. Runs entirely in your browser — nothing is uploaded.</p>
<textarea id="src" spellcheck="false"># compose.yaml — a team stack written on Docker Desktop
services:
web:
image: nginx:1.27
ports:
- "80:8080"
environment:
API_URL: http://host.docker.internal:3000
agent:
image: docker.io/portainer/agent:2.21.4
volumes:
- /var/run/docker.sock:/var/run/docker.sock
kubectl:
image: docker.io/bitnami/kubectl:1.31
environment:
KUBE_API: https://kubernetes.docker.internal:6443
command: ["config", "use-context", "docker-desktop"]</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> Check the open compose.yaml, Dockerfile, devcontainer.json, workflow or script for Docker Desktop ties, with the Podman fix on each line. <strong>In the editor:</strong> Scan every repo in the workspace in one pass and export a Markdown migration report per repo for the licence decision — that part asks for a licence key.</div>
<div id="buy" style="margin:8px 0;padding:10px;border:1px solid #ccc;border-radius:6px">
<strong>Full version:</strong> scan every repo in the workspace in one pass and export a Markdown migration report per repo.
<a href="https://getreadystack.com/api/buy/cl/polar_cl_pynzSk53f1xZ4TW6BmUSQGoDHpWhL3uLWl6vT4KssMq" data-polar-checkout data-polar-checkout-theme="light">Get the full version — $29</a>
<br><small>$29 once · one licence key per person or team seat. Yardstick: Docker Business is $24 per user per month billed annually ($288 per developer a year).</small></div>
<script defer data-auto-init src="https://cdn.jsdelivr.net/npm/@polar-sh/checkout@latest/dist/embed.global.js"></script>
<p class="note">Same engine as the VS Code extension, byte for byte.</p>
</div>
<script>var PM_RULES = [
{"id": "PM01", "check": "docker-sock-host-path", "sev": "error", "kind": "regex",
"re": "(?:^|[\\s\"'=\\-])(?:unix:\\/\\/)?\\/var\\/run\\/docker\\.sock", "flags": "",
"msg": "Host path /var/run/docker.sock only exists while Docker Desktop (or dockerd) runs. Rootless Podman serves $XDG_RUNTIME_DIR/podman/podman.sock after `systemctl --user enable --now podman.socket`; mount that path instead.",
"source": "https://docs.podman.io/en/latest/markdown/podman-system-service.1.html"},
{"id": "PM02", "check": "desktop-only-hostname", "sev": "error", "kind": "regex",
"re": "\\b(?:gateway|kubernetes)\\.docker\\.internal\\b", "flags": "i",
"msg": "gateway.docker.internal and kubernetes.docker.internal are DNS names injected by Docker Desktop. Podman has no such names; point at host.containers.internal or at your own cluster's API address.",
"source": "https://docs.docker.com/desktop/features/networking/"},
{"id": "PM03", "check": "host-docker-internal", "sev": "warn", "kind": "regex",
"re": "(?\u003c![\\w.-])host\\.docker\\.internal\\b", "flags": "i",
"msg": "host.docker.internal is Docker Desktop's name for the host. Podman's own name is host.containers.internal; older Podman releases do not add the Docker alias, so use the Podman name.",
"source": "https://docs.podman.io/en/latest/markdown/podman-run.1.html"},
{"id": "PM04", "check": "credsstore-desktop", "sev": "error", "kind": "regex",
"re": "\"credsStore\"\\s*:\\s*\"desktop\"", "flags": "",
"msg": "credsStore \"desktop\" calls docker-credential-desktop, which ships with Docker Desktop and disappears when it is uninstalled. Podman reads ${XDG_RUNTIME_DIR}/containers/auth.json; run `podman login` or set credsStore to pass/secretservice.",
"source": "https://docs.podman.io/en/latest/markdown/podman-login.1.html"},
{"id": "PM05", "check": "desktop-context", "sev": "error", "kind": "regex",
"re": "(?\u003c![\\w-])(?:desktop-linux|docker-desktop)(?![\\w-])", "flags": "",
"msg": "The desktop-linux Docker context and the docker-desktop Kubernetes context exist only inside Docker Desktop. Use a Podman machine connection (`podman system connection`) and a kind or minikube cluster context.",
"source": "https://docs.docker.com/desktop/features/kubernetes/"},
{"id": "PM06", "check": "privileged-host-port", "sev": "warn", "kind": "port",
"msg": "Host port below 1024. Rootless Podman cannot bind it unless net.ipv4.ip_unprivileged_port_start is lowered on the host (or the Podman machine); map to 8080/8443 instead.",
"source": "https://github.com/containers/podman/blob/main/rootless.md"},
{"id": "PM07", "check": "short-image-name", "sev": "warn", "kind": "image",
"msg": "Unqualified image name. Podman resolves short names through registries.conf (short-name-mode enforcing) and can prompt or fail in CI; write the full name, e.g. docker.io/library/nginx:1.27.",
"source": "https://github.com/containers/image/blob/main/docs/containers-registries.conf.5.md"},
{"id": "PM08", "check": "desktop-cli-plugin", "sev": "error", "kind": "regex",
"re": "\\bdocker\\s+(?:scout|extension|desktop)\\b", "flags": "",
"msg": "docker scout, docker extension and docker desktop are CLI plugins bundled with Docker Desktop; podman has no such subcommand. Replace scout with a standalone scanner (e.g. trivy or grype) before uninstalling.",
"source": "https://docs.docker.com/scout/"},
{"id": "PM09", "check": "buildx-bake", "sev": "warn", "kind": "regex",
"re": "\\bbuildx\\s+(?:bake|create|use)\\b", "flags": "",
"msg": "podman buildx is only an alias for podman build; buildx bake, create and use have no Podman equivalent. Replace bake files with one `podman build --platform` (plus `podman manifest`) per target.",
"source": "https://docs.podman.io/en/latest/markdown/podman-buildx-build.1.html"},
{"id": "PM10", "check": "devcontainer-dind", "sev": "warn", "kind": "regex",
"re": "devcontainers\\/features\\/docker-in-docker", "flags": "",
"msg": "The docker-in-docker dev container feature starts a privileged nested dockerd. Under rootless Podman switch to docker-outside-of-docker pointed at the Podman socket and set dev.containers.dockerPath to podman.",
"source": "https://github.com/devcontainers/features/tree/main/src/docker-in-docker"}
]
;</script>
<script>// Podman Migration Check engine: finds Docker Desktop ties line by line.
// Same file runs in Node (VS Code extension, verify) and in the browser (free web page).
(function (root) {
const RULES = (typeof module !== 'undefined') ? require('./rules.json') : root.PM_RULES;
const PORT_RES = [
/^\s*-\s*["']?(?:\d{1,3}(?:\.\d{1,3}){3}:)?(\d{1,5})(?:-\d{1,5})?:\d{1,5}/, // compose ports list
/(?:^|\s)(?:-p|--publish)[\s=]+["']?(?:\d{1,3}(?:\.\d{1,3}){3}:)?(\d{1,5})(?:-\d{1,5})?:\d{1,5}/ // docker run -p
];
const IMAGE_RES = [
/^\s*image:\s*["']?([^\s"'#]+)/,
/^\s*FROM\s+(?:--platform=\S+\s+)?([^\s#]+)/i,
/"image"\s*:\s*"([^"]+)"/
];
function isQualified(ref, stages) {
if (!ref || ref === 'scratch' || ref.startsWith('$') || stages.has(ref.toLowerCase())) return true;
const first = ref.split('/')[0];
if (!ref.includes('/')) return false;
return first.includes('.') || first.includes(':') || first === 'localhost';
}
function check(text, opts) {
const lines = String(text || '').split(/\r?\n/);
const findings = [];
const stages = new Set();
lines.forEach(l => { const m = l.match(/^\s*FROM\s+\S+(?:\s+\S+)*?\s+AS\s+([\w.-]+)/i); if (m) stages.add(m[1].toLowerCase()); });
const compiled = RULES.map(r => r.kind === 'regex' ? Object.assign({ rx: new RegExp(r.re, r.flags || '') }, r) : r);
lines.forEach((line, i) => {
if (/^\s*(#|\/\/)/.test(line)) return;
for (const r of compiled) {
let hit = false;
if (r.kind === 'regex') hit = r.rx.test(line);
else if (r.kind === 'port') hit = PORT_RES.some(rx => { const m = line.match(rx); return m && +m[1] > 0 && +m[1] < 1024; });
else if (r.kind === 'image') hit = IMAGE_RES.some(rx => { const m = line.match(rx); return m && !isQualified(m[1], stages); });
if (hit) findings.push({ check: r.check, id: r.id, sev: r.sev, msg: r.msg, line: i + 1, text: line.trim() });
}
});
return { findings, errors: findings.filter(f => f.sev === 'error').length, warnings: findings.filter(f => f.sev === 'warn').length, as_of: (opts && opts.today) || '' };
}
const api = { engine: { check }, RULES, RULE_COUNT: RULES.length };
if (typeof module !== 'undefined') module.exports = api;
root.PMENGINE = api;
})(typeof window !== 'undefined' ? window : globalThis);
</script>
<script>// ⛔뼈대 — kit/scaffold.py 가 찍는다 (s143). findings [{check,sev,msg,line?}] → 글/HTML. 같은 파일이 Node 와 브라우저에서 산다.
'use strict';
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 PMREPORT = { escapeHtml: escapeHtml, summaryLine: summaryLine, toText: toText, toHtml: toHtml };
if (typeof module !== 'undefined' && module.exports) module.exports = PMREPORT;
else window.PMREPORT = PMREPORT;
</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.PMENGINE.engine.check(src.value,{today:today.value}); out.innerHTML=window.PMREPORT.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://marketplace.visualstudio.com/items?itemName=ReadyStack.podman-migration-check" rel="noopener" data-yj-install-door="mp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'podman-migration-check',src:'mp',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">VS Code Marketplace</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.podman-migration-check</pre><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 Podman Migration Check — Docker Desktop ties 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:"podman-migration-check",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 every repo in the workspace in one pass and export a Markdown migration report per repo for the licence decision</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">Docker Business is $24 per user per month billed annually ($288 per developer a year); Docker Team is $15 per user per month billed annually.</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_pynzSk53f1xZ4TW6BmUSQGoDHpWhL3uLWl6vT4KssMq" 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>
<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><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 Podman Migration Check do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Podman Migration Check reads compose.yaml, Dockerfile, devcontainer.json, CI workflow and shell files and flags every line that only works while Docker Desktop is installed: the /var/run/docker.sock host socket, host.docker.internal and kubernetes.docker.internal, the desktop-linux and docker-desktop contexts, credsStore desktop, docker scout, host ports below 1024 and short image names. Each finding shows the Podman replacement.</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 Podman Migration Check for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It is for platform engineers and DevOps leads at companies that crossed Docker's paid-licence line of more than 250 employees or more than $10 million annual revenue and are moving developers from Docker Desktop to rootless Podman. It suits teams whose compose files, dev containers and CI scripts were written on Docker Desktop Macs and Windows laptops.</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 ask a chatbot or run podman compose and see what fails?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A chatbot rewrites the file you paste but cannot tell which lines depend on Docker Desktop, and it may silently keep host.docker.internal or the docker-desktop context. Running podman compose shows only the first failure, and only on the machine that runs it; a CI runner or a colleague's Mac fails later, one line at a time.</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 paid version add?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">The free version runs all 10 rules on the open file in VS Code and in the web page, with the fix text on each finding and no cap. The paid version, $29 once with one licence key per person or team seat, scans every repo in the workspace in one pass and exports a Markdown migration report per repo.</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">How does the cost compare with staying on Docker Desktop?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Docker Business costs $24 per user per month billed annually, which is $288 per developer a year, and Docker Team costs $15 per user per month billed annually. Podman is free and open source. Podman Migration Check is a one-time $29 per seat for the workspace report; the single-file check stays free.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does Podman Migration Check do?", "acceptedAnswer": {"@type": "Answer", "text": "Podman Migration Check reads compose.yaml, Dockerfile, devcontainer.json, CI workflow and shell files and flags every line that only works while Docker Desktop is installed: the /var/run/docker.sock host socket, host.docker.internal and kubernetes.docker.internal, the desktop-linux and docker-desktop contexts, credsStore desktop, docker scout, host ports below 1024 and short image names. Each finding shows the Podman replacement."}}, {"@type": "Question", "name": "Who is Podman Migration Check for?", "acceptedAnswer": {"@type": "Answer", "text": "It is for platform engineers and DevOps leads at companies that crossed Docker's paid-licence line of more than 250 employees or more than $10 million annual revenue and are moving developers from Docker Desktop to rootless Podman. It suits teams whose compose files, dev containers and CI scripts were written on Docker Desktop Macs and Windows laptops."}}, {"@type": "Question", "name": "Why not just ask a chatbot or run podman compose and see what fails?", "acceptedAnswer": {"@type": "Answer", "text": "A chatbot rewrites the file you paste but cannot tell which lines depend on Docker Desktop, and it may silently keep host.docker.internal or the docker-desktop context. Running podman compose shows only the first failure, and only on the machine that runs it; a CI runner or a colleague's Mac fails later, one line at a time."}}, {"@type": "Question", "name": "What is free and what does the paid version add?", "acceptedAnswer": {"@type": "Answer", "text": "The free version runs all 10 rules on the open file in VS Code and in the web page, with the fix text on each finding and no cap. The paid version, $29 once with one licence key per person or team seat, scans every repo in the workspace in one pass and exports a Markdown migration report per repo."}}, {"@type": "Question", "name": "How does the cost compare with staying on Docker Desktop?", "acceptedAnswer": {"@type": "Answer", "text": "Docker Business costs $24 per user per month billed annually, which is $288 per developer a year, and Docker Team costs $15 per user per month billed annually. Podman is free and open source. Podman Migration Check is a one-time $29 per seat for the workspace report; the single-file check stays free."}}]}</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:0,slug:"podman-migration-check",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><!--yj-embed-s178--><details id="embed" data-yj="yj-embed" style="max-width:46rem;margin:1.6rem auto;padding:.85rem 1.1rem;border:1px solid #8884;border-radius:10px"><summary style="cursor:pointer;font-weight:600">Embed this tool on your site (free)</summary><p style="margin:.6rem 0;opacity:.85">Paste this code into your page. It runs in your visitor’s browser and stays up to date. Nothing your visitors type is stored.</p><textarea readonly rows="6" style="width:100%;font:12px/1.4 ui-monospace,Menlo,Consolas,monospace;border:1px solid #8886;border-radius:7px;padding:.5rem"><iframe src="https://getreadystack.com/embed/podman-migration-check/" title="Docker Desktop alternatives — check your files for free" loading="lazy" data-rs-embed="en-podman-migration-check" style="width:100%;max-width:760px;height:640px;border:1px solid #e3e3e3;border-radius:10px"></iframe>
<p style="font-size:13px;margin:6px 0 0"><a href="https://getreadystack.com/tools/podman-migration-check">Docker Desktop alternatives — check your files for free</a> by <a href="https://getreadystack.com/">ReadyStack</a></p>
<script>window.addEventListener("message",function(e){if(e.origin!=="https://getreadystack.com"||!e.data||e.data.type!=="readystack-embed")return;var f=document.querySelectorAll("iframe[data-rs-embed]");for(var i=0;i<f.length;i++){if(f[i].contentWindow===e.source)f[i].style.height=Math.min(e.data.h+6,8000)+"px";}});</script></textarea><p style="margin:.5rem 0 0"><button type="button" data-yj="yj-embed-copy" style="font:inherit;padding:8px 14px;border:1px solid #8884;border-radius:9px;background:transparent;cursor:pointer">Copy code</button> <a href="/embed/">All embeddable tools</a></p><p style="margin:.7rem 0 0;font-size:.92em;opacity:.9">For businesses: your name and logo instead of ours, and each visitor’s result + e-mail in your inbox (only when they tick consent) — Pro from $19/month. <a href="/embed/pro/?ref=embed_box">See Pro →</a></p></details><script data-yj="yj-embed">(function(){var b=document.querySelector("[data-yj=yj-embed-copy]");if(!b)return;var t=b.textContent;b.addEventListener("click",function(){var a=b.closest("details").querySelector("textarea");var v=a.value;function d(){b.textContent="Copied";setTimeout(function(){b.textContent=t;},1800);}if(navigator.clipboard&&navigator.clipboard.writeText){navigator.clipboard.writeText(v).then(d,function(){a.select();});}else{a.select();}});})();</script><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/docker-image-for-development"><span class="yj-rel-t">Docker Image for Development — Node.js 22 + TypeScript Dev Container with Post</span><span class="yj-rel-p">$19</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/bitnami-image-catalog-gate"><span class="yj-rel-t">Bitnami Image Gate: Compose, Helm, Dockerfile</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/mcp-config-audit"><span class="yj-rel-t">MCP Server Config Audit</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/base-image-eol-lint"><span class="yj-rel-t">Base Image EOL Lint - Dockerfile and CI end-of-life check</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/cra-annex-ii-docs-lint"><span class="yj-rel-t">CRA Annex II User Docs Lint</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/csaf-advisory-check-cra-2026"><span class="yj-rel-t">CSAF Advisory Check for CRA 2026</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><!--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></body>
</html>
|