getreadystack commited on
Commit
6437506
·
verified ·
1 Parent(s): c4224d6

Upload index.html with huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +31 -8
index.html CHANGED
@@ -2,7 +2,6 @@
2
  <meta name="viewport" content="width=device-width,initial-scale=1">
3
  <title>Base Image EOL Lint - Dockerfile and CI end-of-life check</title>
4
  <meta name="description" content="Marks every base image in your Dockerfiles, compose files and CI workflows whose security patches have already stopped - or stop before 13 November 2026 - and prints the tag that replaces it.">
5
- <script defer data-auto-init src="https://cdn.jsdelivr.net/npm/@polar-sh/checkout@latest/dist/embed.global.js"></script>
6
  <style>
7
  :root{color-scheme:light dark}
8
  body{margin:0;font:16px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;
@@ -43,7 +42,7 @@ FROM mcr.microsoft.com/dotnet/aspnet:8.0
43
  </textarea>
44
  <button id="go">Check these images</button>
45
  <div id="out"></div>
46
- <div class="next"><h2>In the full version</h2><ul><li>Every Dockerfile, compose file and workflow in the repository</li><li>A dated CSV, JSON or HTML report</li><li>JSON output that fails the build</li><li><a href="https://buy.polar.sh/polar_cl_brZKgBkvnYrEIMElB5Ynt5gGEnqmTjvx9r9ZX3ljztR" data-polar-checkout data-polar-checkout-theme="light">Get the full version - $29</a></li></ul></div>
47
  </div>
48
  <script>
49
  var RULES=[{"pattern": "\\bnode:20\\b", "flags": "i", "sev": "error", "message": "node:20 - Node.js 20 reached end-of-life on 30 April 2026. No security release has shipped for it since. Replace with node:24-trixie (Active LTS to 30 April 2028).", "fix": "FROM node:24-trixie"}, {"pattern": "\\bnode:18\\b", "flags": "i", "sev": "error", "message": "node:18 - Node.js 18 reached end-of-life on 30 April 2025. Replace with node:24-trixie (Active LTS to 30 April 2028).", "fix": "FROM node:24-trixie"}, {"pattern": "\\bnode:(?:14|16)\\b", "flags": "i", "sev": "error", "message": "Node.js 14 (end-of-life 30 April 2023) and Node.js 16 (11 September 2023) have been unpatched for over two years. Replace with node:24-trixie.", "fix": "FROM node:24-trixie"}, {"pattern": "\\bpython:3\\.(?:7|8|9)\\b", "flags": "i", "sev": "error", "message": "Python 3.9 reached end-of-life on 31 October 2025 (3.8 on 7 October 2024, 3.7 on 27 June 2023). 3.9.25 was the final security release. Replace with python:3.13-trixie.", "fix": "FROM python:3.13-trixie"}, {"pattern": "\\bpython:3\\.10\\b", "flags": "i", "sev": "warn", "message": "python:3.10 - Python 3.10 reaches end-of-life on 31 October 2026. After that date the PSF ships no further security patches. Replace with python:3.13-trixie.", "fix": "FROM python:3.13-trixie"}, {"pattern": "\\b(?:debian:11|bullseye)\\b", "flags": "i", "sev": "error", "message": "Debian 11 bullseye LTS ended on 31 August 2026 - no security updates from September 2026 onward. Replace with debian:trixie, or bookworm if you need LTS to 30 June 2028.", "fix": "FROM debian:trixie"}, {"pattern": "\\b(?:debian:(?:8|9|10)|buster|stretch|jessie)\\b", "flags": "i", "sev": "error", "message": "Debian 10 buster LTS ended on 30 June 2024; stretch and jessie are older still. Replace with debian:trixie.", "fix": "FROM debian:trixie"}, {"pattern": "\\b(?:ubuntu:20\\.04|ubuntu-20\\.04|ubuntu:focal|:focal\\b)", "flags": "i", "sev": "error", "message": "Ubuntu 20.04 focal left standard support on 31 May 2025. Patches now require a paid Ubuntu Pro (ESM) subscription. Replace with ubuntu:24.04, supported to April 2029.", "fix": "FROM ubuntu:24.04"}, {"pattern": "\\b(?:ubuntu:1[68]\\.04|ubuntu-1[68]\\.04|bionic|xenial)\\b", "flags": "i", "sev": "error", "message": "Ubuntu 18.04 bionic and 16.04 xenial left standard support in 2023 and 2021. Replace with ubuntu:24.04.", "fix": "FROM ubuntu:24.04"}, {"pattern": "\\balpine:3\\.(?:[0-9]|1[0-9]|20)\\b", "flags": "i", "sev": "error", "message": "This Alpine branch is out of support: 3.20 ended 1 April 2026, 3.19 on 1 November 2025, and everything older before that. Replace with alpine:3.23 (supported to 1 November 2027).", "fix": "FROM alpine:3.23"}, {"pattern": "\\balpine:3\\.21\\b", "flags": "i", "sev": "warn", "message": "alpine:3.21 - Alpine keeps a branch for two years, so 3.21 reaches end of support on 1 November 2026. Replace with alpine:3.23 (to 1 November 2027).", "fix": "FROM alpine:3.23"}, {"pattern": "\\bdotnet/(?:aspnet|sdk|runtime|samples):(?:6|7)\\.0\\b", "flags": "i", "sev": "error", "message": ".NET 6 reached end of support on 12 November 2024 and .NET 7 on 14 May 2024. Replace with mcr.microsoft.com/dotnet/aspnet:10.0 (LTS to 14 November 2028).", "fix": "FROM mcr.microsoft.com/dotnet/aspnet:10.0"}, {"pattern": "\\bdotnet/(?:aspnet|sdk|runtime|samples):(?:8|9)\\.0\\b", "flags": "i", "sev": "warn", "message": ".NET 8 (LTS) and .NET 9 (STS) both reach end of support on 10 November 2026 - the LTS release dies on the same day as the STS one. Replace with dotnet/aspnet:10.0, LTS to 14 November 2028.", "fix": "FROM mcr.microsoft.com/dotnet/aspnet:10.0"}, {"pattern": "\\bpostgres(?:ql)?:(?:9\\.[0-9]|1[0-3])\\b", "flags": "i", "sev": "error", "message": "PostgreSQL 13 reached end of life on 13 November 2025; 12 and older are further behind. The community ships no security patches for them. Replace with postgres:17.", "fix": "image: postgres:17"}, {"pattern": "\\bpostgres(?:ql)?:14\\b", "flags": "i", "sev": "warn", "message": "postgres:14 - PostgreSQL supports a major version for five years, so 14 reaches end of life on 12 November 2026. Replace with postgres:17.", "fix": "image: postgres:17"}, {"pattern": "\\bmysql:5\\.[0-9]\\b", "flags": "i", "sev": "error", "message": "MySQL 5.7 reached end of life on 31 October 2023 and 5.6 in February 2021. Replace with mysql:8.4, the current LTS.", "fix": "image: mysql:8.4"}, {"pattern": "\\bphp:(?:7\\.[0-9]|8\\.[01])\\b", "flags": "i", "sev": "error", "message": "PHP 8.1 security support ended on 31 December 2025; 8.0 and every 7.x are older. Replace with php:8.4-trixie.", "fix": "FROM php:8.4-trixie"}, {"pattern": "\\bphp:8\\.2\\b", "flags": "i", "sev": "warn", "message": "php:8.2 - PHP 8.2 reaches end of life on 31 December 2026, after which the PHP project ships no patches for it. Replace with php:8.4-trixie.", "fix": "FROM php:8.4-trixie"}, {"pattern": "\\bcentos:(?:6|7|8|stream8)\\b", "flags": "i", "sev": "error", "message": "CentOS 7 reached end of life on 30 June 2024 and CentOS 8 on 31 December 2021. The distribution line is finished. Replace with a maintained base such as debian:trixie.", "fix": "FROM debian:trixie"}, {"pattern": "\\bopenjdk:", "flags": "i", "sev": "warn", "message": "The openjdk Docker Official Image is deprecated and no longer updated. Replace with eclipse-temurin:21-jre-noble.", "fix": "FROM eclipse-temurin:21-jre-noble"}, {"pattern": "\\b[\\w./-]+:latest\\b", "flags": "i", "sev": "info", "message": "A :latest tag floats. The image you build today is not the image you built last month, so no end-of-life check - this one included - can tell you what is actually in the layer. Pin a dated tag.", "fix": "pin an explicit tag, e.g. FROM debian:trixie"}];
@@ -66,11 +65,35 @@ document.getElementById('go').click();
66
  </html>
67
 
68
 
69
- <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.base-image-eol-lint" rel="noopener" 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><a href="https://open-vsx.org/extension/readystack/base-image-eol-lint" rel="noopener" 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><a href="https://www.npmjs.com/package/@readystack/base-image-eol-lint" rel="noopener" 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">npm</a><a href="https://www.npmjs.com/package/@readystack/base-image-eol-lint" rel="noopener" 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">MCP server (npx)</a><a href="https://hub.docker.com/r/getreadystack/base-image-eol-lint" rel="noopener" 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">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.base-image-eol-lint
70
  npx @readystack/base-image-eol-lint &lt;file&gt;
71
- npx @readystack/base-image-eol-lint --mcp</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://buy.polar.sh/polar_cl_l6iN1uWt0FwWu7tBsczD0jWpP2vxFM54Wdwqb3KPi1G" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section>
72
- <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 Base Image EOL Lint - Dockerfile and CI end-of-life check 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:"base-image-eol-lint",lang:"en",source:"rule_alert"})}).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></section>
73
 
74
- <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 complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">Marks every base image in your Dockerfiles, compose files and CI workflows whose security patches have already stopped - or stop before 13 November 2026 - and prints the tag that replaces it</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">Snyk's Team tier is $25 per contributing developer per month.</p><a href="https://buy.polar.sh/polar_cl_brZKgBkvnYrEIMElB5Ynt5gGEnqmTjvx9r9ZX3ljztR" 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>
75
- <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 Base Image EOL Lint actually do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads the image references written in your repository - Dockerfile FROM lines, docker-compose image keys, GitHub Actions runner labels and container images - and marks every one whose vendor has stopped shipping security patches, or stops soon, with the exact tag that replaces it and the date behind the finding.</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 it for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Platform, DevOps and backend engineers who own the Dockerfiles and CI workflows in a repository: the person who answers when an auditor asks which base images are still supported, and the person who has to do the upgrade. If you maintain a multi-stage Dockerfile or a compose file, this reads your files.</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 will a free image scanner not do this?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free scanners test an image that has already been built and pushed, and they report the vulnerable packages inside it. They cannot open the Dockerfile on your screen and tell you that FROM python:3.10-slim names a runtime whose final security release lands on 31 October 2026. Nothing that needs a built image can.</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 needs a licence?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free covers one whole file: open a Dockerfile, run the check, and all 21 rules report every finding with its severity and its replacement tag. Nothing is watermarked, timed or locked after N runs. The licence changes the scope only - every file in the repository at once, a dated exported report, and JSON for CI.</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 would this cost otherwise?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Snyk&#x27;s Team tier is $25 per contributing developer per month, and it still starts from a built image rather than the file you are editing. Auditing FROM lines by hand means grepping every repository each time a vendor retires a branch, which happens several times a year. This is $29 once.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does Base Image EOL Lint actually do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads the image references written in your repository - Dockerfile FROM lines, docker-compose image keys, GitHub Actions runner labels and container images - and marks every one whose vendor has stopped shipping security patches, or stops soon, with the exact tag that replaces it and the date behind the finding."}}, {"@type": "Question", "name": "Who is it for?", "acceptedAnswer": {"@type": "Answer", "text": "Platform, DevOps and backend engineers who own the Dockerfiles and CI workflows in a repository: the person who answers when an auditor asks which base images are still supported, and the person who has to do the upgrade. If you maintain a multi-stage Dockerfile or a compose file, this reads your files."}}, {"@type": "Question", "name": "Why will a free image scanner not do this?", "acceptedAnswer": {"@type": "Answer", "text": "Free scanners test an image that has already been built and pushed, and they report the vulnerable packages inside it. They cannot open the Dockerfile on your screen and tell you that FROM python:3.10-slim names a runtime whose final security release lands on 31 October 2026. Nothing that needs a built image can."}}, {"@type": "Question", "name": "What is free and what needs a licence?", "acceptedAnswer": {"@type": "Answer", "text": "Free covers one whole file: open a Dockerfile, run the check, and all 21 rules report every finding with its severity and its replacement tag. Nothing is watermarked, timed or locked after N runs. The licence changes the scope only - every file in the repository at once, a dated exported report, and JSON for CI."}}, {"@type": "Question", "name": "What would this cost otherwise?", "acceptedAnswer": {"@type": "Answer", "text": "Snyk's Team tier is $25 per contributing developer per month, and it still starts from a built image rather than the file you are editing. Auditing FROM lines by hand means grepping every repository each time a vendor retires a branch, which happens several times a year. This is $29 once."}}]}</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:"base-image-eol-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, 7-day refund.</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/runtime-eol-deploy-block-audit"><span class="yj-rel-t">Runtime EOL and Deploy-Block Audit for Docker, CI and AWS Lambda</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/data-science-docker-image"><span class="yj-rel-t">Data Science Docker Image — JupyterLab 4 + Python 3.12 Analytics Stack (non-ro</span><span class="yj-rel-p">$19</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/docker-image-for-data-science"><span class="yj-rel-t">Docker Image for Data Science — Reproducible JupyterLab + MLflow Stack (Python</span><span class="yj-rel-p">$19</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/webflow-restaurant-template"><span class="yj-rel-t">Webflow Restaurant Template — delivered as self-contained HTML you own: 26 pag</span><span class="yj-rel-p">$49</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/actions-deprecation-lint-2026"><span class="yj-rel-t">GitHub Actions Deprecation Lint: the 2026 runner and action EOL dates</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><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 {"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[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>
76
- <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||'')})}).catch(function(){});}catch(e){}})();</script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  <meta name="viewport" content="width=device-width,initial-scale=1">
3
  <title>Base Image EOL Lint - Dockerfile and CI end-of-life check</title>
4
  <meta name="description" content="Marks every base image in your Dockerfiles, compose files and CI workflows whose security patches have already stopped - or stop before 13 November 2026 - and prints the tag that replaces it.">
 
5
  <style>
6
  :root{color-scheme:light dark}
7
  body{margin:0;font:16px/1.6 system-ui,-apple-system,"Segoe UI",sans-serif;
 
42
  </textarea>
43
  <button id="go">Check these images</button>
44
  <div id="out"></div>
45
+ <div class="next"><h2>In the full version</h2><ul><li>Every Dockerfile, compose file and workflow in the repository</li><li>A dated CSV, JSON or HTML report</li><li>JSON output that fails the build</li><li><a href="https://getreadystack.com/api/buy/cl/polar_cl_brZKgBkvnYrEIMElB5Ynt5gGEnqmTjvx9r9ZX3ljztR">Get the full version - $29</a></li></ul></div>
46
  </div>
47
  <script>
48
  var RULES=[{"pattern": "\\bnode:20\\b", "flags": "i", "sev": "error", "message": "node:20 - Node.js 20 reached end-of-life on 30 April 2026. No security release has shipped for it since. Replace with node:24-trixie (Active LTS to 30 April 2028).", "fix": "FROM node:24-trixie"}, {"pattern": "\\bnode:18\\b", "flags": "i", "sev": "error", "message": "node:18 - Node.js 18 reached end-of-life on 30 April 2025. Replace with node:24-trixie (Active LTS to 30 April 2028).", "fix": "FROM node:24-trixie"}, {"pattern": "\\bnode:(?:14|16)\\b", "flags": "i", "sev": "error", "message": "Node.js 14 (end-of-life 30 April 2023) and Node.js 16 (11 September 2023) have been unpatched for over two years. Replace with node:24-trixie.", "fix": "FROM node:24-trixie"}, {"pattern": "\\bpython:3\\.(?:7|8|9)\\b", "flags": "i", "sev": "error", "message": "Python 3.9 reached end-of-life on 31 October 2025 (3.8 on 7 October 2024, 3.7 on 27 June 2023). 3.9.25 was the final security release. Replace with python:3.13-trixie.", "fix": "FROM python:3.13-trixie"}, {"pattern": "\\bpython:3\\.10\\b", "flags": "i", "sev": "warn", "message": "python:3.10 - Python 3.10 reaches end-of-life on 31 October 2026. After that date the PSF ships no further security patches. Replace with python:3.13-trixie.", "fix": "FROM python:3.13-trixie"}, {"pattern": "\\b(?:debian:11|bullseye)\\b", "flags": "i", "sev": "error", "message": "Debian 11 bullseye LTS ended on 31 August 2026 - no security updates from September 2026 onward. Replace with debian:trixie, or bookworm if you need LTS to 30 June 2028.", "fix": "FROM debian:trixie"}, {"pattern": "\\b(?:debian:(?:8|9|10)|buster|stretch|jessie)\\b", "flags": "i", "sev": "error", "message": "Debian 10 buster LTS ended on 30 June 2024; stretch and jessie are older still. Replace with debian:trixie.", "fix": "FROM debian:trixie"}, {"pattern": "\\b(?:ubuntu:20\\.04|ubuntu-20\\.04|ubuntu:focal|:focal\\b)", "flags": "i", "sev": "error", "message": "Ubuntu 20.04 focal left standard support on 31 May 2025. Patches now require a paid Ubuntu Pro (ESM) subscription. Replace with ubuntu:24.04, supported to April 2029.", "fix": "FROM ubuntu:24.04"}, {"pattern": "\\b(?:ubuntu:1[68]\\.04|ubuntu-1[68]\\.04|bionic|xenial)\\b", "flags": "i", "sev": "error", "message": "Ubuntu 18.04 bionic and 16.04 xenial left standard support in 2023 and 2021. Replace with ubuntu:24.04.", "fix": "FROM ubuntu:24.04"}, {"pattern": "\\balpine:3\\.(?:[0-9]|1[0-9]|20)\\b", "flags": "i", "sev": "error", "message": "This Alpine branch is out of support: 3.20 ended 1 April 2026, 3.19 on 1 November 2025, and everything older before that. Replace with alpine:3.23 (supported to 1 November 2027).", "fix": "FROM alpine:3.23"}, {"pattern": "\\balpine:3\\.21\\b", "flags": "i", "sev": "warn", "message": "alpine:3.21 - Alpine keeps a branch for two years, so 3.21 reaches end of support on 1 November 2026. Replace with alpine:3.23 (to 1 November 2027).", "fix": "FROM alpine:3.23"}, {"pattern": "\\bdotnet/(?:aspnet|sdk|runtime|samples):(?:6|7)\\.0\\b", "flags": "i", "sev": "error", "message": ".NET 6 reached end of support on 12 November 2024 and .NET 7 on 14 May 2024. Replace with mcr.microsoft.com/dotnet/aspnet:10.0 (LTS to 14 November 2028).", "fix": "FROM mcr.microsoft.com/dotnet/aspnet:10.0"}, {"pattern": "\\bdotnet/(?:aspnet|sdk|runtime|samples):(?:8|9)\\.0\\b", "flags": "i", "sev": "warn", "message": ".NET 8 (LTS) and .NET 9 (STS) both reach end of support on 10 November 2026 - the LTS release dies on the same day as the STS one. Replace with dotnet/aspnet:10.0, LTS to 14 November 2028.", "fix": "FROM mcr.microsoft.com/dotnet/aspnet:10.0"}, {"pattern": "\\bpostgres(?:ql)?:(?:9\\.[0-9]|1[0-3])\\b", "flags": "i", "sev": "error", "message": "PostgreSQL 13 reached end of life on 13 November 2025; 12 and older are further behind. The community ships no security patches for them. Replace with postgres:17.", "fix": "image: postgres:17"}, {"pattern": "\\bpostgres(?:ql)?:14\\b", "flags": "i", "sev": "warn", "message": "postgres:14 - PostgreSQL supports a major version for five years, so 14 reaches end of life on 12 November 2026. Replace with postgres:17.", "fix": "image: postgres:17"}, {"pattern": "\\bmysql:5\\.[0-9]\\b", "flags": "i", "sev": "error", "message": "MySQL 5.7 reached end of life on 31 October 2023 and 5.6 in February 2021. Replace with mysql:8.4, the current LTS.", "fix": "image: mysql:8.4"}, {"pattern": "\\bphp:(?:7\\.[0-9]|8\\.[01])\\b", "flags": "i", "sev": "error", "message": "PHP 8.1 security support ended on 31 December 2025; 8.0 and every 7.x are older. Replace with php:8.4-trixie.", "fix": "FROM php:8.4-trixie"}, {"pattern": "\\bphp:8\\.2\\b", "flags": "i", "sev": "warn", "message": "php:8.2 - PHP 8.2 reaches end of life on 31 December 2026, after which the PHP project ships no patches for it. Replace with php:8.4-trixie.", "fix": "FROM php:8.4-trixie"}, {"pattern": "\\bcentos:(?:6|7|8|stream8)\\b", "flags": "i", "sev": "error", "message": "CentOS 7 reached end of life on 30 June 2024 and CentOS 8 on 31 December 2021. The distribution line is finished. Replace with a maintained base such as debian:trixie.", "fix": "FROM debian:trixie"}, {"pattern": "\\bopenjdk:", "flags": "i", "sev": "warn", "message": "The openjdk Docker Official Image is deprecated and no longer updated. Replace with eclipse-temurin:21-jre-noble.", "fix": "FROM eclipse-temurin:21-jre-noble"}, {"pattern": "\\b[\\w./-]+:latest\\b", "flags": "i", "sev": "info", "message": "A :latest tag floats. The image you build today is not the image you built last month, so no end-of-life check - this one included - can tell you what is actually in the layer. Pin a dated tag.", "fix": "pin an explicit tag, e.g. FROM debian:trixie"}];
 
65
  </html>
66
 
67
 
68
+ <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.base-image-eol-lint" rel="noopener" data-yj-install-door="mp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'base-image-eol-lint',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><a href="https://open-vsx.org/extension/readystack/base-image-eol-lint" rel="noopener" data-yj-install-door="ovsx" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'base-image-eol-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><a href="https://www.npmjs.com/package/@readystack/base-image-eol-lint" rel="noopener" data-yj-install-door="npm" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'base-image-eol-lint',src:'npm',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">npm</a><a href="https://www.npmjs.com/package/@readystack/base-image-eol-lint" rel="noopener" data-yj-install-door="mcp" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'base-image-eol-lint',src:'mcp',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">MCP server (npx)</a><a href="https://hub.docker.com/r/getreadystack/base-image-eol-lint" rel="noopener" data-yj-install-door="docker" onclick="try{navigator.sendBeacon('/api/ev',new Blob([JSON.stringify({t:'install',slug:'base-image-eol-lint',src:'docker',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">Docker Hub</a><pre style="margin:.5rem 0 0;padding:.6rem .8rem;background:#f3f5f8;border-radius:8px;font-size:.9rem;overflow:auto">ext install ReadyStack.base-image-eol-lint
69
  npx @readystack/base-image-eol-lint &lt;file&gt;
70
+ npx @readystack/base-image-eol-lint --mcp</pre><p style="margin:.6rem 0 0;font-size:.92rem;color:#41505f"><a href="https://getreadystack.com/api/buy/cl/polar_cl_l6iN1uWt0FwWu7tBsczD0jWpP2vxFM54Wdwqb3KPi1G" rel="nofollow" style="color:#0f7b3f;text-decoration:underline">Team? One key for every ReadyStack linter, 5 seats, $149 once</a></p></section>
71
+ <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 the full rule table as a PDF</b><div style="opacity:.78;margin:.35rem 0 .8rem">All 21 rules Base Image EOL Lint - Dockerfile and CI end-of-life check checks, each with its source and date, on printable pages you can hand to your team or auditor. We email it now, and once more only if a rule changes. 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">Email me the PDF</button></div><div id="yjao" hidden style="margin-top:.6rem;color:#0f7b3f">Sent. It arrives within the hour - check spam too.</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:"base-image-eol-lint",lang:"en",source:"rule_table"+((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);})();</script></section>
72
 
73
+ <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 complete version <span class="yj-price">$29</span></h2><p style="margin:.25rem 0 1rem;color:#41505f">This page is the working piece. The full pack has everything below.</p><p style="margin:0 0 1rem;color:#41505f">Marks every base image in your Dockerfiles, compose files and CI workflows whose security patches have already stopped - or stop before 13 November 2026 - and prints the tag that replaces it</p><p style="margin:0 0 1rem;color:#5b6b7c;font-size:.94rem">Snyk's Team tier is $25 per contributing developer per month.</p><a href="https://getreadystack.com/api/buy/cl/polar_cl_brZKgBkvnYrEIMElB5Ynt5gGEnqmTjvx9r9ZX3ljztR" 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>
74
+ <!--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><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 {"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;"}[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>
75
+
76
+
77
+ <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>
78
+
79
+ <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>
80
+ <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-09">Updated 2026-09-09</time> · ReadyStack</p><script type="application/ld+json">{"@context":"https://schema.org","@type":"WebPage","dateModified":"2026-09-09","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/sku29827_result_card.jpg" alt="Five base images stop getting security patches - and they are all in one repo" loading="lazy" style="max-width:100%;border-radius:6px"></p>
81
+ <p>Five images in the snippet below have already stopped getting security patches or stop before 13 November 2026, and Base Image EOL Lint marks all five the moment a platform engineer opens the file:</p>
82
+ <pre><code>
83
+ FROM node:20-alpine
84
+ # api/Dockerfile
85
+ FROM python:3.10-slim
86
+ # .github/workflows/ci.yml
87
+ runs-on: ubuntu-20.04
88
+ # docker-compose.yml
89
+ image: postgres:14
90
+ # services/report/Dockerfile
91
+ FROM mcr.microsoft.com/dotnet/aspnet:8.0</code></pre>
92
+ <p>Line 2 pins Node.js 20, which reached end-of-life on <strong>30 April 2026</strong>. Line 6 pins the Ubuntu 20.04 runner, which left standard support on <strong>31 May 2025</strong> and now needs a paid Ubuntu Pro subscription to receive anything. Those two are already unpatched.</p>
93
+ <p>The other three are worse, because they are still fine today. Python 3.10 reaches end-of-life on <strong>31 October 2026</strong>. Alpine 3.21, which keeps a branch for two years, ends on <strong>1 November 2026</strong>. .NET 8 and .NET 9 both reach end of support on <strong>10 November 2026</strong> - the LTS release dies on the same day as the short-term one. PostgreSQL 14 follows on <strong>12 November 2026</strong>. Debian 11 bullseye already went on <strong>31 August 2026</strong>, so every <code>-bullseye</code> variant of every language image went with it.</p>
94
+ <p>That is four vendors retiring five runtimes inside a fortnight, and nothing in your monitoring will go red on any of those days. The container keeps starting. The build keeps passing. What stops is the flow of patches, and you find out at the next CVE.</p>
95
+ <p>The second failure is the one nobody plans for: the model wrote it. A code assistant trained before those dates will hand you <code>FROM node:20-bullseye</code> and <code>FROM python:3.10-slim</code> without hesitation, because both were the sensible answer when it learned them. Base images are the one place where a suggestion silently ages, and the year in the training data becomes the year in your Dockerfile.</p>
96
+ <p>Image scanners do not catch this. They test an image that has already been built and pushed, and they report the vulnerable packages inside it - a real job, and a different one. None of them opens the file on your screen and tells you that the <code>FROM</code> line names a runtime whose last security release is seven weeks away. By the time a scanner can see the image, you have already built it, tagged it and pushed it.</p>
97
+ <p>Base Image EOL Lint ships <strong>21 rules</strong> covering Node.js, Python, Debian, Ubuntu, Alpine, .NET, PostgreSQL, MySQL, PHP, CentOS, the deprecated <code>openjdk</code> official image and floating <code>:latest</code> tags. It runs per line, in the editor, with no network call, no account and no build step. Each finding carries a severity - <code>error</code> for an image that is already unpatched, <code>warn</code> for one with a date on the calendar - and the exact tag that replaces it: <code>node:20-alpine</code> becomes <code>node:24-trixie</code>, <code>python:3.10-slim</code> becomes <code>python:3.13-trixie</code>, <code>postgres:14</code> becomes <code>postgres:17</code>.</p>
98
+ <p>Checking the file you have open is free and complete: all 21 rules, every finding, every replacement, no watermark and no run limit. The licence changes the scope, not the answer - it walks every Dockerfile, compose file and workflow in the repository, writes a dated CSV, JSON or HTML report you can attach to a change ticket, and prints JSON that lets CI fail the build before an unpatched base image reaches production.</p>
99
+ <p>The first of those dates is 31 October 2026. Grep your repository for <code>-bullseye</code> today, or open the file and let 21 rules do it.</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/sku29827_result_card.jpg" style="width:100%;max-width:360px;border-radius:10px;display:block;margin:0 auto"><source src="/media/sku29827_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 Base Image EOL Lint actually do?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">It reads the image references written in your repository - Dockerfile FROM lines, docker-compose image keys, GitHub Actions runner labels and container images - and marks every one whose vendor has stopped shipping security patches, or stops soon, with the exact tag that replaces it and the date behind the finding.</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 it for?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Platform, DevOps and backend engineers who own the Dockerfiles and CI workflows in a repository: the person who answers when an auditor asks which base images are still supported, and the person who has to do the upgrade. If you maintain a multi-stage Dockerfile or a compose file, this reads your files.</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 will a free image scanner not do this?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free scanners test an image that has already been built and pushed, and they report the vulnerable packages inside it. They cannot open the Dockerfile on your screen and tell you that FROM python:3.10-slim names a runtime whose final security release lands on 31 October 2026. Nothing that needs a built image can.</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 needs a licence?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Free covers one whole file: open a Dockerfile, run the check, and all 21 rules report every finding with its severity and its replacement tag. Nothing is watermarked, timed or locked after N runs. The licence changes the scope only - every file in the repository at once, a dated exported report, and JSON for CI.</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 would this cost otherwise?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">Snyk&#x27;s Team tier is $25 per contributing developer per month, and it still starts from a built image rather than the file you are editing. Auditing FROM lines by hand means grepping every repository each time a vendor retires a branch, which happens several times a year. This is $29 once.</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 ChatGPT or another AI chat?</summary><p style="margin:8px 0 2px;font:400 14.5px/1.6 system-ui,sans-serif;color:#33404b">A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. Dockerfile EOL Lint - base image end-of-life (FROM tags) checks the file you open against 21 rules from a rule set dated 2026-09-20, and points at the exact line with the fix. For a filing, an audit or a client you need that dated result on your own files.</p></details><script type="application/ld+json" data-yj="yj-faq-ld">{"@context": "https://schema.org", "@type": "FAQPage", "mainEntity": [{"@type": "Question", "name": "What does Base Image EOL Lint actually do?", "acceptedAnswer": {"@type": "Answer", "text": "It reads the image references written in your repository - Dockerfile FROM lines, docker-compose image keys, GitHub Actions runner labels and container images - and marks every one whose vendor has stopped shipping security patches, or stops soon, with the exact tag that replaces it and the date behind the finding."}}, {"@type": "Question", "name": "Who is it for?", "acceptedAnswer": {"@type": "Answer", "text": "Platform, DevOps and backend engineers who own the Dockerfiles and CI workflows in a repository: the person who answers when an auditor asks which base images are still supported, and the person who has to do the upgrade. If you maintain a multi-stage Dockerfile or a compose file, this reads your files."}}, {"@type": "Question", "name": "Why will a free image scanner not do this?", "acceptedAnswer": {"@type": "Answer", "text": "Free scanners test an image that has already been built and pushed, and they report the vulnerable packages inside it. They cannot open the Dockerfile on your screen and tell you that FROM python:3.10-slim names a runtime whose final security release lands on 31 October 2026. Nothing that needs a built image can."}}, {"@type": "Question", "name": "What is free and what needs a licence?", "acceptedAnswer": {"@type": "Answer", "text": "Free covers one whole file: open a Dockerfile, run the check, and all 21 rules report every finding with its severity and its replacement tag. Nothing is watermarked, timed or locked after N runs. The licence changes the scope only - every file in the repository at once, a dated exported report, and JSON for CI."}}, {"@type": "Question", "name": "What would this cost otherwise?", "acceptedAnswer": {"@type": "Answer", "text": "Snyk's Team tier is $25 per contributing developer per month, and it still starts from a built image rather than the file you are editing. Auditing FROM lines by hand means grepping every repository each time a vendor retires a branch, which happens several times a year. This is $29 once."}}, {"@type": "Question", "name": "Why not just ask ChatGPT or another AI chat?", "acceptedAnswer": {"@type": "Answer", "text": "A general AI chat answers from training data with a cutoff date, cannot read your repository and names no rule version. Dockerfile EOL Lint - base image end-of-life (FROM tags) checks the file you open against 21 rules from a rule set dated 2026-09-20, and points at the exact line with the fix. For a filing, an audit or a client you need that dated result on your own files."}}]}</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:29827,slug:"base-image-eol-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/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/runtime-eol-deploy-block-audit"><span class="yj-rel-t">Runtime EOL and Deploy-Block Audit for Docker, CI and AWS Lambda</span><span class="yj-rel-p">$29</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/docker-image-for-data-science"><span class="yj-rel-t">Docker Image for Data Science — Reproducible JupyterLab + MLflow Stack (Python</span><span class="yj-rel-p">$19</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/webflow-restaurant-template"><span class="yj-rel-t">Webflow Restaurant Template — delivered as self-contained HTML you own: 26 pag</span><span class="yj-rel-p">$49</span></a><a class="yj-rel-c" href="https://getreadystack.com/tools/dotnet-eol-support-gate"><span class="yj-rel-t">.NET EOL &amp; CRA Support Window Gate</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>