Answers: <p>As promised, here is a solution using haproxy with sticky cookies. Note, that this approach requires support on the application side (as only your application layer may know once transactions are completed).</p>
  
  <p>To achieve this, first - start with haproxy configuration of the following kind: </p>
  
  <pre><code>    global
          daemon
          maxconn 256
      defaults
          mode http
          timeout connect 5000ms
          timeout client 50000ms
          timeout server 50000ms
  
      frontend http-in
          bind *:80
          default_backend servers
  
      backend servers
          balance roundrobin
          cookie SID insert indirect preserve
          server server1 blue-server-hostname:8000 cookie sblue
  </code></pre>
  
  <p>Note that this configuration is pretty generic and taken from haproxy documentation - from here: <a href="https://cbonte.github.io/haproxy-dconv/2.2/configuration.html#2.5" rel="nofollow noreferrer">https://cbonte.github.io/haproxy-dconv/2.2/configuration.html#2.5</a></p>
  
  <p>The part that is used to achieve stickiness is cookie instruction that is added in the end, detailed documentation here: <a href="https://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-cookie" rel="nofollow noreferrer">https://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-cookie</a></p>
  
  <p>So, with this line:</p>
  
  <pre><code>cookie SID insert indirect preserve
  </code></pre>
  
  <p>we tell haproxy to insert cookie called <strong>SID</strong> which may only have value <strong>sblue</strong> for now (this value is defined in last line of configuration). And we also say that if this cookie is supplied by the back-end server, we don't want haproxy to overwrite it (achieved by <strong>insert</strong> and <strong>preserve</strong> keywords).</p>
  
  <p>The next part is to add some application level logic to set <strong>SID</strong> cookie to client and make its value configurable on the application side. You want to set <strong>SID</strong> cookie to <strong>sblue</strong> for your old code and to <strong>sgreen</strong> for your new code.</p>
  
  <p>Now, when you do deployment, at first you have only blue instance, all your <strong>SID</strong> cookies are set to <strong>sblue</strong> and haproxy directs all your traffic to the only blue instance.</p>
  
  <p>Next, you add your green instance, and after that you add it to haproxy by adding the following line to the end of configuration above:</p>
  
  <pre><code>server server2 green-server-hostname:8000 cookie sgreen
  </code></pre>
  
  <p>Now any request which gets to your new green instance would have its cookie set to sgreen and would stick to the new instance.</p>
  
  <p>Finally, you want to engage your application-level configuration on the old blue instance to set cookie to <strong>sgreen</strong> to clients once their transaction is over (basically, at the point where application knows it's safe to do so). Then any new requests from such clients would be directed to green instance. At some point all your requests would be transitioned to green - and you can detach blue instance at that point.</p>
  
  <p>This kind of approach (or its variations) would be the most graceful and controlled by your application-layer transaction logic.</p>
  
Answers: CC BY-SA 4.0
Answers: 2024-05-27T21:17:16.760Z
Answers: Do you perhaps know how to answer this question as well? Here:  https://devops.stackexchange.com/questions/19340/green-blue-deployments-with-multiple-development-teams
Answers: CodeMonkey
Answers: CC BY-SA 4.0
Answers: 2020-04-05T02:15:21.487Z
Answers: 2020-04-05T02:15:21.487Z
Answers: taleodor
Answers: <p>As per Martin Flowers' <a href="https://martinfowler.com/bliki/BlueGreenDeployment.html" rel="nofollow noreferrer">definition</a> of Blue-Green deployment</p>
  
  <blockquote>
    <p>The blue-green deployment approach does this by ensuring you have two production environments, as identical as possible. At any time one of them, let's say blue for the example, is live. As you prepare a new release of your software you do your final stage of testing in the green environment. Once the software is working in the green environment, you switch the router so that all incoming requests go to the green environment - the blue one is now idle.</p>
  </blockquote>
  
  <h1>Steps</h1>
  
  <p>You've said that DBs are synced using <code>master-slave</code> topology.
  So, to switch traffic from one instance to another, we have to make  steps:</p>
  
  <ul>
  <li>Switch web-traffic from <code>APP v1</code> to <code>APP v2</code></li>
  <li>Shutdown deprecated <code>DB Blue</code></li>
  <li>Promote <code>DB Green</code> to <code>master</code> mode</li>
  <li>Start new <code>DB Blue v2</code> in <code>slave</code> mode
  (you may ask - why shutdown <code>DB Blue</code> instead of using <code>master-master</code> replication or other ways to sync <code>DB Blue v1</code> with <code>DB Green</code> in <code>master</code> mode. See explanation in <code>DB replication</code>)</li>
  </ul>
  
  <h2>Graceful switch web-traffic</h2>
  
  <p>To switch web-traffic from <code>APP v1</code> <code>APP v2</code> - just use <code>nginx reload</code> - it will graceful end all working connection and move traffic from <code>App v1</code> to <code>App v2</code>
  There are many scripting solutions for switch <code>blue/green</code> using shell/python scripts</p>
  
  <p>E.g.:</p>
  
  <ul>
  <li><p><a href="https://github.com/meappy/docker-nginx-blue-green" rel="nofollow noreferrer">meappy/docker-nginx-blue-green</a>: Docker blue green upstreams for nginx with ngx_http_perl_module</p></li>
  <li><p><a href="https://dan.bravender.net/2014/8/24/Simple_0-Downtime_Blue_Green_Deployments.html" rel="nofollow noreferrer">Simple 0-Downtime Blue Green Deployments</a>: Python simple 0-Downtime Blue Green Deployments example</p></li>
  </ul>
  
  <p>The logic is simple: add <code>green</code> upstream in <code>nginx</code> config, use it as default and send <code>reload</code> to <code>nginx</code>:</p>
  
  <p>Sample <code>nginx.conf</code> for <code>reverse proxy</code>/<code>load balancer</code></p>
  
  <pre><code>http {
  
  upstream appv1 {
      zone appv1 64K;
      server 10.10.0.1:80;
  }
  
  upstream appv2 {
      zone appv2 64K;
      server 10.10.0.3:80;
  }
  
  server {
  ...
  location / {
      proxy_pass http://$appv1;
  }
  }
  
  }
  </code></pre>
  
  <p>Replace <code>proxy_pass http://$appv1;</code> with <code>proxy_pass http://$appvv;</code></p>
  
  <p>And then</p>
  
  <pre><code>nginx -s reload
  </code></pre>
  
  <h2>Stop <code>DB Blue</code></h2>
  
  <p><code>systemctl stop postgresql</code></p>
  
  <h2>Promote <code>DB Green</code> to <code>master</code> mode</h2>
  
  <ul>
  <li>Trigger the promotion using your defined trigger in <code>$PGDATA/recovery.conf</code></li>
  </ul>
  
  <pre><code>touch $PGDATA/failover
  </code></pre>
  
  <ul>
  <li>Remove <code>failover</code> trigger from <code>Green DB</code></li>
  </ul>
  
  <pre><code>cd $PRIMARY_DATA
  rm -f recovery.* failover  
  </code></pre>
  
  <ul>
  <li>Make sure that <code>hot stanby</code> mode is <code>on</code> on <code>Green DB</code> in <code>master</code> mode </li>
  </ul>
  
  <pre><code>cat postgresql.conf | grep '#hot_standby = on'
  </code></pre>
  
  <h1>DB replication</h1>
  
  <h2>Make a backup of master Green DB</h2>
  
  <pre><code>psql -c "SELECT pg_start_backup('Streaming Replication', true)" postgresql://postgres@GreenDB/postgres
  </code></pre>
  
  <h2>Send a backup to Blue DB</h2>
  
  <pre><code>rsync -a $PG_DATA_Green_DB/ $BlueDB_IP:$PG_DATA_Blue_DB/ --exclude postmaster.pid --exclude postmaster.opts 
  </code></pre>
  
  <h2>See also</h2>
  
  <ul>
  <li><a href="https://www.2ndquadrant.com/en/blog/evolution-of-fault-tolerance-in-postgresql/" rel="nofollow noreferrer">Evolution of Fault Tolerance in PostgreSQL</a></li>
  </ul>
  
  <h1>DB Migration (More complex but more robust database migration scheme)</h1>
  
  <p>You may use more complex scheme for migration using <code>Ansible</code> and `Pglupgrade tool:</p>
  
  <p><img src="https://www.2ndquadrant.com/wp-content/uploads/2018/04/Screen-Shot-2018-04-24-at-16.02.54.png" alt=""></p>
  
  <p>See for details: </p>
  
  <ul>
  <li><p><a href="https://www.2ndquadrant.com/blog/near-zero-downtime-automated-upgrades-postgresql-clusters-cloud/" rel="nofollow noreferrer">Near-Zero Downtime Automated Upgrades of PostgreSQL Clusters in Cloud (Part I)</a></p></li>
  <li><p><a href="https://www.2ndquadrant.com/en/blog/near-zero-downtime-automated-upgrades-postgresql-clusters-cloud-part-ii/" rel="nofollow noreferrer">Near-Zero Downtime Automated Upgrades of PostgreSQL Clusters in Cloud (Part II)</a></p></li>
  </ul>
  
  <h1>P.s some definitions.</h1>
  
  <p>Just to...</p>
  
  <blockquote>
    <p>... sort the buyers from the spyers, the needy from the greedy...</p>
  </blockquote>
  
  <p>And <code>blue/green deployment</code> vs <code>canary deployment</code> vs <code>A/B test</code></p>
  
  <h1>Definitions, kinds of deployments and tests</h1>
  
  <p>(see details in <a href="https://stackoverflow.com/questions/23746038/canary-release-strategy-vs-blue-green">these answers</a> )</p>
  
  <ul>
  <li><p><strong>Blue-Green Deployment</strong> - When deploying a new version of an application, a second environment is created. Once the new environment is tested, it takes over from the old version. The old environment can then be turned off.</p></li>
  <li><p><strong>A/B Testing</strong> - Two versions of an application are running at the same time. A portion of requests go to each. Developers can then compare the versions.  </p></li>
  <li><p><strong>Canary Release</strong> - A new version of a microservice is started along with the old versions. That new version can then take a portion of the requests and the team can test how this new version interacts with the overall system.</p></li>
  <li><p><strong>Feature flagging</strong> - The action of "configuring" (cold, or even hot) which functionality is (not)available for which (group) of users. If you also do something like "feature flagging" you can deploy first, measure soundness of your release in backwards compatibility/bug perspective, and release new functionality gradually to different users, or vice versa (scale down or even rollback functionality and/or binaries). Feature flagging allows for splitting availability of functionality from deployment of binaries, and gives much more fine-grained decision making then only "deploy/rollback"</p></li>
  </ul>
  
  <h1>P.P.S <code>Blue/Green</code> vs <code>Canary</code></h1>
  
  <p><a href="https://github.com/lerndevops/educka/blob/master/other/Canary-vs-Blue-Green-Deployments.md" rel="nofollow noreferrer">source</a></p>
  
  <ul>
  <li><p>Both blue-green and canary releases solve the same purpose</p></li>
  <li><p>Although both of these terms look quite close to each other, they have subtle differences. One put confidence in your functionality release and the other put confidence the way you release.</p></li>
  </ul>
  
  <h2>Blue-Green Deployment</h2>
  
  <blockquote>
    <p>When deploying a new version of an application, a second environment is created. Once the new environment is tested, it takes over from the old version. The old environment can then be turned off.</p>
  </blockquote>
  
  <p><code>1. It is more about the predictable release with zero downtime deployment.</code></p>
  
  <p><code>2. Easy rollbacks in case of failure.</code></p>
  
  <p><code>3. Completely automated deployment process</code></p>
  
  <p><code>4. In cloud environment where it is easier to script &amp; recreate infrastructure, blue/green deployment is preferred as it allows the infrastructure to be in sync with the automation</code></p>
  
  <h2>Canary Release</h2>
  
  <blockquote>
    <p>A new version of a microservice is started along with the old versions. That new version can then take a portion of the requests and the team can test how this new version interacts with the overall system.</p>
  </blockquote>
  
  <p><code>1. The canary release is a technique to reduce the risk of introducing a new software version in production by slowly rolling out the change to a small subset of users before rolling it out to the entire infrastructure.</code></p>
  
  <p><code>2. It is about to get an idea of how new version will perform (integrate with other apps, CPU, memory, disk usage, etc).</code></p>
  
  <p>See also illustration (<a href="https://stackoverflow.com/a/47397219/5720818">source</a>):</p>
  
  <p>Blue/Green: <a href="https://i.sstatic.net/RtQRg.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/RtQRg.png" alt="enter image description here"></a></p>
  
  <p>Canary: <a href="https://i.sstatic.net/bA9Xi.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/bA9Xi.png" alt="enter image description here"></a></p>
  
Answers: CC BY-SA 4.0
Answers: 2020-04-02T13:17:33.020Z
Answers: Good answer! However, the definitions of **A/B Testing** and **Canaray Release** are identical which is confusing.
Answers: UserControl
Answers: CC BY-SA 4.0
Answers: 2020-04-02T19:19:16.877Z
Answers: thx, added explanation
Answers: Yasen
Answers: CC BY-SA 4.0
Answers: 2020-04-03T13:14:23.240Z
Answers: This is a regular approach that I would use, but it misses this point in the question: "Forward the new traffic to green and wait for existing blue's environment's transactions complete." Instead what would happen under this sort of nginx switch - all requests would be forwarded to green at once, including any unfinished ones from blue.
Answers: taleodor
Answers: CC BY-SA 4.0
Answers: 2020-04-03T13:32:51.723Z
Answers: Yes, you are right - it's regular approach. As for this part of question: '... and wait for existing blue's environment's transactions complete' - `nginx -s reload` will switch traffic gracefully. Since there is `master-slave` replication, then no need to forward unfinished `blue` traffic to the `green` app. We just let 'em finish on the `blue` node.
Answers: Yasen
Answers: CC BY-SA 4.0
Answers: 2020-04-03T14:18:08.937Z
Answers: The question could be phrased better - so I agree it's not very clear what is meant, but I was initially understanding it as a multi-master approach. I'll post a sticky cookie solution a little later for that case. If it's a regular master-slave sync, your solution is fine most of the time.
Answers: taleodor
Answers: CC BY-SA 4.0
Answers: 2024-05-27T21:17:01.507Z
Answers: Do you perhaps know how to answer this question as well? Here:  https://devops.stackexchange.com/questions/19340/green-blue-deployments-with-multiple-development-teams
Answers: CodeMonkey
Answers: CC BY-SA 4.0
Answers: 2020-04-01T10:58:09.840Z
Answers: 2020-04-02T19:18:52.933Z
Answers: 2020-04-02T19:18:52.933Z
Answers: Yasen
Body: <p>Imagining I have 2 sets of environment(Blue and Green)</p>
  
  <pre><code>           +
             |
             |
             |
             v
     +-------+---------+
     |     Proxy/LB    |
     |                 |
     +--+-------------++
        |             |
  +-----++          +-+----+
  |      |          |      |
  |APP v1|          |APP v2|
  |Blue  |          |Green |
  +--+---+          +--+---+
     |                 |
  +--+---+          +--+---+
  | DB   |          | DB   |
  | Blue | DB Sync  | Green|
  |      &lt;----------&gt;      |
  +------+          +------+
  
  </code></pre>
  
  <p>The version Blue is currently running and green is deployed and all DB replication completed. Now I want switch traffic to green environment. In this case, what is the best way to manage the DB transactions?(I have one thought below)</p>
  
  <ul>
  <li>Forward the new traffic to green and wait for existing blue's environment's transactions complete. Once all are done, switch traffic completely to green(<strong>UPDATE: Can I achieve this with Nginx?</strong>)</li>
  </ul>
  
  <p>If above is true, I'd have to do little extra work to forward only new traffic to green.</p>
  
  <p>Or what is the best way of doing Blue Green deployment in this case?</p>
  
  <p><strong>PS:</strong></p>
  
  <ul>
  <li>We are using Nginx proxy</li>
  <li>All servers are bare metal, no cloud!</li>
  <li>2 standalone DB setups(Postgresql with master-slave) </li>
  </ul>
  
Comments: CC BY-SA 4.0
Comments: 2020-03-30T14:48:44.477Z
Comments: To route only new traffic you need sticky cookie logic which is only supported in nginx plus (paid). If you're looking for fully open sourced solution, you may add haproxy layer below. Let me know if this (how to route only new traffic to new deployment) is what you're asking about or there is more to your question. If this is all, let me know whether you go with Nginx plus or you need fully open-source solution and I can elaborate.
Comments: taleodor
Comments: CC BY-SA 4.0
Comments: 2020-04-03T10:26:40.637Z
Comments: @taleodor You can your answer. Haproxy would be great also.
Comments: veerendra2
Tags: <deployment><nginx><postgresql><bluegreen>
Title: Blue Green Deployment DB transactions management
UserDisplayName: veerendra2
ThreadText: # Blue Green Deployment DB transactions management
  
  (Asked by: username_0 on 2020-03-26)
  
  Imagining I have 2 sets of environment(Blue and Green)
  
  ```
             +
             |
             |
             |
             v
     +-------+---------+
     |     Proxy/LB    |
     |                 |
     +--+-------------++
        |             |
  +-----++          +-+----+
  |      |          |      |
  |APP v1|          |APP v2|
  |Blue  |          |Green |
  +--+---+          +--+---+
     |                 |
  +--+---+          +--+---+
  | DB   |          | DB   |
  | Blue | DB Sync  | Green|
  |      <---------->      |
  +------+          +------+
  
  ```
  
  The version Blue is currently running and green is deployed and all DB replication completed. Now I want switch traffic to green environment. In this case, what is the best way to manage the DB transactions?(I have one thought below)
  
  * Forward the new traffic to green and wait for existing blue's environment's transactions complete. Once all are done, switch traffic completely to green(**UPDATE: Can I achieve this with Nginx?**)
  
  If above is true, I'd have to do little extra work to forward only new traffic to green.
  
  Or what is the best way of doing Blue Green deployment in this case?
  
  **PS:**
  
  * We are using Nginx proxy
  * All servers are bare metal, no cloud!
  * 2 standalone DB setups(Postgresql with master-slave)
  
  **Tags:** deployment, nginx, postgresql, bluegreen
  
  > **Comments:**
  > **username_1**: To route only new traffic you need sticky cookie logic which is only supported in nginx plus (paid). If you're looking for fully open sourced solution, you may add haproxy layer below. Let me know if this (how to route only new traffic to new deployment) is what you're asking about or there is more to your question. If this is all, let me know whether you go with Nginx plus or you need fully open-source solution and I can elaborate.  
  > **username_0**: @username_1 You can your answer. Haproxy would be great also.  
  
  ---
  
  ## 2 answers
  
  ### Answer by username_3 on 2020-04-01. Score: 6 | Accepted answer
  
  As per Martin Flowers' [definition](https://martinfowler.com/bliki/BlueGreenDeployment.html) of Blue-Green deployment
  
  > The blue-green deployment approach does this by ensuring you have two production environments, as identical as possible. At any time one of them, let's say blue for the example, is live. As you prepare a new release of your software you do your final stage of testing in the green environment. Once the software is working in the green environment, you switch the router so that all incoming requests go to the green environment - the blue one is now idle.
  
  # Steps
  
  You've said that DBs are synced using `master-slave` topology.
  So, to switch traffic from one instance to another, we have to make steps:
  
  * Switch web-traffic from `APP v1` to `APP v2`
  * Shutdown deprecated `DB Blue`
  * Promote `DB Green` to `master` mode
  * Start new `DB Blue v2` in `slave` mode
    (you may ask - why shutdown `DB Blue` instead of using `master-master` replication or other ways to sync `DB Blue v1` with `DB Green` in `master` mode. See explanation in `DB replication`)
  
  ## Graceful switch web-traffic
  
  To switch web-traffic from `APP v1` `APP v2` - just use `nginx reload` - it will graceful end all working connection and move traffic from `App v1` to `App v2`
  There are many scripting solutions for switch `blue/green` using shell/python scripts
  
  E.g.:
  
  * [meappy/docker-nginx-blue-green](https://github.com/meappy/docker-nginx-blue-green): Docker blue green upstreams for nginx with ngx\_http\_perl\_module
  * [Simple 0-Downtime Blue Green Deployments](https://dan.bravender.net/2014/8/24/Simple_0-Downtime_Blue_Green_Deployments.html): Python simple 0-Downtime Blue Green Deployments example
  
  The logic is simple: add `green` upstream in `nginx` config, use it as default and send `reload` to `nginx`:
  
  Sample `nginx.conf` for `reverse proxy`/`load balancer`
  
  ```
  http {
  
  upstream appv1 {
      zone appv1 64K;
      server 10.10.0.1:80;
  }
  
  upstream appv2 {
      zone appv2 64K;
      server 10.10.0.3:80;
  }
  
  server {
  ...
  location / {
      proxy_pass http://$appv1;
  }
  }
  
  }
  
  ```
  
  Replace `proxy_pass http://$appv1;` with `proxy_pass http://$appvv;`
  
  And then
  
  ```
  nginx -s reload
  
  ```
  
  ## Stop `DB Blue`
  
  `systemctl stop postgresql`
  
  ## Promote `DB Green` to `master` mode
  
  * Trigger the promotion using your defined trigger in `$PGDATA/recovery.conf`
  
  ```
  touch $PGDATA/failover
  
  ```
  
  * Remove `failover` trigger from `Green DB`
  
  ```
  cd $PRIMARY_DATA
  rm -f recovery.* failover  
  
  ```
  
  * Make sure that `hot stanby` mode is `on` on `Green DB` in `master` mode
  
  ```
  cat postgresql.conf | grep '#hot_standby = on'
  
  ```
  
  # DB replication
  
  ## Make a backup of master Green DB
  
  ```
  psql -c "SELECT pg_start_backup('Streaming Replication', true)" postgresql://postgres@GreenDB/postgres
  
  ```
  
  ## Send a backup to Blue DB
  
  ```
  rsync -a $PG_DATA_Green_DB/ $BlueDB_IP:$PG_DATA_Blue_DB/ --exclude postmaster.pid --exclude postmaster.opts 
  
  ```
  
  ## See also
  
  * [Evolution of Fault Tolerance in PostgreSQL](https://www.2ndquadrant.com/en/blog/evolution-of-fault-tolerance-in-postgresql/)
  
  # DB Migration (More complex but more robust database migration scheme)
  
  You may use more complex scheme for migration using `Ansible` and `Pglupgrade tool:
  
  ![](https://www.2ndquadrant.com/wp-content/uploads/2018/04/Screen-Shot-2018-04-24-at-16.02.54.png)
  
  See for details:
  
  * [Near-Zero Downtime Automated Upgrades of PostgreSQL Clusters in Cloud (Part I)](https://www.2ndquadrant.com/blog/near-zero-downtime-automated-upgrades-postgresql-clusters-cloud/)
  * [Near-Zero Downtime Automated Upgrades of PostgreSQL Clusters in Cloud (Part II)](https://www.2ndquadrant.com/en/blog/near-zero-downtime-automated-upgrades-postgresql-clusters-cloud-part-ii/)
  
  # P.s some definitions.
  
  Just to...
  
  > ... sort the buyers from the spyers, the needy from the greedy...
  
  And `blue/green deployment` vs `canary deployment` vs `A/B test`
  
  # Definitions, kinds of deployments and tests
  
  (see details in [these answers](https://stackoverflow.com/questions/23746038/canary-release-strategy-vs-blue-green) )
  
  * **Blue-Green Deployment** - When deploying a new version of an application, a second environment is created. Once the new environment is tested, it takes over from the old version. The old environment can then be turned off.
  * **A/B Testing** - Two versions of an application are running at the same time. A portion of requests go to each. Developers can then compare the versions.
  * **Canary Release** - A new version of a microservice is started along with the old versions. That new version can then take a portion of the requests and the team can test how this new version interacts with the overall system.
  * **Feature flagging** - The action of "configuring" (cold, or even hot) which functionality is (not)available for which (group) of users. If you also do something like "feature flagging" you can deploy first, measure soundness of your release in backwards compatibility/bug perspective, and release new functionality gradually to different users, or vice versa (scale down or even rollback functionality and/or binaries). Feature flagging allows for splitting availability of functionality from deployment of binaries, and gives much more fine-grained decision making then only "deploy/rollback"
  
  # P.P.S `Blue/Green` vs `Canary`
  
  [source](https://github.com/lerndevops/educka/blob/master/other/Canary-vs-Blue-Green-Deployments.md)
  
  * Both blue-green and canary releases solve the same purpose
  * Although both of these terms look quite close to each other, they have subtle differences. One put confidence in your functionality release and the other put confidence the way you release.
  
  ## Blue-Green Deployment
  
  > When deploying a new version of an application, a second environment is created. Once the new environment is tested, it takes over from the old version. The old environment can then be turned off.
  
  `1. It is more about the predictable release with zero downtime deployment.`
  
  `2. Easy rollbacks in case of failure.`
  
  `3. Completely automated deployment process`
  
  `4. In cloud environment where it is easier to script & recreate infrastructure, blue/green deployment is preferred as it allows the infrastructure to be in sync with the automation`
  
  ## Canary Release
  
  > A new version of a microservice is started along with the old versions. That new version can then take a portion of the requests and the team can test how this new version interacts with the overall system.
  
  `1. The canary release is a technique to reduce the risk of introducing a new software version in production by slowly rolling out the change to a small subset of users before rolling it out to the entire infrastructure.`
  
  `2. It is about to get an idea of how new version will perform (integrate with other apps, CPU, memory, disk usage, etc).`
  
  See also illustration ([source](https://stackoverflow.com/a/47397219/5720818)):
  
  Blue/Green: [![enter image description here](https://i.sstatic.net/RtQRg.png)](https://i.sstatic.net/RtQRg.png)
  
  Canary: [![enter image description here](https://i.sstatic.net/bA9Xi.png)](https://i.sstatic.net/bA9Xi.png)
  
  > **Comments:**
  > **username_4**: Good answer! However, the definitions of **A/B Testing** and **Canaray Release** are identical which is confusing.  
  > **username_3**: thx, added explanation  
  > **username_1**: This is a regular approach that I would use, but it misses this point in the question: "Forward the new traffic to green and wait for existing blue's environment's transactions complete." Instead what would happen under this sort of nginx switch - all requests would be forwarded to green at once, including any unfinished ones from blue.  
  > **username_3**: Yes, you are right - it's regular approach. As for this part of question: '... and wait for existing blue's environment's transactions complete' - `nginx -s reload` will switch traffic gracefully. Since there is `master-slave` replication, then no need to forward unfinished `blue` traffic to the `green` app. We just let 'em finish on the `blue` node.  
  > **username_1**: The question could be phrased better - so I agree it's not very clear what is meant, but I was initially understanding it as a multi-master approach. I'll post a sticky cookie solution a little later for that case. If it's a regular master-slave sync, your solution is fine most of the time.  
  > **username_2**: Do you perhaps know how to answer this question as well? Here:  https://devops.stackexchange.com/questions/19340/green-blue-deployments-with-multiple-development-teams  
  
  ---
  
  ### Answer by username_1 on 2020-04-05. Score: 1
  
  As promised, here is a solution using haproxy with sticky cookies. Note, that this approach requires support on the application side (as only your application layer may know once transactions are completed).
  
  To achieve this, first - start with haproxy configuration of the following kind:
  
  ```
      global
          daemon
          maxconn 256
      defaults
          mode http
          timeout connect 5000ms
          timeout client 50000ms
          timeout server 50000ms
  
      frontend http-in
          bind *:80
          default_backend servers
  
      backend servers
          balance roundrobin
          cookie SID insert indirect preserve
          server server1 blue-server-hostname:8000 cookie sblue
  
  ```
  
  Note that this configuration is pretty generic and taken from haproxy documentation - from here: <https://cbonte.github.io/haproxy-dconv/2.2/configuration.html#2.5>
  
  The part that is used to achieve stickiness is cookie instruction that is added in the end, detailed documentation here: <https://cbonte.github.io/haproxy-dconv/2.2/configuration.html#4-cookie>
  
  So, with this line:
  
  ```
  cookie SID insert indirect preserve
  
  ```
  
  we tell haproxy to insert cookie called **SID** which may only have value **sblue** for now (this value is defined in last line of configuration). And we also say that if this cookie is supplied by the back-end server, we don't want haproxy to overwrite it (achieved by **insert** and **preserve** keywords).
  
  The next part is to add some application level logic to set **SID** cookie to client and make its value configurable on the application side. You want to set **SID** cookie to **sblue** for your old code and to **sgreen** for your new code.
  
  Now, when you do deployment, at first you have only blue instance, all your **SID** cookies are set to **sblue** and haproxy directs all your traffic to the only blue instance.
  
  Next, you add your green instance, and after that you add it to haproxy by adding the following line to the end of configuration above:
  
  ```
  server server2 green-server-hostname:8000 cookie sgreen
  
  ```
  
  Now any request which gets to your new green instance would have its cookie set to sgreen and would stick to the new instance.
  
  Finally, you want to engage your application-level configuration on the old blue instance to set cookie to **sgreen** to clients once their transaction is over (basically, at the point where application knows it's safe to do so). Then any new requests from such clients would be directed to green instance. At some point all your requests would be transitioned to green - and you can detach blue instance at that point.
  
  This kind of approach (or its variations) would be the most graceful and controlled by your application-layer transaction logic.
  
  > **Comments:**
  > **username_2**: Do you perhaps know how to answer this question as well? Here:  https://devops.stackexchange.com/questions/19340/green-blue-deployments-with-multiple-development-teams  
  
  ---
  
  