Skip to content

Instantly share code, notes, and snippets.

@framp
Last active September 17, 2023 00:29
Show Gist options
  • Save framp/b7f6a6104ca83f8d97137e16b7966d9a to your computer and use it in GitHub Desktop.
Save framp/b7f6a6104ca83f8d97137e16b7966d9a to your computer and use it in GitHub Desktop.
Blue Green Deployment with Traefik and automatic git sync
#!/usr/bin/env bash
output=$(git pull)
if [[ $output == *"Already up to date."* ]]; then
echo "No changes detected."
else
echo "Changes detected."
color=$(grep file dynamic/http.routers.docker-localhost.yml | cut -d' ' -f8 | cut -d'@' -f 1);
new_color=$([ "$color" = "green" ] && echo "blue" || echo "green")
echo "Current deploy is $color"
sudo docker-compose -f docker-compose.yml build $new_color
sudo docker-compose -f docker-compose.yml up -d $new_color
sed -e s/$color/$new_color/ dynamic/http.routers.docker-localhost.yml > /tmp/temp.yml
mv /tmp/temp.yml dynamic/http.routers.docker-localhost.yml
sleep 20
sudo docker-compose -f docker-compose.yml build $color
sudo docker-compose -f docker-compose.yml up -d $color
fi

Instructions

Install docker-compose and gpg.

sudo apt install docker-compose gpg

Run ./install.sh.

It will install a service into /etc/systemd/system/app.service which will be run every 10m.

The service will git clone and zero downtime deploy changes

[Unit]
Description=app service
[Service]
Type=oneshot
WorkingDirectory=/root/app/deploy/
ExecStart=/bin/bash /root/appa/deploy/10m.sh
[Unit]
Description=app timer
[Timer]
OnUnitActiveSec=10m
OnBootSec=10s
[Install]
WantedBy=timers.target
version: '3.8'
services:
traefik:
image: traefik:v2.4
ports:
- 80:80
- 443:443
- 8080:8080
volumes:
- ./traefik.yml:/etc/traefik/traefik.yml
- ./dynamic:/etc/traefik/dynamic:ro
blue:
build:
context: ../..
dockerfile: Dockerfile
deploy:
replicas: 2
env_file:
- ./app.env
volumes:
- ./db.sqlite:/app/prisma/db.sqlite
- ./uploads:/app/uploads
green:
build:
context: ../..
dockerfile: Dockerfile
deploy:
replicas: 2
env_file:
- ./app.env
volumes:
- ./db.sqlite:/app/prisma/db.sqlite
- ./uploads:/app/uploads
http:
routers:
blue-docker-localhost:
rule: Host(`blue.docker.localhost`)
service: blue@file
http:
routers:
green-docker-localhost:
rule: Host(`green.docker.localhost`)
service: green@file
http:
routers:
docker-localhost:
rule: Host(`docker.localhost`)
service: green@file
http:
services:
blue:
loadBalancer:
servers:
- url: 'http://blue:3000/'
http:
services:
green:
loadBalancer:
servers:
- url: 'http://green:3000/'
#!/usr/bin/env bash
gpg -d app.env.gpg > app.env
cp http.routers.host.yml.example dynamic/http.routers.host.yml
sudo docker-compose -f docker-compose.yml up -d
echo "Installing service into /etc/systemd/system/app.service"
sudo cp app.service /etc/systemd/system/app.service
echo "Running every 10m as per /etc/systemd/system/app.service"
sudo cp app.timer /etc/systemd/system/app.timer
sudo systemctl daemon-reload
sudo systemctl enable --now papp.timer
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
file:
directory: /etc/traefik/dynamic
watch: true
api:
dashboard: true
insecure: true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment