Here’s how it works:
- No Deployment has happened (mark blue as version to assign to the next deployment)
- V1 is deployed to blue and will be marked as active if it responds to a call to the version endpoint
- deploy
- check version endpoint
- create
/opt/myapp/canary/blue
- V2 is deployed to green and will be marked active if it responds to a call to its version endpoint
- deploy
- check version endpoint
- delete
/opt/myapp/canary/blue
- create
/opt/myapp/canary/green
Upstream (Target Groups)
upstream blue-app {
include /etc/nginx/upstream-blue.conf;
keepalive 256;
}
upstream green-app {
include /etc/nginx/upstream-green.conf;
keepalive 256;
}
server {
listen 80;
location / {
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
if (-e /etc/nginx/switch/blue) {
proxy_pass http://blue-app;
}
if (-e /etc/nginx/switch/green) {
proxy_pass http://green-app;
}
}
}
/etc/nginx/upstream-blue.conf:
server 172.16.40.73:9080
/etc/nginx/upstream-green.conf:
server 172.16.40.73:9080
switchDeploy.sh
#!/bin/bash
##########################################
# Cfg
blue="/etc/nginx/sites-enabled/blue"
green="/etc/nginx/sites-enabled/green"
# Functions
reloadNg (){
systemctl reload nginx
}
switch2Green () {
echo "Switching to: green"
rm -rf $blue
ln -s /etc/nginx/sites-available/green $green
reloadNg
exit 0
}
switch2Blue () {
echo "Switching to: blue"
rm -rf $green
ln -s /etc/nginx/sites-available/blue $blue
reloadNg
exit 0
}
findActive () {
if [ -L $blue ]; then
echo "ActiveSite:blue"
switch2Green
fi
if [ -L $green ]; then
echo "ActiveSite:green"
switch2Blue
fi
echo "No active site!"
switch2Blue
}
# Now some action
findActive
docker-compose.yml
version: '3.5'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./data/nginx.conf:/etc/nginx/nginx.conf:ro
- ./data/conf.d/etc/nginx/conf.d/:ro
app1:
image: containous/whoami
app2:
image: containous/whoami