Created
July 19, 2024 09:24
-
-
Save Navdevl/0e34061880b5d91cd38c12364d81770c to your computer and use it in GitHub Desktop.
Deploying applications using Dockerfile (with nearly zero downtime)
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
#!/bin/bash | |
# Function to check container health | |
check_container_health() { | |
local container=$1 | |
local max_retries=10 | |
local retry_interval=5 | |
for i in $(seq 1 $max_retries); do | |
if [ "$(docker inspect --format='{{.State.Health.Status}}' $container)" == "healthy" ]; then | |
echo "$container is healthy" | |
return 0 | |
fi | |
echo "Waiting for $container to be healthy... (Attempt $i/$max_retries)" | |
sleep $retry_interval | |
done | |
echo "Error: $container failed to become healthy" | |
return 1 | |
} | |
# Pull latest code | |
git pull | |
HEAD_COMMIT=$(git rev-parse HEAD) | |
echo "Deploying commit: $HEAD_COMMIT" | |
# Determine which port is currently active | |
if grep -q "localhost:8000" /etc/caddy/Caddyfile; then | |
CURRENT_PORT=8000 | |
NEW_PORT=8001 | |
else | |
CURRENT_PORT=8001 | |
NEW_PORT=8000 | |
fi | |
echo "Deploying to port: $NEW_PORT" | |
# Build new Docker image | |
echo "Building new Docker image..." | |
docker build -t mosaic_backend:latest . | |
# Start new container | |
echo "Starting new container..." | |
NEW_CONTAINER=$(docker run -d --health-cmd="curl -f http://localhost:8000/api/health || exit 1" --health-interval=30s --health-timeout=20s --health-retries=3 --health-start-period=10s --memory-swap=-1 --add-host=host.docker.internal:host-gateway -p $NEW_PORT:8000 --env-file .env --env HEAD_COMMIT=$HEAD_COMMIT mosaic_backend:latest gunicorn app.main:app -c gunicorn.conf.py) | |
# Check health of new container | |
echo "Checking health of new container..." | |
if ! check_container_health $NEW_CONTAINER; then | |
echo "Deployment failed: New container is not healthy" | |
docker stop $NEW_CONTAINER | |
docker rm $NEW_CONTAINER | |
exit 1 | |
fi | |
# Update caddy configuration | |
sudo sed -i "s/localhost:$CURRENT_PORT/localhost:$NEW_PORT/" /etc/caddy/Caddyfile | |
# Reload caddy | |
echo "Reloading caddy..." | |
sudo systemctl reload caddy | |
# Stop and remove the old container | |
OLD_CONTAINER=$(docker ps -q --filter "publish=$CURRENT_PORT") | |
if [ ! -z "$OLD_CONTAINER" ]; then | |
docker stop $OLD_CONTAINER | |
docker rm $OLD_CONTAINER | |
fi | |
echo "Deployment completed successfully" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment