Login

Navigation

This articles is published 342 days ago and last updated 342 days ago, some information may be out of date.

Automating Blog Updates Across Multiple Servers with cron Jobs and Shell Scripts

Logo.jpg

About Script
With these scripts, update blog servers data just once each time.

Update the first server, and the updates will propagate to the other servers automatically. And with the backup cron job, also, the data is always safe and secure.


Scenario

There have 3 servers for blog: blog 01, blog 02, and blog 03.

Whenever update the first server (blog 01), it triggers the update of the second server (blog 02), which in turn triggers the update of the third server (blog 03).

Additionally, a backup of the latest zip file is stored on a storage server through a cron job.


Architecture

2023-05-19_120653.png


Information on the servers

Information on the servers
NumberServer NameIP Address
01blog 0110.1.1.1
02blog 0210.2.2.2
03blog 0310.3.3.3
04storage server10.4.4.4

Requirements
  • Each server must be able to communicate with the others via SSH without a password.
  • The blog services on each server must be deployed through Docker and Docker Compose.
  • A user account (in this scenario, named "user") must have privileges to run Docker.

1st Server (Blog01)

In the first server, blog 01.

Set up a cron job to run a shell script that checks if a directory has been modified in the last 5 minutes.

crontab -e
0 1 * bash /apps/bak_dnmp.sh > /apps/archive/$(date +%Y-%m-%d).log

If it has been modified, the script performs a backup of a specified directory, copies the backup to a remote server, and runs an update script on the remote server.

If the directory has not been modified, the script does nothing.

The shell script for blog 01:

#!/bin/bash

# Set the directory to check
DIR="/apps/dnmp/www/"

if find "$DIR" -type f -mmin -5 | grep -q "."
then
    echo "Directory has been modified in the last 5 minutes"
        
    # Variables
    BACKUP_FILE="/apps/dnmp_backup_$(date +%Y-%m-%d).tar.gz"
    DNMP_PATH="/apps/dnmp"
    ARCHIVE_DIR="/apps/archive/$(date +%Y-%m-%d)"

    # Stop docker-compose
    docker-compose -f $DNMP_PATH/docker-compose.yml stop

    # Backup DNMP folder
    tar -czf "$BACKUP_FILE" $DNMP_PATH || exit 1

    # Change permission
    chmod 777 "$BACKUP_FILE"

    # Copy to 2nd server
    scp "$BACKUP_FILE" [email protected]:/apps/ || exit 2

    # Start docker-compose
    docker-compose -f $DNMP_PATH/docker-compose.yml up -d

    # Create archive directory if it doesn't exist
    mkdir -p "$ARCHIVE_DIR"

    # Move the backup file to the archive directory
    mv "$BACKUP_FILE" "$ARCHIVE_DIR/"

    # SSH to 2nd server and run update script
    ssh -tq [email protected] <<EOF
    bash /apps/update_dnmp.sh
EOF
else
    echo "Directory has not been modified in the last 5 minutes"
fi

Note the last syntax of the shell script, which runs a remote command via SSH.

Specifically, it connects to the 2nd server at IP address 10.2.2.2 as the user "user" using SSH.

The -tq options are used to force a pseudo-terminal allocation and suppress warning and diagnostic messages.

Run the update_dnmp.sh script located in the /apps directory.

Once the script has completed running, the SSH connection is terminated.


2nd Server (Blog02)

In the second server, blog 02.

Set up a shell script that

  • Stops the Docker services
  • Creates an archive of the current DNMP directory
  • Extracts the latest backup file from blog 01
  • Starts the Docker services
  • Copies the backup file to the 3rd server (10.3.3.3)
  • Finally, the script runs the next update_dnmp.sh script on the 3rd server.

The shell script for blog 02:

#!/bin/bash

# Variables
DNMP_DIR="/apps/dnmp"
ARCHIVE_DIR="/apps/archive/$(date +%Y-%m-%d)"
DOCKER_COMPOSE_FILE="$DNMP_DIR/docker-compose.yml"
BACKUP_FILE="/apps/dnmp_backup_$(date +%Y-%m-%d).tar.gz"

# Stop docker-compose
docker-compose -f "$DOCKER_COMPOSE_FILE" down

# Create archive directory if it doesn't exist
mkdir -p "$ARCHIVE_DIR"

# Move old dnmp directory to the archive directory
mv "$DNMP_DIR" "$ARCHIVE_DIR/"

# Extract the backup file
tar -xzf "$BACKUP_FILE" -C /apps
mv /apps/apps/dnmp /apps && rm -r /apps/apps

# Start docker-compose
docker-compose -f "$DOCKER_COMPOSE_FILE" up -d

# Copy the backup file to the 3rd server
scp "$ARCHIVE_DIR/dnmp_backup_$(date +%Y-%m-%d).tar.gz" [email protected]:/apps/

# Move the backup file to the archive directory
mv "$BACKUP_FILE" "$ARCHIVE_DIR/"

# SSH to 3rd server and run update script
ssh -tq [email protected] <<EOF
bash /apps/update_dnmp.sh
EOF

3rd Server (Blog03)

In the third server, blog 03.

Set up a shell script that

  • Stops the Docker services
  • Creates an archive of the current DNMP directory
  • Unzip the backup file from blog 02 server (10.2.2.2)
  • Starts the Docker services
  • Copies the backup file to a Storage server (10.4.4.4)

The shell script for blog 03:

#!/bin/bash

# Set variables
DNMP_DIR="/apps/dnmp"
ARCHIVE_DIR="/apps/archive/$(date +%Y-%m-%d)"
DOCKER_COMPOSE_FILE="$DNMP_DIR/docker-compose.yml"
BACKUP_FILE="/apps/dnmp_backup_$(date +%Y-%m-%d).tar.gz"
REMOTE_BACKUP_DIR="[email protected]:/wwww/backup/"

# Stop docker-compose
docker-compose -f "$DOCKER_COMPOSE_FILE" down

# Create archive directory if it doesn't exist
mkdir -p "$ARCHIVE_DIR"

# Move old dnmp directory to the archive directory
mv "$DNMP_DIR" "$ARCHIVE_DIR/dnmp_$(date +%H%M%S)"

# Extract the backup file
tar -xzf "$BACKUP_FILE" -C /apps
mv /apps/apps/dnmp /apps && rm -r /apps/apps

# Start docker-compose
docker-compose -f "$DOCKER_COMPOSE_FILE" up -d

# Move the backup file to the archive directory
mv "$BACKUP_FILE" "$ARCHIVE_DIR/"

# Copy the backup file to the storage server
scp "$ARCHIVE_DIR/dnmp_backup_$(date +%Y-%m-%d).tar.gz" "$REMOTE_BACKUP_DIR"

Telegram notification when a script is done (Alternative)

Reference:


Conclusion
If you have multiple Linux servers for your blog, each with a different domain, and you want to update them all at once, you can use a combination of shell scripts and cron jobs to automate the process.

Related

啟用 Windows 10/11 內置 WSL2 的 Crontab 服務