-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add bash script for zero downtime deployment
- Loading branch information
1 parent
4161552
commit 94d31f1
Showing
3 changed files
with
164 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
version: "3.8" | ||
|
||
services: | ||
traefik: | ||
image: traefik:v2.10 | ||
command: | ||
- "--api.insecure=true" | ||
- "--providers.docker=true" | ||
- "--providers.docker.exposedbydefault=false" | ||
- "--entrypoints.web.address=:80" | ||
ports: | ||
- 80:80 | ||
# - 8080:8080 # Optional: Expose Traefik dashboard on port 8080 | ||
volumes: | ||
- /var/run/docker.sock:/var/run/docker.sock | ||
|
||
web: | ||
image: caffeinejena/cheminfo-microservice:dev-latest | ||
labels: | ||
- "traefik.enable=true" | ||
- "traefik.http.routers.web.rule=Host(`dev.api.naturalproducts.net`)" | ||
- "traefik.http.routers.web.entrypoints=web" | ||
- "traefik.http.services.web.loadbalancer.server.port=80" | ||
healthcheck: | ||
test: ["CMD", "curl", "-f", "http://localhost:80/latest/chem"] | ||
interval: 1m | ||
timeout: 10s | ||
retries: 10 | ||
start_period: 40s | ||
|
||
prometheus: | ||
image: prom/prometheus | ||
container_name: prometheus | ||
ports: | ||
- 9090:9090 | ||
volumes: | ||
- ./prometheus_data/prometheus.yml:/etc/prometheus/prometheus.yml | ||
command: | ||
- '--config.file=/etc/prometheus/prometheus.yml' | ||
grafana: | ||
image: grafana/grafana | ||
container_name: grafana | ||
ports: | ||
- 3000:3000 | ||
volumes: | ||
- /mnt/data/grafana_data:/var/lib/grafana | ||
volumes: | ||
prometheus_data: | ||
driver: local | ||
driver_opts: | ||
o: bind | ||
type: none | ||
device: /mnt/data/prometheus_data | ||
grafana_data: | ||
driver: local | ||
driver_opts: | ||
o: bind | ||
type: none | ||
device: /mnt/data/grafana_data | ||
postgres_data: | ||
networks: | ||
default: | ||
name: cpm_fastapi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#!/bin/bash | ||
|
||
# Define variables | ||
COMPOSE_FILE="/mnt/data/cheminformatics-python-microservice/docker-compose-dev.yml" | ||
DOCKER_REPO_NAME="caffeinejena/cheminfo-microservice:dev-latest" | ||
IMAGE_NAME="caffeinejena/cheminfo-microservice:dev-latest" | ||
NEW_CONTAINER_ID="" | ||
IS_CONTAINER_HEALTHY=1 | ||
|
||
# Function to check the health of the container | ||
check_health() { | ||
|
||
HEALTH=$(docker inspect --format='{{json .State.Health.Status}}' $NEW_CONTAINER_ID) | ||
|
||
if [[ $HEALTH == *"healthy"* ]]; then | ||
echo "Container is healthy." | ||
return 0 | ||
else | ||
echo "Container is unhealthy or still starting" | ||
return 1 | ||
fi | ||
|
||
} | ||
|
||
# Check if there is a new image available in the Docker repository | ||
if [ "$(docker pull $DOCKER_REPO_NAME | grep "Status: Image is up to date" | wc -l)" -eq 0 ]; then | ||
# Pull the latest image | ||
echo "Pull the latest image.." | ||
docker-compose -f $COMPOSE_FILE pull | ||
|
||
# Scale up a new container | ||
echo "Scale up new container.." | ||
docker-compose -f $COMPOSE_FILE up -d --scale web=2 --no-recreate | ||
|
||
NEW_CONTAINER_ID=$(docker ps -q -l) | ||
|
||
echo "New Container Id is.." | ||
echo "$NEW_CONTAINER_ID" | ||
|
||
# Wait for new containers to start and health checks to pass | ||
echo "Waiting for the new containers to start and health check to pass retry 5 times.." | ||
n=0; | ||
while [ $n -le 10 ] | ||
do | ||
if ! check_health; then | ||
n=$(( $n + 1 )) | ||
sleep 1m | ||
echo "Container not healthy.. Check once more.." | ||
else | ||
IS_CONTAINER_HEALTHY=0 | ||
break | ||
fi | ||
done | ||
|
||
# Remove old containers and images | ||
if [ $IS_CONTAINER_HEALTHY == 0 ] ; then | ||
|
||
# Get the container IDs of running containers with the same image | ||
container_ids=$(docker ps --filter ancestor=$IMAGE_NAME --format "{{.ID}}") | ||
|
||
# Check if there are exactly two containers running with the same image | ||
if [[ $(echo "$container_ids" | wc -l) -eq 2 ]]; then | ||
|
||
# Get the creation timestamps of the two containers | ||
timestamp1=$(docker inspect --format="{{.Created}}" $container_ids | head -n 1) | ||
timestamp2=$(docker inspect --format="{{.Created}}" $container_ids | tail -n 1) | ||
|
||
# Compare the timestamps to determine the older container | ||
if [[ "$timestamp1" < "$timestamp2" ]]; then | ||
container_to_delete=$container_ids | ||
else | ||
container_to_delete=$(echo "$container_ids" | tail -n 1) | ||
fi | ||
|
||
# Delete the older container and images | ||
docker stop $container_to_delete | ||
docker rm $container_to_delete | ||
docker image prune -af | ||
|
||
echo "Deleted container $container_to_delete" | ||
|
||
else | ||
echo "Two running containers with the same image not found" | ||
fi | ||
|
||
else | ||
echo "Couldnot complete the deployment as the container is unhealthy.." | ||
docker stop $NEW_CONTAINER_ID | ||
docker rm $NEW_CONTAINER_ID | ||
fi | ||
|
||
else | ||
echo "Skipping deployment as no new image available.." | ||
fi |