Skip to content

Instantly share code, notes, and snippets.

@Navdevl
Created July 19, 2024 09:24
Show Gist options
  • Save Navdevl/0e34061880b5d91cd38c12364d81770c to your computer and use it in GitHub Desktop.
Save Navdevl/0e34061880b5d91cd38c12364d81770c to your computer and use it in GitHub Desktop.
Deploying applications using Dockerfile (with nearly zero downtime)
#!/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