Skip to content

Commit

Permalink
feat: add docker-compose file for dev and prod
Browse files Browse the repository at this point in the history
add script for zero downtime deployment
  • Loading branch information
NishaSharma14 committed Aug 4, 2023
1 parent b25ada4 commit 631eefc
Show file tree
Hide file tree
Showing 4 changed files with 323 additions and 2 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/prod-build.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

# This worklflow will perform following actions when the code is pushed to main branch:
# - Build the latest docker image in development which needs test to pass first.
# - Push the docker image to Docker Hub under namespace - caffeinejena with tag:[release_version].
# - Push the docker image to Docker Hub under namespace - nfdi4chem with tag:[release_version].
#
# Maintainers:
# - name: Nisha Sharma
Expand All @@ -17,7 +17,7 @@ env:
DOCKER_HUB_USERNAME : ${{ secrets.DOCKER_USERNAME }}
DOCKER_HUB_PASSWORD : ${{ secrets.DOCKER_PASSWORD }}
REPOSITORY_NAME: nmrkit
REPOSITORY_NAMESPACE: caffeinejena
REPOSITORY_NAMESPACE: nfdi4chem

jobs:
push_to_registry:
Expand Down
117 changes: 117 additions & 0 deletions ops/docker-compose-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
version: "3.8"

services:
traefik:
image: traefik:v2.10
container_name: traefik
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: nfdi4chem/nmrkit:dev-latest
pull_policy: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`dev.nmrkit.nmrxiv.org`)"
- "traefik.http.routers.web.entrypoints=web"
- "traefik.http.services.web.loadbalancer.server.port=80"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/latest/registration/health"]
interval: 1m
timeout: 10s
retries: 10
start_period: 40s
env_file:
- ./.env

prometheus:
image: prom/prometheus
container_name: nmrkit_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: nmrkit_grafana
ports:
- 3000:3000
volumes:
- /mnt/data/grafana_data:/var/lib/grafana

redis:
image: "redis:alpine"
ports:
- "${FORWARD_REDIS_PORT:-6379}:6379"
volumes:
- "/mnt/data/redis:/data"
networks:
- default
healthcheck:
test: ["CMD", "redis-cli", "ping"]
retries: 3
timeout: 5s

pgsql:
image: "informaticsmatters/rdkit-cartridge-debian"
ports:
- "${FORWARD_DB_PORT:-5432}:5432"
env_file:
- ./.env
volumes:
- "/mnt/data/pgsql:/var/lib/postgresql/data"
networks:
- default
healthcheck:
test:
[
"CMD",
"pg_isready",
"-q",
"-d",
"${POSTGRES_DB}",
"-U",
"${POSTGRES_USER}",
]
retries: 3
timeout: 5s
minio:
image: 'minio/minio:latest'
ports:
- '${FORWARD_MINIO_PORT:-9001}:9001'
- '${FORWARD_MINIO_CONSOLE_PORT:-8900}:8900'
environment:
- ./.env
volumes:
- /mnt/data/minio:/data/minio
networks:
- default
command: minio server /data/minio --console-address ":8900"

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
networks:
default:
name: nmrkit_vpc
117 changes: 117 additions & 0 deletions ops/docker-compose-prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
version: "3.8"

services:
traefik:
image: traefik:v2.10
container_name: traefik
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: nfdi4chem/nmrkit:v0.1.0
pull_policy: always
labels:
- "traefik.enable=true"
- "traefik.http.routers.web.rule=Host(`dev.nmrkit.nmrxiv.org`)"
- "traefik.http.routers.web.entrypoints=web"
- "traefik.http.services.web.loadbalancer.server.port=80"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/latest/registration/health"]
interval: 1m
timeout: 10s
retries: 10
start_period: 40s
env_file:
- ./.env

prometheus:
image: prom/prometheus
container_name: nmrkit_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: nmrkit_grafana
ports:
- 3000:3000
volumes:
- /mnt/data/grafana_data:/var/lib/grafana

redis:
image: "redis:alpine"
ports:
- "${FORWARD_REDIS_PORT:-6379}:6379"
volumes:
- "/mnt/data/redis:/data"
networks:
- default
healthcheck:
test: ["CMD", "redis-cli", "ping"]
retries: 3
timeout: 5s

pgsql:
image: "informaticsmatters/rdkit-cartridge-debian"
ports:
- "${FORWARD_DB_PORT:-5432}:5432"
env_file:
- ./.env
volumes:
- "/mnt/data/pgsql:/var/lib/postgresql/data"
networks:
- default
healthcheck:
test:
[
"CMD",
"pg_isready",
"-q",
"-d",
"${POSTGRES_DB}",
"-U",
"${POSTGRES_USER}",
]
retries: 3
timeout: 5s
minio:
image: 'minio/minio:latest'
ports:
- '${FORWARD_MINIO_PORT:-9001}:9001'
- '${FORWARD_MINIO_CONSOLE_PORT:-8900}:8900'
environment:
- ./.env
volumes:
- /mnt/data/minio:/data/minio
networks:
- default
command: minio server /data/minio --console-address ":8900"

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
networks:
default:
name: nmrkit_vpc
87 changes: 87 additions & 0 deletions ops/zero-downtime-deployment-script.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#!/bin/bash

# Define variables
COMPOSE_FILE="/mnt/data/nmrkit/ops/docker-compose-dev.yml"
DOCKER_REPO_NAME="nfdi4chem/nmrkit:dev-latest"
IMAGE_NAME="nfdi4chem/nmrkit: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

# 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 again.."
else
IS_CONTAINER_HEALTHY=0
break
fi
done

# Remove old containers and images
if [ $IS_CONTAINER_HEALTHY == 0 ] ; then

# Set the desired container name prefix
CONTAINER_NAME_PREFIX="ops_web"

# Retrieve the container IDs that match the prefix
container_ids=$(docker ps -a --filter "name=^/${CONTAINER_NAME_PREFIX}" --format "{{.ID}}")

# Sort the container IDs by creation date in ascending order
sorted_container_ids=$(echo "$container_ids" | xargs docker inspect --format='{{.Created}} {{.ID}}' | sort | awk '{print $2}')

# Get the oldest container ID
oldest_container_id=$(echo "$sorted_container_ids" | head -n 1)

# Check if any container IDs were found
if [[ -z "$oldest_container_id" ]]; then
echo "No containers found with the name prefix '${CONTAINER_NAME_PREFIX}'."
exit 1
fi

# Delete the old container and unused images
docker stop $oldest_container_id
docker rm $oldest_container_id
docker image prune -af
echo "Deleted the oldest container with ID: ${oldest_container_id}"

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

0 comments on commit 631eefc

Please sign in to comment.