{"id":3869,"date":"2025-07-07T15:25:29","date_gmt":"2025-07-07T18:25:29","guid":{"rendered":"\/blog\/?p=3869"},"modified":"2026-04-06T10:16:59","modified_gmt":"2026-04-06T13:16:59","slug":"automating-docker-builds-monorepo-github-actions","status":"publish","type":"post","link":"https:\/\/beon.tech\/blog\/automating-docker-builds-monorepo-github-actions\/","title":{"rendered":"Automating Docker Builds for a Monorepo with Multiple Microservices with GitHub Actions: A Step-by-Step Guide"},"content":{"rendered":"\n<p>In today&#8217;s microservices architecture, you might have several services in one repository, you even may have a monorepo with all your applications in a single place! But what if only a single service changed? What if a subset of them changed? In this tutorial, we\u2019ll set up a GitHub Action that:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Detects changes<\/strong> in the<mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\"> app\/**<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\"> <\/mark>folder (you may modify the name based on your personal need) where multiple microservices live.<\/li>\n\n\n\n<li><strong>Builds and pushes Docker images<\/strong> only for the changed services.<\/li>\n\n\n\n<li><strong>Triggers a deployment<\/strong> using ArgoCD (but you may want to use a different CD tech, no worries).<\/li>\n<\/ol>\n\n\n\n<p>Let&#8217;s dive in step-by-step!&nbsp;<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Prerequisites<\/strong><\/h2>\n\n\n\n<p>Before you begin, make sure you have:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A GitHub repository set up<\/li>\n\n\n\n<li>Basic knowledge of Docker and GitHub Actions<\/li>\n\n\n\n<li><a href=\"https:\/\/cli.github.com\/\">GitHub CLI<\/a> installed (for managing secrets)<\/li>\n\n\n\n<li>Docker installed on your machine<\/li>\n\n\n\n<li>A working ArgoCD installation<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 1: Setting Up Your Repository &amp; Folder Structure<\/strong><\/h2>\n\n\n\n<p>Assume you have a repository with multiple microservices, each with its own <mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">Dockerfile<\/mark>. Your repository might look like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"785\" height=\"537\" src=\"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/image-1.png\" alt=\"Example of Github repository\" class=\"wp-image-3875\" srcset=\"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/image-1.png 785w, https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/image-1-300x205.png 300w, https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/image-1-768x525.png 768w\" sizes=\"auto, (max-width: 785px) 100vw, 785px\" \/><\/figure>\n\n\n\n<p>Here, our GitHub Action will <strong>only build images for the services that changed<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 2: Creating the Dynamic GitHub Action Workflow<\/strong><\/h2>\n\n\n\n<p>We need to first detect which microservices in the app\/ folder have changed. We&#8217;ll do this in a dedicated job that creates a dynamic matrix for the build job.<\/p>\n\n\n\n<p>Create the file<mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-light-green-cyan-color\"> <\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\">.<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">github\/workflows\/docker-build.yml<\/mark><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-vivid-green-cyan-color\"> <\/mark>with the following content:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"yaml\" class=\"language-yaml\">name: Docker Build for Changed Microservices\n\n\non:\n push:\n   paths:\n     - 'app\/**'\n\n\njobs:\n detect:\n   name: Detect Changed Services\n   runs-on: ubuntu-latest\n   outputs:\n     matrix: ${{ steps.get-matrix.outputs.matrix }}\n   steps:\n     - name: Checkout Repository Code\n       uses: actions\/checkout@v3\n       with:\n         fetch-depth: 0\n\n\n     - name: Determine Changed Services\n       id: get-matrix\n       shell: bash\n       run: |\n         cd $GITHUB_WORKSPACE\n        echo \"Detecting changes...\"\n        CHANGED_FOLDERS=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} app | awk -F\/ '!($2 ~ \/^(Dockerfile|SomeFileYouDoNotWantToDetect|Makefile)$\/) {print $2}' | sort -u | xargs)\n        echo \"Changed folders: $CHANGED_FOLDERS\"\n\n\n        matrix=\"{\\\"include\\\": [\"\n        first=1\n        for service in $CHANGED_FOLDERS; do\n          if [ -f \"app\/${service}\/Dockerfile\" ]; then\n            if [ $first -eq 0 ]; then\n              matrix+=\",\"\n            fi\n            matrix+=\"{\\\"service\\\": \\\"${service}\\\"}\"\n            first=0\n          fi\n        done\n        matrix+=\"]}\"\n       \n        echo \"Matrix for build job: $matrix\"\n        echo \"matrix=$matrix\" &gt;&gt; $GITHUB_OUTPUT\n\n\n     - name: Validate Matrix\n       if: ${{ fromJson(steps.get-matrix.outputs.matrix).include[0] == null }}\n       run: |\n         echo \"Output from previous step:\"\n        echo \"${{ fromJson(steps.get-matrix.outputs.matrix).include.length }}\"\n        echo \"${{ steps.get-matrix.outputs.matrix }}\"\n        echo \"No services with a Dockerfile were changed. Exiting gracefully.\"\n        exit 0\n\n\n build:\n   name: Build &amp; Push Docker Images\n   needs: detect\n   runs-on: ubuntu-latest\n   if: ${{ fromJson(needs.detect.outputs.matrix).include[0] != null }}\n   strategy:\n     matrix: ${{ fromJson(needs.detect.outputs.matrix) }}\n   env:\n     DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}\n     DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}\n   steps:\n     - name: Checkout Repository\n       uses: actions\/checkout@v3\n\n\n     - name: Set up Docker Buildx\n       uses: docker\/setup-buildx-action@v2\n\n\n     - name: Login to DockerHub\n       uses: docker\/login-action@v2\n       with:\n         registry: ghcr.io\n         username: juliolugo96 # Change to your Github username\n         password: ${{ github.token }}\n\n\n     - name: Build and Push Docker Image for ${{ matrix.service }}\n       uses: docker\/build-push-action@v4\n       with:\n         context: .\/app\/${{ matrix.service }}\n         file: .\/app\/${{ matrix.service }}\/Dockerfile\n         push: true\n         tags: ghcr.io\/juliolugo96\/${{ matrix.service }}:${{ github.sha }},ghcr.io\/juliolugo96\/${{ matrix.service }}:latest\n\n\n     # - name: Trigger ArgoCD Deployment for ${{ matrix.service }}\n     #   env:\n     #     ARGOCD_TOKEN: ${{ secrets.ARGOCD_TOKEN }}\n     #     ARGOCD_SERVER: ${{ secrets.ARGOCD_SERVER }}\n     #   run: |\n     #     curl -H \"Authorization: Bearer ${ARGOCD_TOKEN}\"           -X POST \"https:\/\/${ARGOCD_SERVER}\/api\/v1\/applications\/your-argocd-app-${{ matrix.service }}\/sync\"\n<\/code><\/pre>\n\n\n\n<div class=\"wp-block-genesis-blocks-gb-container gb-block-container\"><div class=\"gb-container-inside\"><div class=\"gb-container-content\">\n<div class=\"wp-block-genesis-blocks-gb-container gb-block-container\"><div class=\"gb-container-inside\"><div class=\"gb-container-content\"><\/div><\/div><\/div>\n<\/div><\/div><\/div>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>How It Works:<\/strong><\/h3>\n\n\n\n<p>Such a beautiful yet simple code, right? Let me show you how it works:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Detect Job:<\/strong><strong><br><\/strong>\n<ul class=\"wp-block-list\">\n<li>Checks out your repository.<\/li>\n\n\n\n<li>Uses git diff to determine which files in app\/ changed.<\/li>\n\n\n\n<li>Extracts the service names (assumes structure app\/&lt;service&gt;\/&#8230;).<\/li>\n\n\n\n<li>Validates that a Dockerfile exists in each service folder.<\/li>\n\n\n\n<li>Outputs a JSON matrix containing only the changed services.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Build Job:<\/strong><strong><br><\/strong>\n<ul class=\"wp-block-list\">\n<li>Runs for each service in the matrix.<\/li>\n\n\n\n<li>Checks out the repository and sets up Docker Buildx.<\/li>\n\n\n\n<li>Logs into GHCR using your secrets.<\/li>\n\n\n\n<li>Builds and pushes the Docker image for the specific service.<\/li>\n\n\n\n<li>Triggers an ArgoCD sync for the corresponding application.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p><strong>Note:<\/strong> Adjust the Docker image tags and ArgoCD endpoints to match your environment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 3: Defining Environment Variables &amp; Secrets<\/strong><\/h2>\n\n\n\n<p>Since our workflow relies on environment variables and secrets, you can automate their setup using the following shell script with GitHub CLI.<\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<h3 class=\"wp-block-heading\"><strong><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">setup-secrets.sh<\/mark><\/strong><\/h3>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">#!\/bin\/bash<\/mark><\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\"># Ensure you are logged in with GitHub CLI: gh auth login<\/mark><\/p>\n<\/div>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">REPO=&#8221;your-github-username\/your-repository&#8221;<\/mark><\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\"># Set DockerHub credentials<\/mark><\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">gh secret set DOCKER_USERNAME &#8211;repo $REPO &#8211;body &#8220;your-dockerhub-username&#8221;<\/mark><\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">gh secret set DOCKER_PASSWORD &#8211;repo $REPO &#8211;body &#8220;your-dockerhub-password&#8221;<\/mark><\/p>\n<\/div>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\"># Set ArgoCD credentials<\/mark><\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">gh secret set ARGOCD_TOKEN &#8211;repo $REPO &#8211;body &#8220;your-argocd-token&#8221;<\/mark><\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">gh secret set ARGOCD_SERVER &#8211;repo $REPO &#8211;body &#8220;your-argocd-server-address&#8221;<\/mark><\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">echo &#8220;Secrets have been set for $REPO!&#8221;<\/mark><\/p>\n\n\n\n<p><\/p>\n<\/div>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0)\" class=\"has-inline-color has-black-color\">Run this script from your terminal:<\/mark><\/p>\n\n\n\n<p><\/p>\n\n\n\n<div class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">chmod +x setup-secrets.sh<\/mark><\/p>\n\n\n\n<p><mark style=\"background-color:rgba(0, 0, 0, 0);color:#073d00\" class=\"has-inline-color\">.\/setup-secrets.sh<\/mark><\/p>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 4: Deploying with ArgoCD<\/strong><\/h2>\n\n\n\n<p>Once a Docker image is built and pushed, our workflow triggers an ArgoCD sync. This sync uses a simple curl command to notify ArgoCD that the application (per microservice) has been updated.<\/p>\n\n\n\n<p>If your deployment strategy is more complex, consider:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Using the<a href=\"https:\/\/argo-cd.readthedocs.io\/en\/stable\/cli_installation\/\"> ArgoCD CLI<\/a> action.<\/li>\n\n\n\n<li>Creating dedicated ArgoCD projects for each microservice.<\/li>\n<\/ul>\n\n\n\n<p>Check ArgoCD&#8217;s<a href=\"https:\/\/argo-cd.readthedocs.io\/\"> documentation<\/a> for more advanced deployment configurations.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Wrapping Up<\/strong><\/h2>\n\n\n\n<p><strong>Congratulations!<\/strong> You now have a fully automated CI\/CD pipeline that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Detects changes<\/strong> in individual microservices within the app\/ folder.<\/li>\n\n\n\n<li><strong>Builds and pushes Docker images<\/strong> only for the changed services.<\/li>\n\n\n\n<li><strong>Triggers deployments<\/strong> via ArgoCD for each updated microservice.<\/li>\n<\/ul>\n\n\n\n<p>This setup helps you efficiently manage multiple microservices within a single repository. Customize and expand the workflow to suit your project\u2019s needs, and enjoy a smoother DevOps experience!&nbsp;<\/p>\n\n\n\n<p>Want to see the full code in action? <a href=\"https:\/\/github.com\/juliolugo96\/monorepo-github-actions\">Check out the repository <\/a>.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In today&#8217;s microservices architecture, you might have several services in one repository, you even may have a monorepo with all your applications in a single place! But what if only a single service changed? What if a subset of them changed? In this tutorial, we\u2019ll set up a GitHub Action that: Let&#8217;s dive in step-by-step!&nbsp;<a class=\"read_more_linkk\" href=\"https:\/\/beon.tech\/blog\/automating-docker-builds-monorepo-github-actions\/\">&#8230;<\/a><\/p>\n","protected":false},"author":47,"featured_media":3871,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_sitemap_exclude":false,"_sitemap_priority":"","_sitemap_frequency":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[168],"tags":[421,437,439],"class_list":["post-3869","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technical-engineering","tag-ai-for-software-engineering","tag-coding","tag-docker"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.6 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Automating Docker Builds in a Monorepo with GitHub Actions | BEON.tech Blog<\/title>\n<meta name=\"description\" content=\"Learn how to automate Docker builds for multiple microservices in a monorepo using GitHub Actions. Detect changes, build only what\u2019s needed, and trigger deployments with ArgoCD.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/beon.tech\/blog\/automating-docker-builds-monorepo-github-actions\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Automating Docker Builds in a Monorepo with GitHub Actions | BEON.tech Blog\" \/>\n<meta property=\"og:description\" content=\"Learn how to automate Docker builds for multiple microservices in a monorepo using GitHub Actions. Detect changes, build only what\u2019s needed, and trigger deployments with ArgoCD.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/beon.tech\/blog\/automating-docker-builds-monorepo-github-actions\/\" \/>\n<meta property=\"og:site_name\" content=\"Software &amp; Tech Hiring Insights | BEON.tech Blog\" \/>\n<meta property=\"article:published_time\" content=\"2025-07-07T18:25:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-04-06T13:16:59+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/Software-Developer-at-Work.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"904\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Julio Lugo\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@beontechok\" \/>\n<meta name=\"twitter:site\" content=\"@beontechok\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Julio Lugo\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"3 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/\"},\"author\":{\"name\":\"Julio Lugo\",\"@id\":\"https:\\\/\\\/beon.tech\\\/blog\\\/#\\\/schema\\\/person\\\/0e4d4e9639237b3b68f319e92475a6fb\"},\"headline\":\"Automating Docker Builds for a Monorepo with Multiple Microservices with GitHub Actions: A Step-by-Step Guide\",\"datePublished\":\"2025-07-07T18:25:29+00:00\",\"dateModified\":\"2026-04-06T13:16:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/\"},\"wordCount\":614,\"image\":{\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/beon.tech\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/Software-Developer-at-Work.png\",\"keywords\":[\"AI for Software Engineering\",\"Coding\",\"Docker\"],\"articleSection\":[\"Technical Engineering\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/\",\"url\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/\",\"name\":\"Automating Docker Builds in a Monorepo with GitHub Actions | BEON.tech Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/beon.tech\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/beon.tech\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/Software-Developer-at-Work.png\",\"datePublished\":\"2025-07-07T18:25:29+00:00\",\"dateModified\":\"2026-04-06T13:16:59+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/beon.tech\\\/blog\\\/#\\\/schema\\\/person\\\/0e4d4e9639237b3b68f319e92475a6fb\"},\"description\":\"Learn how to automate Docker builds for multiple microservices in a monorepo using GitHub Actions. Detect changes, build only what\u2019s needed, and trigger deployments with ArgoCD.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/#primaryimage\",\"url\":\"https:\\\/\\\/beon.tech\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/Software-Developer-at-Work.png\",\"contentUrl\":\"https:\\\/\\\/beon.tech\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/07\\\/Software-Developer-at-Work.png\",\"width\":1200,\"height\":904,\"caption\":\"Man coding at a desk with three monitors in a purple-lit room, focused on programming tasks.\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/beontech.wpengine.com\\\/automating-docker-builds-monorepo-github-actions\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/beon.tech\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Automating Docker Builds for a Monorepo with Multiple Microservices with GitHub Actions: A Step-by-Step Guide\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/beon.tech\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/beon.tech\\\/blog\\\/\",\"name\":\"Software &amp; Tech Hiring Insights | BEON.tech Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/beon.tech\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/beon.tech\\\/blog\\\/#\\\/schema\\\/person\\\/0e4d4e9639237b3b68f319e92475a6fb\",\"name\":\"Julio Lugo\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/beon.tech\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/09\\\/1733507784249-500x500-2-96x96.jpeg\",\"url\":\"https:\\\/\\\/beon.tech\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/09\\\/1733507784249-500x500-2-96x96.jpeg\",\"contentUrl\":\"https:\\\/\\\/beon.tech\\\/blog\\\/wp-content\\\/uploads\\\/2025\\\/09\\\/1733507784249-500x500-2-96x96.jpeg\",\"caption\":\"Julio Lugo\"},\"description\":\"Julio Lugo is a Software Engineer at BEON.tech, AWS Certified Solutions Architect, and a Georgia Tech OMSCS student. He specializes in frontend architecture and performance optimization, having led key initiatives to modernize build pipelines and improve application speed and reliability.\",\"url\":\"https:\\\/\\\/beon.tech\\\/blog\\\/author\\\/julio-lugo\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Automating Docker Builds in a Monorepo with GitHub Actions | BEON.tech Blog","description":"Learn how to automate Docker builds for multiple microservices in a monorepo using GitHub Actions. Detect changes, build only what\u2019s needed, and trigger deployments with ArgoCD.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/beon.tech\/blog\/automating-docker-builds-monorepo-github-actions\/","og_locale":"en_US","og_type":"article","og_title":"Automating Docker Builds in a Monorepo with GitHub Actions | BEON.tech Blog","og_description":"Learn how to automate Docker builds for multiple microservices in a monorepo using GitHub Actions. Detect changes, build only what\u2019s needed, and trigger deployments with ArgoCD.","og_url":"https:\/\/beon.tech\/blog\/automating-docker-builds-monorepo-github-actions\/","og_site_name":"Software &amp; Tech Hiring Insights | BEON.tech Blog","article_published_time":"2025-07-07T18:25:29+00:00","article_modified_time":"2026-04-06T13:16:59+00:00","og_image":[{"width":1200,"height":904,"url":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/Software-Developer-at-Work.png","type":"image\/png"}],"author":"Julio Lugo","twitter_card":"summary_large_image","twitter_creator":"@beontechok","twitter_site":"@beontechok","twitter_misc":{"Written by":"Julio Lugo","Est. reading time":"3 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/#article","isPartOf":{"@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/"},"author":{"name":"Julio Lugo","@id":"https:\/\/beon.tech\/blog\/#\/schema\/person\/0e4d4e9639237b3b68f319e92475a6fb"},"headline":"Automating Docker Builds for a Monorepo with Multiple Microservices with GitHub Actions: A Step-by-Step Guide","datePublished":"2025-07-07T18:25:29+00:00","dateModified":"2026-04-06T13:16:59+00:00","mainEntityOfPage":{"@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/"},"wordCount":614,"image":{"@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/#primaryimage"},"thumbnailUrl":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/Software-Developer-at-Work.png","keywords":["AI for Software Engineering","Coding","Docker"],"articleSection":["Technical Engineering"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/","url":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/","name":"Automating Docker Builds in a Monorepo with GitHub Actions | BEON.tech Blog","isPartOf":{"@id":"https:\/\/beon.tech\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/#primaryimage"},"image":{"@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/#primaryimage"},"thumbnailUrl":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/Software-Developer-at-Work.png","datePublished":"2025-07-07T18:25:29+00:00","dateModified":"2026-04-06T13:16:59+00:00","author":{"@id":"https:\/\/beon.tech\/blog\/#\/schema\/person\/0e4d4e9639237b3b68f319e92475a6fb"},"description":"Learn how to automate Docker builds for multiple microservices in a monorepo using GitHub Actions. Detect changes, build only what\u2019s needed, and trigger deployments with ArgoCD.","breadcrumb":{"@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/#primaryimage","url":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/Software-Developer-at-Work.png","contentUrl":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/Software-Developer-at-Work.png","width":1200,"height":904,"caption":"Man coding at a desk with three monitors in a purple-lit room, focused on programming tasks."},{"@type":"BreadcrumbList","@id":"https:\/\/beontech.wpengine.com\/automating-docker-builds-monorepo-github-actions\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/beon.tech\/blog\/"},{"@type":"ListItem","position":2,"name":"Automating Docker Builds for a Monorepo with Multiple Microservices with GitHub Actions: A Step-by-Step Guide"}]},{"@type":"WebSite","@id":"https:\/\/beon.tech\/blog\/#website","url":"https:\/\/beon.tech\/blog\/","name":"Software &amp; Tech Hiring Insights | BEON.tech Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/beon.tech\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/beon.tech\/blog\/#\/schema\/person\/0e4d4e9639237b3b68f319e92475a6fb","name":"Julio Lugo","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/09\/1733507784249-500x500-2-96x96.jpeg","url":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/09\/1733507784249-500x500-2-96x96.jpeg","contentUrl":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/09\/1733507784249-500x500-2-96x96.jpeg","caption":"Julio Lugo"},"description":"Julio Lugo is a Software Engineer at BEON.tech, AWS Certified Solutions Architect, and a Georgia Tech OMSCS student. He specializes in frontend architecture and performance optimization, having led key initiatives to modernize build pipelines and improve application speed and reliability.","url":"https:\/\/beon.tech\/blog\/author\/julio-lugo\/"}]}},"featured_image_src":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/Software-Developer-at-Work-600x400.png","featured_image_src_square":"https:\/\/beon.tech\/blog\/wp-content\/uploads\/2025\/07\/Software-Developer-at-Work-600x600.png","author_info":{"display_name":"Julio Lugo","author_link":"https:\/\/beon.tech\/blog\/author\/julio-lugo\/"},"_links":{"self":[{"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/posts\/3869","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/users\/47"}],"replies":[{"embeddable":true,"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/comments?post=3869"}],"version-history":[{"count":0,"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/posts\/3869\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/media\/3871"}],"wp:attachment":[{"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/media?parent=3869"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/categories?post=3869"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/beon.tech\/blog\/wp-json\/wp\/v2\/tags?post=3869"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}