{"id":73456,"date":"2023-08-02T05:31:17","date_gmt":"2023-08-02T12:31:17","guid":{"rendered":"https:\/\/github.blog\/?p=73456"},"modified":"2023-08-02T05:31:17","modified_gmt":"2023-08-02T12:31:17","slug":"how-we-build-containerized-services-at-github-using-github","status":"publish","type":"post","link":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/","title":{"rendered":"How we build containerized services at GitHub using GitHub"},"content":{"rendered":"<p>The developer experience engineering team at GitHub works on creating safe, delightful, and inclusive solutions for GitHub engineers to efficiently code, ship, and operate software\u2013setting an example for the world on how to build software with GitHub. To achieve this we provide our developers with a paved path\u2013a comprehensive suite of automated tools and applications to streamline our runtime platforms, deployment, and hosting that helps power some of the microservices on the GitHub.com platform and many internal tools. Let\u2019s take a deeper look at how one of our main paved paths works.<\/p>\n<h2 id=\"our-development-ecosystem\"><a class=\"heading-link\" href=\"#our-development-ecosystem\">Our development ecosystem<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>GitHub\u2019s main paved path covers everything that\u2019s needed for running software\u2013creating, deploying, scaling, debugging, and running applications. It is an ecosystem of tools like Kubernetes, Docker, load balancers, and many custom apps that work together to create a cohesive experience for our engineers. It isn\u2019t just infrastructure and isn\u2019t just Kubernetes. Kubernetes is our base layer, and the paved path is a mix of conventions, tools, and settings built on top of it.<\/p>\n<p>The kind of services that we typically run using the paved path include web apps, computation pipelines, batch processors, and monitoring systems.<\/p>\n<p>Kubernetes, which is the base layer of the paved path, runs in a multi-cluster, multi-region topology.<\/p>\n<h2 id=\"benefits-of-the-paved-path\"><a class=\"heading-link\" href=\"#benefits-of-the-paved-path\">Benefits of the paved path<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>There are hundreds of services at GitHub\u2013from a small internal tool to an external API supporting production workloads. For a variety of reasons, it would be inefficient to spin up virtual machines for each service.<\/p>\n<ul>\n<li>Planning and capacity usage across all services wouldn\u2019t be efficient. We would encounter significant overhead in managing both physical and Kubernetes infrastructure on an ongoing basis. <\/li>\n<li>Teams would need to build deep expertise in managing their own Kubernetes clusters and would have less time to focus on their application\u2019s unique needs.<\/li>\n<li>We would have less central visibility of applications.<\/li>\n<li>Security and compliance would be difficult to standardize and enforce.<\/li>\n<\/ul>\n<p>With the paved path based on Kubernetes and other runtime apps, we\u2019re instead able to:<\/p>\n<ul>\n<li>Plan capacity centrally and only for the Kubernetes nodes, so we can optimally use capacity across nodes, as small workloads and large workloads coexist on the same machines.  <\/li>\n<li>Scale rapidly thanks to central capacity planning.<\/li>\n<li>Easily manage configuration and deployments across services in one central control plane.<\/li>\n<li>Consistently provide insights into app and deployment performance for individual services.<\/li>\n<\/ul>\n<h2 id=\"onboarding-a-service\"><a class=\"heading-link\" href=\"#onboarding-a-service\">Onboarding a service<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>Onboarding a service with the code living in its own repository has been made easy with our ChatOps command service, called <a href=\"https:\/\/hubot.github.com\/\">Hubot<\/a>, and GitHub Apps. Service owners can easily generate some basic scaffolding needed to deploy the service by running a command like:<\/p>\n<pre><code>hubot gh-platform app scaffold monalisa-app\n<\/code><\/pre>\n<p>A custom GitHub App installed on the service\u2019s GitHub repository will then automatically generate a pull request to add the necessary configurations, which includes:<\/p>\n<ul>\n<li>A <code>deployment.yaml<\/code> file that defines the service\u2019s deployment environments. <\/li>\n<li>Kubernetes manifests that define <code>Deployment<\/code> and <code>Service<\/code> objects for deploying the service.<\/li>\n<li>A Debian Dockerfile that runs a trivial web server to start off with, which will be used by the Kubernetes manifests.<\/li>\n<li>Setting up CI builds as GitHub Checks that build the Docker images on every push, and store in a container registry ready for deployment.<\/li>\n<\/ul>\n<p>Each service that is onboarded to the paved path has its unique Kubernetes namespace that is defined by <code>&lt;app-name&gt;-&lt;environment&gt;<\/code> and generally has a staging and production environment. This helps separate the workloads of multiple services, and also multiple environments for the same service since each environment gets its own Kubernetes namespace.<\/p>\n<h2 id=\"deploying-a-service\"><a class=\"heading-link\" href=\"#deploying-a-service\">Deploying a service<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>At GitHub, we deploy branches and perform deployments through Hubot ChatOps commands. To deploy a branch named <code>bug-fixes<\/code> in the <code>monalisa-app<\/code> repository to the <code>staging<\/code> environment, a developer would run a ChatOps command like:<\/p>\n<pre><code>hubot deploy monalisa-app\/bug-fixes to staging\n<\/code><\/pre>\n<p>This triggers a deployment that fetches the Docker image associated with the latest commit in the <code>bug-fixes<\/code> branch, updates the Kubernetes manifests, and applies those manifests to the clusters in the runtime platform relevant to that environment.<\/p>\n<p>Typically, the Docker image would be deployed to multiple Kubernetes clusters across multiple geographical sites in a region that forms a part of the runtime platform.<\/p>\n<p>To automate pull request merges into the busiest branches and orchestrate the rollout across environments we\u2019re also using <a href=\"https:\/\/github.blog\/2023-07-12-github-merge-queue-is-generally-available\/\">merge queue and deployment pipelines<\/a>, which our engineers can observe and interact with during their deployment.<\/p>\n<h2 id=\"securing-our-services\"><a class=\"heading-link\" href=\"#securing-our-services\">Securing our services<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>For any company, the security of the platform itself, along with services running within it, is critical. In addition to our engineering-wide practices, such as requiring two-person reviews on every pull request, we also have Security and Platform teams automating security measures, such as:<\/p>\n<ul>\n<li>Pre-built Docker images to be used as base images for the Dockerfiles. These base images contain only the necessary packages\/dependencies with security updates, a set of installed software that is auditable and curated according to shared needs.<\/li>\n<li>Build-time and periodic scanning of all packages and running container images, for any vulnerabilities or dependencies needing a patch, powered by our own products for <a href=\"https:\/\/github.com\/features\/security\/software-supply-chain\">software supply chain security<\/a> like Dependabot.<\/li>\n<li>Build time and periodic scanning of GitHub repositories of services for exposed secrets and vulnerabilities, using GitHub\u2019s native security features for advanced security like <a href=\"https:\/\/github.com\/features\/security\/code\">code scanning and secret scanning<\/a>.<\/li>\n<li>Multiple authentication and authorization mechanisms that allow only the relevant individuals to directly access underlying Kubernetes resources.<\/li>\n<li>Comprehensive telemetry for threat detection.<\/li>\n<li>Services running in the platform are by default accessible only within GitHub\u2019s internal networks and not exposed on the public internet.<\/li>\n<li>Branch protection policies are enforced on all production repositories. These policies prevent merging a pull request until designated automated tests pass and the change has been reviewed by a different developer from the one who proposed the change. <\/li>\n<\/ul>\n<p>Another key aspect of security for an application is how secrets like keys and tokens are managed. At GitHub, we use a centralized secret store to manage secrets. Each service and each environment within the service has its own vault to store secrets. These secrets are then injected into the relevant pods in Kubernetes, which are then exposed to the containers.<\/p>\n<h2 id=\"the-deployment-flow-from-merge-to-rollout\"><a class=\"heading-link\" href=\"#the-deployment-flow-from-merge-to-rollout\">The deployment flow, from merge to rollout<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>The whole deployment process would look something like this:<\/p>\n<p><img data-recalc-dims=\"1\" decoding=\"async\" loading=\"lazy\" src=\"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/containerized-services-the-whole-flow-2.png?w=1024&#038;resize=1024%2C620\" alt=\"\" width=\"1024\" height=\"620\" class=\"aligncenter size-large wp-image-73467 width-fit\" srcset=\"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/containerized-services-the-whole-flow-2.png?w=2676 2676w, https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/containerized-services-the-whole-flow-2.png?w=300 300w, https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/containerized-services-the-whole-flow-2.png?w=768 768w, https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/containerized-services-the-whole-flow-2.png?w=1024 1024w, https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/containerized-services-the-whole-flow-2.png?w=1536 1536w, https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/containerized-services-the-whole-flow-2.png?w=2048 2048w\" sizes=\"auto, (max-width: 1000px) 100vw, 1000px\" \/><\/p>\n<ol>\n<li>A GitHub engineer merges a pull request to a branch in a repository. In the above example, it is the <code>bug-fixes<\/code> branch in the <code>monalisa-app<\/code> repository. This repository would also contain the Kubernetes manifest template files for deploying the application.<\/li>\n<li>The pull request merge triggers relevant CI workflows. One of them is a build of the Docker image, which builds the container image based on the Dockerfile specified in the repository, and pushes the image to an internal artifact registry.<\/li>\n<li>Once all the CI workflows have completed successfully, the engineer initiates a deployment by running a ChatOps command like <code>hubot deploy monalisa-app\/bug-fixes to staging<\/code>. This triggers a deployment to our environments such as <code>Staging<\/code>.<\/li>\n<li>The build systems fetch the Kubernetes manifest files from the repository branch, replaces the latest image to be deployed from the artifact registry, injects app secrets from the secret store, and runs some custom operations. At the end of this stage, a ready-to-deploy Kubernetes manifest is available.<\/li>\n<li>Our deployment systems then apply the Kubernetes manifest to relevant clusters and monitor the rollout status of new changes.<\/li>\n<\/ol>\n<h2 id=\"conclusion\"><a class=\"heading-link\" href=\"#conclusion\">Conclusion<span class=\"heading-hash pl-2 text-italic text-bold\" aria-hidden=\"true\"><\/span><\/a><\/h2>\n<p>GitHub\u2019s internal paved path helps developers at GitHub focus on building services and delivering value to our users, with minimal focus on the infrastructure. We accomplish this by providing a streamlined path to our GitHub engineers that uses the power of containers and Kubernetes; scalable security, authentication, and authorization mechanisms; and the GitHub.com platform itself.<\/p>\n<p>Want to try some of these for yourself? Learn more about all of GitHub\u2019s features on <a href=\"https:\/\/github.com\/features\">github.com\/features<\/a>. If you have adopted any of our practices for your own development, give us a shout on <a href=\"https:\/\/twitter.com\/github\">Twitter<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn about how we build containerized services that power microservices on the GitHub.com platform and many internal tools.<\/p>\n","protected":false},"author":1830,"featured_media":73458,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_gh_post_show_toc":"no","_gh_post_is_no_robots":"no","_gh_post_is_featured":"no","_gh_post_is_excluded":"no","_gh_post_is_unlisted":"no","_gh_post_related_link_1":"","_gh_post_related_link_2":"","_gh_post_related_link_3":"","_gh_post_sq_img":"https:\/\/github.blog\/wp-content\/uploads\/2022\/01\/GitHub-Engineering_teal-square-icon.png","_gh_post_sq_img_id":"62572","_gh_post_cta_title":"","_gh_post_cta_text":"","_gh_post_cta_link":"","_gh_post_cta_button":"Click Here to Learn More","_gh_post_recirc_hide":"no","_gh_post_recirc_col_1":"gh-auto-select","_gh_post_recirc_col_2":"65301","_gh_post_recirc_col_3":"65308","_gh_post_recirc_col_4":"65316","_featured_video":"","_gh_post_additional_query_params":"","_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"_wpas_customize_per_network":false,"_links_to":"","_links_to_target":""},"categories":[3307,72],"tags":[3113,2930,2944],"coauthors":[2091,3112],"class_list":["post-73456","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-architecture-optimization","category-engineering","tag-chatops","tag-developer-experience","tag-how-github-builds-github"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>How we build containerized services at GitHub using GitHub - The GitHub Blog<\/title>\n<meta name=\"description\" content=\"Learn about how we build containerized services that power microservices on the GitHub.com platform and many internal tools.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How we build containerized services at GitHub using GitHub\" \/>\n<meta property=\"og:description\" content=\"Learn about how we build containerized services that power microservices on the GitHub.com platform and many internal tools.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/\" \/>\n<meta property=\"og:site_name\" content=\"The GitHub Blog\" \/>\n<meta property=\"article:published_time\" content=\"2023-08-02T12:31:17+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"850\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"MV Karan, Catherine Weilaender\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"MV Karan, Catherine Weilaender\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/\"},\"author\":{\"name\":\"MV Karan\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/4de0fba2753c8a269027d4959ab2161f\"},\"headline\":\"How we build containerized services at GitHub using GitHub\",\"datePublished\":\"2023-08-02T12:31:17+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/\"},\"wordCount\":1299,\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2023\\\/08\\\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850\",\"keywords\":[\"ChatOps\",\"developer experience\",\"How GitHub builds GitHub\"],\"articleSection\":[\"Architecture &amp; optimization\",\"Engineering\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/\",\"url\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/\",\"name\":\"How we build containerized services at GitHub using GitHub - The GitHub Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2023\\\/08\\\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850\",\"datePublished\":\"2023-08-02T12:31:17+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/4de0fba2753c8a269027d4959ab2161f\"},\"description\":\"Learn about how we build containerized services that power microservices on the GitHub.com platform and many internal tools.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/#primaryimage\",\"url\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2023\\\/08\\\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850\",\"contentUrl\":\"https:\\\/\\\/github.blog\\\/wp-content\\\/uploads\\\/2023\\\/08\\\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850\",\"width\":1600,\"height\":850},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/how-we-build-containerized-services-at-github-using-github\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/github.blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Engineering\",\"item\":\"https:\\\/\\\/github.blog\\\/engineering\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Architecture &amp; optimization\",\"item\":\"https:\\\/\\\/github.blog\\\/engineering\\\/architecture-optimization\\\/\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"How we build containerized services at GitHub using GitHub\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/github.blog\\\/#website\",\"url\":\"https:\\\/\\\/github.blog\\\/\",\"name\":\"The GitHub Blog\",\"description\":\"Updates, ideas, and inspiration from GitHub to help developers build and design software.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/github.blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/github.blog\\\/#\\\/schema\\\/person\\\/4de0fba2753c8a269027d4959ab2161f\",\"name\":\"MV Karan\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/003cc53e57153cee2bef95e41f19d541f1916319c6162292479a0dda862a59e5?s=96&d=mm&r=g8c806c89de27e29967d7b7606396a5ba\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/003cc53e57153cee2bef95e41f19d541f1916319c6162292479a0dda862a59e5?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/003cc53e57153cee2bef95e41f19d541f1916319c6162292479a0dda862a59e5?s=96&d=mm&r=g\",\"caption\":\"MV Karan\"},\"url\":\"https:\\\/\\\/github.blog\\\/author\\\/mvkaran\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"How we build containerized services at GitHub using GitHub - The GitHub Blog","description":"Learn about how we build containerized services that power microservices on the GitHub.com platform and many internal tools.","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:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/","og_locale":"en_US","og_type":"article","og_title":"How we build containerized services at GitHub using GitHub","og_description":"Learn about how we build containerized services that power microservices on the GitHub.com platform and many internal tools.","og_url":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/","og_site_name":"The GitHub Blog","article_published_time":"2023-08-02T12:31:17+00:00","og_image":[{"width":1600,"height":850,"url":"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850","type":"image\/png"}],"author":"MV Karan, Catherine Weilaender","twitter_card":"summary_large_image","twitter_misc":{"Written by":"MV Karan, Catherine Weilaender","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/#article","isPartOf":{"@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/"},"author":{"name":"MV Karan","@id":"https:\/\/github.blog\/#\/schema\/person\/4de0fba2753c8a269027d4959ab2161f"},"headline":"How we build containerized services at GitHub using GitHub","datePublished":"2023-08-02T12:31:17+00:00","mainEntityOfPage":{"@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/"},"wordCount":1299,"image":{"@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/#primaryimage"},"thumbnailUrl":"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850","keywords":["ChatOps","developer experience","How GitHub builds GitHub"],"articleSection":["Architecture &amp; optimization","Engineering"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/","url":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/","name":"How we build containerized services at GitHub using GitHub - The GitHub Blog","isPartOf":{"@id":"https:\/\/github.blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/#primaryimage"},"image":{"@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/#primaryimage"},"thumbnailUrl":"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850","datePublished":"2023-08-02T12:31:17+00:00","author":{"@id":"https:\/\/github.blog\/#\/schema\/person\/4de0fba2753c8a269027d4959ab2161f"},"description":"Learn about how we build containerized services that power microservices on the GitHub.com platform and many internal tools.","breadcrumb":{"@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/#primaryimage","url":"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850","contentUrl":"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850","width":1600,"height":850},{"@type":"BreadcrumbList","@id":"https:\/\/github.blog\/engineering\/architecture-optimization\/how-we-build-containerized-services-at-github-using-github\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/github.blog\/"},{"@type":"ListItem","position":2,"name":"Engineering","item":"https:\/\/github.blog\/engineering\/"},{"@type":"ListItem","position":3,"name":"Architecture &amp; optimization","item":"https:\/\/github.blog\/engineering\/architecture-optimization\/"},{"@type":"ListItem","position":4,"name":"How we build containerized services at GitHub using GitHub"}]},{"@type":"WebSite","@id":"https:\/\/github.blog\/#website","url":"https:\/\/github.blog\/","name":"The GitHub Blog","description":"Updates, ideas, and inspiration from GitHub to help developers build and design software.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/github.blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/github.blog\/#\/schema\/person\/4de0fba2753c8a269027d4959ab2161f","name":"MV Karan","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/003cc53e57153cee2bef95e41f19d541f1916319c6162292479a0dda862a59e5?s=96&d=mm&r=g8c806c89de27e29967d7b7606396a5ba","url":"https:\/\/secure.gravatar.com\/avatar\/003cc53e57153cee2bef95e41f19d541f1916319c6162292479a0dda862a59e5?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/003cc53e57153cee2bef95e41f19d541f1916319c6162292479a0dda862a59e5?s=96&d=mm&r=g","caption":"MV Karan"},"url":"https:\/\/github.blog\/author\/mvkaran\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/github.blog\/wp-content\/uploads\/2023\/08\/254174591-2e8600c8-d130-4516-b309-baeb57358498.png?fit=1600%2C850","jetpack_shortlink":"https:\/\/wp.me\/pamS32-j6M","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/73456","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/users\/1830"}],"replies":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/comments?post=73456"}],"version-history":[{"count":7,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/73456\/revisions"}],"predecessor-version":[{"id":73460,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/posts\/73456\/revisions\/73460"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media\/73458"}],"wp:attachment":[{"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/media?parent=73456"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/categories?post=73456"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/tags?post=73456"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/github.blog\/wp-json\/wp\/v2\/coauthors?post=73456"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}