{"id":2936,"date":"2024-08-24T14:28:49","date_gmt":"2024-08-24T13:28:49","guid":{"rendered":"https:\/\/contentlabstudy.com\/soft\/?p=2936"},"modified":"2026-09-24T21:15:55","modified_gmt":"2026-09-24T20:15:55","slug":"software-deployment","status":"publish","type":"post","link":"https:\/\/contentlabstudy.com\/soft\/software-deployment\/","title":{"rendered":"Software Deployment"},"content":{"rendered":"<p><strong>Software deployment<\/strong> is moving a specific build into an environment and making it the thing that serves traffic. If you cannot say which git SHA is in production, you do not have a deployment process \u2014 you have hope. The mechanics (IIS, containers, Functions) come after the loop: build once, promote the same artifact, verify, roll forward or back.<\/p>\n<h2>Build once, promote<\/h2>\n<p>Compile\/package in CI. The artifact that passed tests is what staging and production run. Rebuilding on the server (\u201cpull main and compile\u201d) is how \u201cworks on my machine\u201d becomes \u201cworks on Tuesday\u2019s compiler.\u201d<\/p>\n<h2>Environments<\/h2>\n<p>Dev \/ test \/ staging \/ prod differ by <em>config and data<\/em>, not by a different branch of code. Secrets stay out of the artifact (env, a vault). Connection strings in the repo are an incident.<\/p>\n<h2>Cutover<\/h2>\n<ul>\n<li><strong>Recreate:<\/strong> stop, replace, start. Simple. Downtime.<\/li>\n<li><strong>Rolling \/ blue-green:<\/strong> new instances, health check, shift traffic. Need two slots and compatible schema.<\/li>\n<li><strong>Canary:<\/strong> a fraction of traffic. Needs metrics you trust. See <a href=\"\/soft\/software-metrics-monitoring\/\">metrics<\/a>.<\/li>\n<\/ul>\n<h2>Example<\/h2>\n<p>Expand, then contract. The old binary ignores the new nullable column. A later release backfills and drops the old column.<\/p>\n<pre><code>ALTER TABLE orders ADD COLUMN status text NULL;\n-- old binary ignores status\n-- later: backfill, then drop the old column<\/code><\/pre>\n<h2>What breaks it<\/h2>\n<p>The same release drops a column the running binary still reads. The new pods crash, and the old pods would have too if you rolled back.<\/p>\n<pre><code>ALTER TABLE orders DROP COLUMN legacy_status;\n-- this release still has a binary that reads legacy_status<\/code><\/pre>\n<h2>Pitfalls<\/h2>\n<ul>\n<li>Schema change that is not backward compatible with the currently running binary (expand\/migrate\/contract).<\/li>\n<li>No health endpoint, so the load balancer loves your crashing process.<\/li>\n<li>Deploying from a laptop as the only path.<\/li>\n<\/ul>\n<p>Principles: <a href=\"\/soft\/deployment-principles\/\">Deployment Principles<\/a>. Azure: <a href=\"\/soft\/implementing-azure-pipelines\/\">Azure Pipelines<\/a>. Kubernetes: <a href=\"\/soft\/kubernetes-deployment\/\">Kubernetes Deployment<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Software deployment is moving a specific build into an environment and making it the thing that serves traffic. If you [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","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":"","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":[13],"tags":[],"class_list":["post-2936","post","type-post","status-publish","format-standard","hentry","category-software-deployment"],"_links":{"self":[{"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/posts\/2936","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/comments?post=2936"}],"version-history":[{"count":4,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/posts\/2936\/revisions"}],"predecessor-version":[{"id":3236,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/posts\/2936\/revisions\/3236"}],"wp:attachment":[{"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/media?parent=2936"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/categories?post=2936"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/contentlabstudy.com\/soft\/wp-json\/wp\/v2\/tags?post=2936"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}