{"id":3465,"date":"2026-02-19T14:12:44","date_gmt":"2026-02-19T14:12:44","guid":{"rendered":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2026\/02\/19\/how-medplum-secured-their-healthcare-platform-with-docker-hardened-images-dhi\/"},"modified":"2026-02-19T14:12:44","modified_gmt":"2026-02-19T14:12:44","slug":"how-medplum-secured-their-healthcare-platform-with-docker-hardened-images-dhi","status":"publish","type":"post","link":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2026\/02\/19\/how-medplum-secured-their-healthcare-platform-with-docker-hardened-images-dhi\/","title":{"rendered":"How Medplum Secured Their Healthcare Platform with Docker Hardened Images (DHI)"},"content":{"rendered":"<p><em>Special thanks to <\/em><a href=\"https:\/\/www.linkedin.com\/in\/codyebberson\/\" rel=\"nofollow noopener\" target=\"_blank\"><em>Cody Ebberson <\/em><\/a><em>and the Medplum team for their open-source contribution and for sharing their migration experience with the community. A real-world example of migrating a HIPAA-compliant EHR platform to DHI with minimal code changes.<\/em><\/p>\n<p>Healthcare software runs on trust. When patient data is at stake, security isn\u2019t just a feature but a fundamental requirement. For healthcare platform providers, proving that trust to enterprise customers is an ongoing challenge that requires continuous investment in security posture, compliance certifications, and vulnerability management.<\/p>\n<p>That\u2019s why we\u2019re excited to share how <a href=\"https:\/\/www.medplum.com\/\" rel=\"nofollow noopener\" target=\"_blank\">Medplum<\/a>, an open-source healthcare platform serving over 20 million patients, recently migrated to Docker Hardened Images (DHI). This migration demonstrates exactly what we designed DHI to deliver: enterprise-grade security with minimal friction. Medplum\u2019s team made the switch with just 54 lines of changes across 5 files\u2014a near net-zero code change that dramatically improved their security posture.<\/p>\n<p><a href=\"https:\/\/www.medplum.com\/\" rel=\"nofollow noopener\" target=\"_blank\">Medplum<\/a> is a headless EHR\u2014the platform handles patient data, clinical workflows, and compliance so developers can focus on building healthcare apps. Built by and for healthcare developers, the platform provides:<\/p>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/www.medplum.com\/docs\/compliance\/hipaa\" rel=\"nofollow noopener\" target=\"_blank\"><strong>HIPAA<\/strong><\/a><strong> and <\/strong><a href=\"https:\/\/www.medplum.com\/docs\/compliance\/soc2\" rel=\"nofollow noopener\" target=\"_blank\"><strong>SOC2<\/strong><\/a><strong> compliance<\/strong> out of the box<\/li>\n<li><a href=\"https:\/\/www.medplum.com\/docs\/fhir-basics\" rel=\"nofollow noopener\" target=\"_blank\"><strong>FHIR<\/strong><\/a><strong> R4 API<\/strong> for healthcare data interoperability<\/li>\n<li><strong>Self-hosted or managed deployment<\/strong> options<\/li>\n<li>Support for <strong>20+ million patients<\/strong> across hundreds of practices<\/li>\n<\/ul>\n<p>With over <strong>500,000 pulls on Docker Hub<\/strong> for their<a href=\"https:\/\/hub.docker.com\/r\/medplum\/medplum-server\" rel=\"nofollow noopener\" target=\"_blank\"> medplum-server image<\/a>, Medplum has become a trusted foundation for healthcare developers worldwide. As an open-source project licensed under Apache 2.0, their entire codebase\u2014including Docker configurations\u2014is publicly available on<a href=\"https:\/\/github.com\/medplum\/medplum\" rel=\"nofollow noopener\" target=\"_blank\"> GitHub<\/a>. This transparency made their DHI migration a perfect case study for the community.<\/p>\n<div class=\"wp-block-ponyo-image\">\n                <img data-opt-id=1968389129  fetchpriority=\"high\" decoding=\"async\" width=\"1880\" height=\"1586\" src=\"https:\/\/www.docker.com\/app\/uploads\/2026\/02\/image1-1.png\" class=\"fade-in attachment-full size-full\" alt=\"Diagram of Medplum as headless EHR\" title=\"- image1 1\" \/>\n        <\/div>\n<p><em>Caption: Medplum is a headless EHR \u2014 the platform handles patient data, clinical workflows, and compliance so developers can focus on building healthcare apps.<\/em><\/p>\n<p>Medplum is developer-first. It\u2019s not a plug-and-play low-code tool\u2014it\u2019s designed for engineering teams that want a strong FHIR-based foundation with full control over the codebase.<\/p>\n<h2 class=\"wp-block-heading\">The Challenge: Vulnerability Noise and Security Toil<\/h2>\n<p>Healthcare software development comes with unique challenges. Integration with existing EHR systems, compliance with regulations like HIPAA, and the need for robust security all add complexity and cost to development cycles.<\/p>\n<div class=\"wp-block-ponyo-simon organism\">\n<div class=\"container\">\n<h4 class=\"quote-size__small fade-in\">\u201cThe Medplum team found themselves facing a challenge common to many high-growth platforms: \u201cVulnerability Noise.\u201d Even with lean base images, standard distributions often include non-essential packages that trigger security flags during enterprise audits. For a company helping others achieve HIPAA compliance, every \u201cLow\u201d or \u201cMedium\u201d CVE (Common Vulnerability and Exposure) requires investigation and documentation, creating significant \u201csecurity toil\u201d for their engineering team.\u201d<\/h4>\n<div class=\"speaker-container fade-in\">\n<p class=\"name\">Reshma Khilnani<\/p>\n<p class=\"title\">CEO, Medplum<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p>Medplum addresses this by providing a compliant foundation. But even with that foundation, their team found themselves facing another challenge common to high-growth platforms: <strong>\u201cVulnerability Noise.\u201d<\/strong><\/p>\n<p>Healthcare is one of the most security-conscious industries. Medplum\u2019s enterprise customers\u2014including Series C and D funded digital health companies\u2014don\u2019t just ask about security; they actively verify it. These customers routinely scan Medplum\u2019s Docker images as part of their security due diligence.<\/p>\n<p>Even with lean base images, standard distributions often include non-essential packages that trigger security flags during enterprise audits. For a company helping others achieve HIPAA compliance, every \u201cLow\u201d or \u201cMedium\u201d CVE requires investigation and documentation. This creates significant \u201csecurity toil\u201d for their engineering team.<\/p>\n<h2 class=\"wp-block-heading\">The First Attempt: Distroless<\/h2>\n<p>This wasn\u2019t Medplum\u2019s first attempt at solving the problem. Back in November 2024, the team investigated Google\u2019s distroless images as a potential solution.<\/p>\n<p>The motivations were similar to what DHI would later deliver:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Less surface area<\/strong> in production images, and therefore less CVE noise<\/li>\n<li><strong>Smaller images<\/strong> for faster deployments<\/li>\n<li><strong>Simpler build process<\/strong> without manual hardening scripts<\/li>\n<\/ul>\n<p>The idea was sound. Distroless images strip away everything except the application runtime\u2014no shell, no package manager, minimal attack surface. On paper, it was exactly what Medplum needed.<\/p>\n<p>But the results were mixed. Image sizes actually increased. Build times went up. There were concerns about multi-architecture support for native dependencies. The<a href=\"https:\/\/github.com\/medplum\/medplum\/pull\/5538\" rel=\"nofollow noopener\" target=\"_blank\"> PR was closed<\/a> without merging.<\/p>\n<p>The core problem remained: many CVEs in standard images simply aren\u2019t actionable. Often there isn\u2019t a fix available, so all you can do is document and explain why it doesn\u2019t apply to your use case. And often the vulnerability is in a corner of the image you\u2019re not even using\u2014like Perl, which comes preinstalled on Debian but serves no purpose in a Node.js application.<\/p>\n<p>Fully removing these unused components is the only real answer. The team knew they needed hardened images. They just hadn\u2019t found the right solution yet.<\/p>\n<h2 class=\"wp-block-heading\">The Solution: Docker Hardened Images<\/h2>\n<p>When <a href=\"https:\/\/www.docker.com\/press-release\/docker-makes-hardened-images-free-open-and-transparent-for-everyone\/\">Docker made Hardened Images freely available <\/a>under Apache 2.0, Medplum\u2019s team saw an opportunity to simplify their security posture while maintaining compatibility with their existing workflows.<\/p>\n<p>By switching to Docker Hardened Images, Medplum was able to <strong>offload the repetitive work of OS-level hardening<\/strong>\u2014like configuring non-root users and stripping out unnecessary binaries\u2014to Docker. This allowed them to provide their users with a <strong>\u201cSecure-by-Default\u201d<\/strong> image that meets enterprise requirements without adding complexity to their open-source codebase.<\/p>\n<p>This shift is particularly significant for an open-source project. Rather than maintaining custom hardening scripts that contributors need to understand and maintain, Medplum can now rely on Docker\u2019s expertise and continuous maintenance. The security posture improves automatically with each DHI update, without requiring changes to Medplum\u2019s Dockerfiles.<\/p>\n<div class=\"wp-block-ponyo-simon organism\">\n<div class=\"container\">\n<h4 class=\"quote-size__small fade-in\">\u201cBy switching to Docker Hardened Images, Medplum was able to offload the repetitive work of OS-level hardening\u2014like configuring non-root users and stripping out unnecessary binaries\u2014to Docker. This allowed their users to provide their users with a \u201cSecure-by-Default\u201d image that meets enterprise requirements without adding complexity to their open-source codebase.\u201d<\/h4>\n<div class=\"speaker-container fade-in\">\n<p class=\"name\">Cody Ebberson<\/p>\n<p class=\"title\">CTO, Medplum<\/p>\n<\/div>\n<\/div>\n<\/div>\n<h2 class=\"wp-block-heading\">The Migration: Real Code Changes<\/h2>\n<p>The migration was remarkably clean. Previously, Medplum\u2019s Dockerfile required manual steps to ensure security best practices. By moving to DHI, they could simplify their configuration significantly.<\/p>\n<p>Let\u2019s look at what actually changed. Here\u2019s the complete server Dockerfile after the migration:<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\">\n# Medplum production Dockerfile\n# Uses Docker \"Hardened Images\":\n# https:\/\/hub.docker.com\/hardened-images\/catalog\/dhi\/node\/guides\n\n# Supported architectures: linux\/amd64, linux\/arm64\n\n# Stage 1: Build the application and install production dependencies\nFROM dhi.io\/node:24-dev AS build-stage\nENV NODE_ENV=production\nWORKDIR \/usr\/src\/medplum\nADD .\/medplum-server-metadata.tar.gz .\/\nRUN npm ci --omit=dev &amp;&amp; \n  rm package-lock.json\n\n# Stage 2: Create the runtime image\nFROM dhi.io\/node:24 AS runtime-stage\nENV NODE_ENV=production\nWORKDIR \/usr\/src\/medplum\nCOPY --from=build-stage \/usr\/src\/medplum\/ .\/\nADD .\/medplum-server-runtime.tar.gz .\/\n\nEXPOSE 5000 8103\n\nENTRYPOINT [ \"node\", \"--require\", \".\/packages\/server\/dist\/otel\/instrumentation.js\", \"packages\/server\/dist\/index.js\" ]\n<\/pre>\n<\/div>\n<p>Notice what\u2019s <strong>not<\/strong> there:<\/p>\n<ul class=\"wp-block-list\">\n<li>No <code>groupadd<\/code> or <code>useradd<\/code> commands \u2014 DHI runs as non-root by default<\/li>\n<li>No <code>chown<\/code> commands \u2014 permissions are already correct<\/li>\n<li>No <code>USER<\/code> directive \u2014 the default user is already non-privileged<\/li>\n<\/ul>\n<h3 class=\"wp-block-heading\">Before vs. After: Server Dockerfile<\/h3>\n<p>Before (node:24-slim):<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\">\nFROM node:24-slim\nENV NODE_ENV=production\nWORKDIR \/usr\/src\/medplum\n\nADD .\/medplum-server.tar.gz .\/\n\n# Install dependencies, create non-root user, and set permissions\nRUN npm ci &amp;&amp; \n  rm package-lock.json &amp;&amp; \n  groupadd -r medplum &amp;&amp; \n  useradd -r -g medplum medplum &amp;&amp; \n  chown -R medplum:medplum \/usr\/src\/medplum\n\nEXPOSE 5000 8103\n\n# Switch to the non-root user\nUSER medplum\n\nENTRYPOINT [ \"node\", \"--require\", \".\/packages\/server\/dist\/otel\/instrumentation.js\", \"packages\/server\/dist\/index.js\" ]\n<\/pre>\n<\/div>\n<p>After (dhi.io\/node:24):<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\">\nFROM dhi.io\/node:24-dev AS build-stage\nENV NODE_ENV=production\nWORKDIR \/usr\/src\/medplum\nADD .\/medplum-server-metadata.tar.gz .\/\nRUN npm ci --omit=dev &amp;&amp; rm package-lock.json\n\nFROM dhi.io\/node:24 AS runtime-stage\nENV NODE_ENV=production\nWORKDIR \/usr\/src\/medplum\nCOPY --from=build-stage \/usr\/src\/medplum\/ .\/\nADD .\/medplum-server-runtime.tar.gz .\/\n\nEXPOSE 5000 8103\n\nENTRYPOINT [ \"node\", \"--require\", \".\/packages\/server\/dist\/otel\/instrumentation.js\", \"packages\/server\/dist\/index.js\" ]\n<\/pre>\n<\/div>\n<p>The migration also introduced a cleaner multi-stage build pattern, separating metadata (package.json files) from runtime artifacts.<\/p>\n<h3 class=\"wp-block-heading\">Before vs. After: App Dockerfile (Nginx)<\/h3>\n<p>The web app migration was even more dramatic:<\/p>\n<p>Before (nginx-unprivileged:alpine):<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\">\nFROM nginxinc\/nginx-unprivileged:alpine\n\n# Start as root for permissions\nUSER root\n\nCOPY &lt;&lt;EOF \/etc\/nginx\/conf.d\/default.conf\n# ... nginx config ...\nEOF\n\nADD .\/medplum-app.tar.gz \/usr\/share\/nginx\/html\nCOPY .\/docker-entrypoint.sh \/docker-entrypoint.sh\n\n# Manual permission setup\nRUN chown -R 101:101 \/usr\/share\/nginx\/html &amp;&amp; \n    chown 101:101 \/docker-entrypoint.sh &amp;&amp; \n    chmod +x \/docker-entrypoint.sh\n\nEXPOSE 3000\n\n# Switch back to non-root\nUSER 101\n\nENTRYPOINT [\"\/docker-entrypoint.sh\"]\n<\/pre>\n<\/div>\n<p>After (dhi.io\/nginx:1):<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\">\nFROM dhi.io\/nginx:1\n\nCOPY &lt;&lt;EOF \/etc\/nginx\/nginx.conf\n# ... nginx config ...\nEOF\n\nADD .\/medplum-app.tar.gz \/usr\/share\/nginx\/html\nCOPY .\/docker-entrypoint.sh \/docker-entrypoint.sh\n\nEXPOSE 3000\n\nENTRYPOINT [\"\/docker-entrypoint.sh\"]\n\n<\/pre>\n<\/div>\n<h2 class=\"wp-block-heading\">Results: Improved Security Posture<\/h2>\n<p>After merging the changes, Medplum\u2019s team shared their improved security scan results. The migration to DHI resulted in:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Dramatically reduced CVE count<\/strong> \u2013 DHI\u2019s minimal base means fewer packages to patch<\/li>\n<li><strong>Non-root by default<\/strong> \u2013 No manual user configuration required<\/li>\n<li><strong>No shell access in production<\/strong> \u2013 Reduced attack surface for container escape attempts<\/li>\n<li><strong>Continuous patching<\/strong> \u2013 All DHI images are rebuilt when upstream security updates are available<\/li>\n<\/ul>\n<p>For organizations that require stronger guarantees, Docker Hardened Images Enterprise adds SLA-backed remediation timelines, image customizations, and FIPS\/STIG variants.<\/p>\n<p>Most importantly, all of this was achieved with <strong>zero functional changes<\/strong> to the application. The same tests passed, the same workflows worked, and the same deployment process applied.<\/p>\n<h2 class=\"wp-block-heading\">CI\/CD Integration<\/h2>\n<p>Medplum also updated their GitHub Actions workflow to authenticate with the DHI registry:<\/p>\n<div class=\"wp-block-syntaxhighlighter-code \">\n<pre class=\"brush: bash; gutter: false; title: ; notranslate\">\n- name: Login to Docker Hub\n  uses: docker\/login-action@v2.2.0\n  with:\n    username: ${{ secrets.DOCKERHUB_USERNAME }}\n    password: ${{ secrets.DOCKERHUB_TOKEN }}\n\n- name: Login to Docker Hub Hardened Images\n  uses: docker\/login-action@v2.2.0\n  with:\n    registry: dhi.io\n    username: ${{ secrets.DOCKERHUB_USERNAME }}\n    password: ${{ secrets.DOCKERHUB_TOKEN }}\n<\/pre>\n<\/div>\n<p>This allows their CI\/CD pipeline to pull hardened base images during builds. The same Docker Hub credentials work for both standard and hardened image registries.<\/p>\n<h2 class=\"wp-block-heading\">The Multi-Stage Pattern for DHI<\/h2>\n<p>One pattern worth highlighting from Medplum\u2019s migration is the use of multi-stage builds with DHI variants:<\/p>\n<ol class=\"wp-block-list\">\n<li><strong>Build stage<\/strong>: Use <code>dhi.io\/node:24-dev<\/code> which includes npm\/yarn for installing dependencies<\/li>\n<li><strong>Runtime stage<\/strong>: Use <code>dhi.io\/node:24<\/code> which is minimal and doesn\u2019t include package managers<\/li>\n<\/ol>\n<p>This pattern ensures that build tools never make it into the production image, further reducing the attack surface. It\u2019s a best practice for any containerized Node.js application, and DHI makes it straightforward by providing purpose-built variants for each stage.<\/p>\n<h3 class=\"wp-block-heading\">Medplum\u2019s Production Architecture<\/h3>\n<p>Medplum\u2019s hosted offering runs on AWS using containerized workloads. Their <code>medplum\/medplum-server<\/code> image\u2014built on DHI base images\u2014now deploys to production.<\/p>\n<div class=\"wp-block-ponyo-image\">\n                <img data-opt-id=2011249333  fetchpriority=\"high\" decoding=\"async\" width=\"1999\" height=\"1114\" src=\"https:\/\/www.docker.com\/app\/uploads\/2026\/02\/image2-1.png\" class=\"fade-in attachment-full size-full\" alt=\"Medplum production architecture\" title=\"- image2 1\" \/>\n        <\/div>\n<p>Here\u2019s how the build-to-deploy flow works:<\/p>\n<ol class=\"wp-block-list\">\n<li><strong>Build time<\/strong>: GitHub Actions pulls <code>dhi.io\/node:24-dev<\/code> and <code>dhi.io\/node:24<\/code> as base images<\/li>\n<li><strong>Push<\/strong>: The resulting hardened image is pushed to <code>medplum\/medplum-server<\/code> on Docker Hub<\/li>\n<li><strong>Deploy<\/strong>: AWS Fargate pulls <code>medplum\/medplum-server:latest<\/code> and runs the hardened container<\/li>\n<\/ol>\n<p>The deployed containers inherit all DHI security properties\u2014non-root execution, minimal attack surface, no shell\u2014because they\u2019re built on DHI base images. This demonstrates that DHI works seamlessly with production-grade infrastructure including:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>AWS Fargate\/ECS<\/strong> for container orchestration<\/li>\n<li><strong>Elastic Load Balancing<\/strong> for high availability<\/li>\n<li><strong>Aurora PostgreSQL<\/strong> for managed database<\/li>\n<li><strong>ElastiCache<\/strong> for Redis caching<\/li>\n<li><strong>CloudFront<\/strong> for CDN and static assets<\/li>\n<\/ul>\n<p>No infrastructure changes were required. The same deployment pipeline, the same Fargate configuration\u2014just a more secure base image.<\/p>\n<h2 class=\"wp-block-heading\">Why This Matters for Healthcare<\/h2>\n<p>For healthcare organizations evaluating container security, Medplum\u2019s migration offers several lessons:<\/p>\n<p><strong>1. Eliminating \u201cVulnerability Noise\u201d<\/strong><\/p>\n<p>The biggest win from DHI isn\u2019t just security\u2014it\u2019s reducing the operational burden of security. Fewer packages means fewer CVEs to investigate, document, and explain to customers. For teams without dedicated security staff, this reclaimed time is invaluable.<\/p>\n<p><strong>2. Compliance-Friendly Defaults<\/strong><\/p>\n<p>HIPAA requires covered entities to implement technical safeguards including access controls and audit controls. DHI\u2019s non-root default and minimal attack surface align with these requirements out of the box. For companies pursuing SOC 2 Type 2 certification\u2014which Medplum implemented from Day 1\u2014or HITRUST certification, DHI provides a stronger foundation for the technical controls auditors evaluate.<\/p>\n<p><strong>3. Reduced Audit Surface<\/strong><\/p>\n<p>When security teams audit container configurations, DHI provides a cleaner story. Instead of explaining custom hardening scripts or why certain CVEs don\u2019t apply, teams can point to Docker\u2019s documented hardening methodology, SLSA Level 3 provenance, and independent security <a href=\"https:\/\/www.docker.com\/blog\/docker-hardened-images-security-independently-validated-by-srlabs\/\">validation<\/a> by SRLabs. This is particularly valuable during enterprise sales cycles where customers scan vendor images as part of due diligence.<\/p>\n<p><strong>4. Practicing What You Preach<\/strong><\/p>\n<p>For platforms like Medplum that help customers achieve compliance, using hardened images isn\u2019t just good security\u2014it\u2019s good business. When you\u2019re helping healthcare organizations meet regulatory requirements, your own infrastructure needs to set the example.<\/p>\n<p><strong>5. Faster Security Response<\/strong><\/p>\n<p>With <strong>DHI Enterprise<\/strong>, critical CVEs are patched within 7 days. For healthcare organizations where security incidents can have regulatory implications, this SLA provides meaningful risk reduction\u2014and a concrete commitment to share with customers.<\/p>\n<h2 class=\"wp-block-heading\"><strong>Conclusion<\/strong><\/h2>\n<p>Medplum\u2019s migration to Docker Hardened Images demonstrates that improving container security doesn\u2019t have to be painful. With minimal code changes\u201454 additions and 52 deletions\u2014they achieved:<\/p>\n<ul class=\"wp-block-list\">\n<li><strong>Secure-by-Default<\/strong> images that meet enterprise requirements<\/li>\n<li>Automatic non-root execution<\/li>\n<li>Dramatically reduced CVE surface<\/li>\n<li>Simplified Dockerfiles with no manual hardening scripts<\/li>\n<li>Less \u201csecurity toil\u201d for their engineering team<\/li>\n<li>A stronger compliance story for enterprise customers<\/li>\n<\/ul>\n<p>By offloading OS-level hardening to Docker, Medplum can focus on what they do best\u2014building healthcare infrastructure\u2014while their security posture improves automatically with each DHI update.<\/p>\n<p>For a platform with 500,000+ Docker Hub pulls serving healthcare organizations worldwide, this migration shows that DHI is ready for production workloads at scale. More importantly, it shows that security improvements can actually <em>reduce<\/em> operational burden rather than add to it.<\/p>\n<p>For platforms helping others achieve compliance, practicing what you preach matters. With Docker Hardened Images, that just got a lot easier.<\/p>\n<p>Ready to harden your containers? Explore the <a href=\"https:\/\/docs.docker.com\/dhi\/\" rel=\"nofollow noopener\" target=\"_blank\">Docker Hardened Images documentation<\/a> or browse the <a href=\"https:\/\/hub.docker.com\/hardened-images\/catalog\" rel=\"nofollow noopener\" target=\"_blank\">free DHI catalog<\/a> to find hardened versions of your favorite base images.<\/p>\n<h3 class=\"wp-block-heading\"><strong>Resources<\/strong><\/h3>\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/github.com\/medplum\/medplum\/pull\/8109\" rel=\"nofollow noopener\" target=\"_blank\">Medplum DHI Pull Request<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/medplum\/medplum\" rel=\"nofollow noopener\" target=\"_blank\">Medplum GitHub Repository<\/a><\/li>\n<li><a href=\"https:\/\/docs.docker.com\/dhi\/\" rel=\"nofollow noopener\" target=\"_blank\">Docker Hardened Images Documentation<\/a><\/li>\n<li><a href=\"https:\/\/www.docker.com\/blog\/docker-hardened-images-for-every-developer\/\">DHI Free Announcement<\/a><\/li>\n<li><a href=\"https:\/\/hub.docker.com\/hardened-images\/catalog\/dhi\/node\/guides\" rel=\"nofollow noopener\" target=\"_blank\">DHI Node.js Guide<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Special thanks to Cody Ebberson and the Medplum team for their open-source contribution and for sharing their migration experience with [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3466,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[4],"tags":[],"class_list":["post-3465","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-docker"],"_links":{"self":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/3465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/comments?post=3465"}],"version-history":[{"count":0,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/3465\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media\/3466"}],"wp:attachment":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media?parent=3465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/categories?post=3465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/tags?post=3465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}