mirror of
https://github.com/d0zingcat/ghost-docker.git
synced 2026-05-13 15:09:34 +00:00
- The idea here is this can start up and do its thing in the background whilst we're rsync'ing content and saves us waiting longer later on
644 lines
22 KiB
Bash
644 lines
22 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
# Constants
|
|
readonly GHOST_UID=1000
|
|
readonly GHOST_GID=1000
|
|
readonly MYSQL_TIMEOUT=120
|
|
readonly DISK_SPACE_SAFETY_FACTOR=1.5
|
|
readonly TEMP_SQL_FILE="${PWD}/data/ghost_import.sql"
|
|
readonly RECOVERY_SCRIPT="${PWD}/recovery_instructions.sh"
|
|
|
|
# Global variables
|
|
current_location=""
|
|
mysql_user=""
|
|
mysql_password=""
|
|
ghost_service_name=""
|
|
|
|
# Function to convert bytes to human readable format
|
|
human_readable() {
|
|
local bytes=$1
|
|
local units=("B" "KB" "MB" "GB" "TB")
|
|
local unit=0
|
|
local size=$bytes
|
|
|
|
while (( $(echo "$size > 1024" | bc -l) )) && (( unit < 4 )); do
|
|
size=$(echo "scale=2; $size / 1024" | bc -l)
|
|
((unit++))
|
|
done
|
|
|
|
echo "${size} ${units[$unit]}"
|
|
}
|
|
|
|
# Function to get size in bytes
|
|
get_size_bytes() {
|
|
local path=$1
|
|
if [[ -d "$path" ]]; then
|
|
du -sb "$path" 2>/dev/null | cut -f1
|
|
else
|
|
echo "0"
|
|
fi
|
|
}
|
|
|
|
# Cleanup function
|
|
cleanup() {
|
|
local exit_code=$?
|
|
|
|
if [[ -f "$TEMP_SQL_FILE" ]]; then
|
|
echo "Cleaning up temporary files..."
|
|
rm "$TEMP_SQL_FILE"
|
|
fi
|
|
|
|
if [[ $exit_code -ne 0 && -f "$RECOVERY_SCRIPT" ]]; then
|
|
echo ""
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo "❌ MIGRATION FAILED!"
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo ""
|
|
echo "Don't worry - your data is safe!"
|
|
echo ""
|
|
echo "To restore your original Ghost installation, run:"
|
|
echo " bash $RECOVERY_SCRIPT"
|
|
echo ""
|
|
echo "Need help? Check the migration logs above for error details."
|
|
echo "════════════════════════════════════════════════════════════"
|
|
fi
|
|
|
|
exit $exit_code
|
|
}
|
|
|
|
# Set trap for cleanup
|
|
trap cleanup EXIT INT TERM
|
|
|
|
# Create recovery script
|
|
create_recovery_script() {
|
|
local service_name="$1"
|
|
cat > "$RECOVERY_SCRIPT" << EOF
|
|
#!/usr/bin/env bash
|
|
# Recovery script generated by Ghost migration on $(date)
|
|
# This script will restore your original Ghost installation
|
|
|
|
set -euo pipefail
|
|
|
|
echo "Restoring original Ghost installation..."
|
|
|
|
# Stop any Docker containers that might have been started
|
|
docker compose down 2>/dev/null || true
|
|
|
|
# Re-enable and start the original Ghost service
|
|
if [[ -n "${service_name}" ]]; then
|
|
systemctl enable "${service_name}" 2>/dev/null || true
|
|
systemctl start "${service_name}" 2>/dev/null || true
|
|
echo "Original Ghost installation has been restored."
|
|
echo "You can check the status with: systemctl status ${service_name}"
|
|
else
|
|
echo "Note: Ghost service was not yet stopped, so no restoration needed."
|
|
echo "Your original installation should still be running."
|
|
fi
|
|
EOF
|
|
|
|
chmod +x "$RECOVERY_SCRIPT"
|
|
echo "✓ Recovery script created at: $RECOVERY_SCRIPT"
|
|
}
|
|
|
|
# Validate MySQL connection
|
|
validate_mysql_connection() {
|
|
local host=$1
|
|
local database=$2
|
|
local user=$3
|
|
local password=$4
|
|
|
|
echo "Testing MySQL connection..."
|
|
|
|
if mysql -h"$host" -u"$user" -p"$password" -e "SELECT 1 FROM information_schema.tables WHERE table_schema='$database' LIMIT 1;" &>/dev/null; then
|
|
echo "✓ MySQL connection successful"
|
|
return 0
|
|
else
|
|
echo "✗ MySQL connection failed"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Check prerequisites
|
|
check_prerequisites() {
|
|
# Check we're running as root
|
|
if [[ "$EUID" -ne 0 ]]; then
|
|
echo "Sorry, this script must be run as root!"
|
|
exit 1
|
|
fi
|
|
|
|
# Check required commands
|
|
local required_commands=("jq" "docker" "bc" "mysql" "mysqldump" "rsync")
|
|
local missing_commands=()
|
|
|
|
for cmd in "${required_commands[@]}"; do
|
|
if ! command -v "$cmd" &>/dev/null; then
|
|
missing_commands+=("$cmd")
|
|
fi
|
|
done
|
|
|
|
if [[ ${#missing_commands[@]} -gt 0 ]]; then
|
|
echo "The following required commands are not installed:"
|
|
printf ' - %s\n' "${missing_commands[@]}"
|
|
echo "Please install them first."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Show migration summary
|
|
show_migration_summary() {
|
|
echo "
|
|
═══════════════════════════════════════════════════════════════════
|
|
GHOST MIGRATION SUMMARY
|
|
═══════════════════════════════════════════════════════════════════
|
|
|
|
This script will migrate your Ghost CLI installation to Docker.
|
|
|
|
WHAT WILL HAPPEN:
|
|
✓ Validate MySQL credentials
|
|
✓ Stop your current Ghost installation
|
|
✓ Copy content directory to Docker mount
|
|
✓ Export and import your database to a Docker based MySQL instance
|
|
✓ Start Ghost in Docker container
|
|
✓ Optionally configure Caddy Webserver for HTTPS
|
|
|
|
WHAT WONT HAPPEN:
|
|
✓ No data will be deleted
|
|
✓ Recovery script will be created
|
|
✓ Original installation remains intact
|
|
|
|
REQUIREMENTS:
|
|
✓ .env file configured for Docker
|
|
✓ MySQL credentials with dump permissions
|
|
✓ Sufficient disk space for migration
|
|
|
|
═══════════════════════════════════════════════════════════════════
|
|
"
|
|
}
|
|
|
|
# Migrate content directory
|
|
migrate_content() {
|
|
local source="${current_location}/content/"
|
|
local dest="${PWD}/data/ghost/"
|
|
|
|
echo "Starting content migration..."
|
|
echo "Source: $source"
|
|
echo "Destination: $dest"
|
|
echo ""
|
|
|
|
# Create destination directory
|
|
mkdir -p "$dest"
|
|
|
|
# Copy with progress
|
|
echo "Copying files..."
|
|
rsync --info=progress2 -aH "$source" "$dest"
|
|
|
|
echo ""
|
|
echo "Setting permissions for Ghost container (UID: $GHOST_UID, GID: $GHOST_GID)..."
|
|
chown -R ${GHOST_UID}:${GHOST_GID} "$dest"
|
|
|
|
echo "✓ Content migration completed"
|
|
}
|
|
|
|
# Test if we can dump database with given credentials
|
|
test_mysql_dump() {
|
|
local host=$1
|
|
local database=$2
|
|
local user=$3
|
|
local password=$4
|
|
|
|
# Try a minimal dump to test permissions
|
|
if MYSQL_PWD="$password" mysqldump --no-tablespaces --no-data -h"$host" -u"$user" "$database" >/dev/null 2>&1; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Export and import database
|
|
migrate_database() {
|
|
local mysql_host
|
|
local mysql_database
|
|
mysql_host=$(jq -r < "${current_location}/config.production.json" '.database.connection.host')
|
|
mysql_database=$(jq -r < "${current_location}/config.production.json" '.database.connection.database')
|
|
|
|
echo "Exporting database from $mysql_host..."
|
|
|
|
# Export database with proper error handling
|
|
local dump_output
|
|
local dump_status
|
|
dump_output=$(MYSQL_PWD="$mysql_password" mysqldump --no-tablespaces -h"$mysql_host" -u"$mysql_user" "$mysql_database" 2>&1 > "$TEMP_SQL_FILE")
|
|
dump_status=$?
|
|
|
|
# Check for errors in output (mysqldump may return 0 even with some errors)
|
|
if [[ $dump_status -ne 0 ]] || [[ "$dump_output" =~ "Error:" ]]; then
|
|
echo ""
|
|
echo "ERROR: Failed to export database"
|
|
if [[ "$dump_output" =~ "PROCESS privilege" ]]; then
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "The MySQL user '$mysql_user' needs the PROCESS privilege."
|
|
echo ""
|
|
echo "To fix this, connect to MySQL as a privileged user and run:"
|
|
echo " GRANT PROCESS ON *.* TO '$mysql_user'@'%';"
|
|
echo " FLUSH PRIVILEGES;"
|
|
echo ""
|
|
echo "Or retry with a user that has sufficient privileges (e.g., root)."
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
elif [[ -n "$dump_output" ]]; then
|
|
echo "Error details: $dump_output"
|
|
fi
|
|
exit 1
|
|
fi
|
|
|
|
# Verify the dump file exists and has content
|
|
if [[ ! -f "$TEMP_SQL_FILE" ]] || [[ ! -s "$TEMP_SQL_FILE" ]]; then
|
|
echo ""
|
|
echo "ERROR: Database dump file is empty or missing"
|
|
echo "This might indicate insufficient disk space or permissions issues."
|
|
exit 1
|
|
fi
|
|
|
|
local dump_size
|
|
dump_size=$(human_readable "$(stat -c%s "$TEMP_SQL_FILE")")
|
|
echo "✓ Database exported successfully ($dump_size)"
|
|
|
|
# Wait for MySQL to be ready
|
|
echo -n "Waiting for MySQL container to be ready"
|
|
local counter=0
|
|
until [ "$(docker compose ps db --format json | jq -r '.Health')" = "healthy" ] || [ $counter -eq $MYSQL_TIMEOUT ]; do
|
|
echo -n "."
|
|
sleep 1
|
|
((counter++)) || true
|
|
done
|
|
|
|
if [[ $counter -eq $MYSQL_TIMEOUT ]]; then
|
|
echo ""
|
|
echo "ERROR: Timed out waiting for MySQL container"
|
|
exit 1
|
|
fi
|
|
|
|
echo " ✓"
|
|
|
|
# Import database
|
|
echo "Importing database into Docker MySQL..."
|
|
local MYSQL_ROOT_PASSWORD
|
|
MYSQL_ROOT_PASSWORD=$(grep DATABASE_ROOT_PASSWORD "$PWD/.env" | cut -d '=' -f 2-)
|
|
if ! docker compose exec -e MYSQL_PWD="$MYSQL_ROOT_PASSWORD" -T db sh -c 'exec mysql -uroot $MYSQL_DATABASE' < "$TEMP_SQL_FILE"; then
|
|
echo "ERROR: Failed to import database"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✓ Database migration completed"
|
|
|
|
# Clean up SQL file
|
|
rm -f "$TEMP_SQL_FILE"
|
|
}
|
|
|
|
# Find Ghost installations in /var/www/
|
|
find_ghost_installations() {
|
|
local installations=()
|
|
|
|
# Search one level deep in /var/www/
|
|
if [[ -d "/var/www" ]]; then
|
|
for dir in /var/www/*/; do
|
|
# Skip if not a directory
|
|
[[ ! -d "$dir" ]] && continue
|
|
|
|
# Remove trailing slash
|
|
dir="${dir%/}"
|
|
|
|
# Check if it's a valid Ghost installation
|
|
if [[ -f "${dir}/.ghost-cli" ]] && [[ -d "${dir}/content" ]]; then
|
|
# Additional validation - check if config file exists
|
|
if [[ -f "${dir}/config.production.json" ]]; then
|
|
installations+=("$dir")
|
|
fi
|
|
fi
|
|
done
|
|
fi
|
|
|
|
printf '%s\n' "${installations[@]}"
|
|
}
|
|
|
|
# Main script starts here
|
|
main() {
|
|
check_prerequisites
|
|
|
|
echo "WARNING: This script is currently in beta, please ensure you have a backup!"
|
|
|
|
show_migration_summary
|
|
|
|
read -rp 'Ready to proceed with migration? (y/n): ' confirm
|
|
if [[ "${confirm,,}" != "y" ]]; then
|
|
echo "Migration cancelled."
|
|
exit 0
|
|
fi
|
|
|
|
# Search for Ghost installations
|
|
echo ""
|
|
echo "Searching for Ghost installations in /var/www/..."
|
|
|
|
local ghost_installations=()
|
|
while IFS= read -r line; do
|
|
[[ -n "$line" ]] && ghost_installations+=("$line")
|
|
done < <(find_ghost_installations)
|
|
|
|
# Get installation location
|
|
if [[ ${#ghost_installations[@]} -gt 0 ]]; then
|
|
echo ""
|
|
echo "Found ${#ghost_installations[@]} Ghost installation(s) in /var/www/:"
|
|
echo ""
|
|
|
|
# Display found installations with numbers
|
|
local i=1
|
|
for installation in "${ghost_installations[@]}"; do
|
|
local site_name
|
|
site_name=$(basename "$installation")
|
|
echo " $i) $site_name (${installation})"
|
|
((i++))
|
|
done
|
|
echo " $i) Enter a different path"
|
|
echo ""
|
|
|
|
read -rp "Select an installation (1-$i): " selection
|
|
|
|
# Validate selection
|
|
if [[ "$selection" =~ ^[0-9]+$ ]] && [[ $selection -ge 1 ]] && [[ $selection -le $i ]]; then
|
|
if [[ $selection -eq $i ]]; then
|
|
# User wants to enter a different path
|
|
read -rp 'Enter your current Ghost installation path: ' current_location
|
|
else
|
|
# User selected a found installation
|
|
current_location="${ghost_installations[$((selection-1))]}"
|
|
echo "Selected: $current_location"
|
|
fi
|
|
else
|
|
echo "Invalid selection"
|
|
exit 1
|
|
fi
|
|
else
|
|
# No installations found, ask for path directly
|
|
echo ""
|
|
echo "No Ghost installations found in /var/www/"
|
|
read -rp 'Enter your current Ghost installation path: ' current_location
|
|
fi
|
|
|
|
if [[ -z "$current_location" ]]; then
|
|
echo "ERROR: Installation path is required"
|
|
exit 1
|
|
fi
|
|
|
|
# Validate Ghost installation
|
|
if [[ ! -f "${current_location}/.ghost-cli" ]]; then
|
|
echo "ERROR: No Ghost-CLI installation found at ${current_location}"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ ! -d "${current_location}/content" ]]; then
|
|
echo "ERROR: No content directory found at ${current_location}/content"
|
|
exit 1
|
|
fi
|
|
|
|
# Check for .env file
|
|
if [[ ! -f "${PWD}/.env" ]]; then
|
|
echo "ERROR: Please create a .env file for the Docker installation first"
|
|
exit 1
|
|
fi
|
|
|
|
# Get Ghost service name
|
|
ghost_service_name="ghost_$(jq -r < "${current_location}/.ghost-cli" '.name')"
|
|
|
|
# Get database configuration
|
|
local mysql_host
|
|
local mysql_database
|
|
local ghost_mysql_user
|
|
local ghost_mysql_password
|
|
mysql_host=$(jq -r < "${current_location}/config.production.json" '.database.connection.host')
|
|
mysql_database=$(jq -r < "${current_location}/config.production.json" '.database.connection.database')
|
|
ghost_mysql_user=$(jq -r < "${current_location}/config.production.json" '.database.connection.user')
|
|
ghost_mysql_password=$(jq -r < "${current_location}/config.production.json" '.database.connection.password')
|
|
|
|
# Check disk space
|
|
echo ""
|
|
echo "Checking disk space requirements..."
|
|
|
|
local content_size
|
|
local content_size_human
|
|
local required_space
|
|
local required_space_human
|
|
local available_space
|
|
local available_space_human
|
|
|
|
content_size=$(get_size_bytes "${current_location}/content")
|
|
content_size_human=$(human_readable "$content_size")
|
|
required_space=$(echo "$content_size * $DISK_SPACE_SAFETY_FACTOR" | bc | cut -d'.' -f1)
|
|
required_space_human=$(human_readable "$required_space")
|
|
available_space=$(df -B1 "${PWD}" | tail -1 | awk '{print $4}')
|
|
available_space_human=$(human_readable "$available_space")
|
|
|
|
echo " Content size: ${content_size_human}"
|
|
echo " Required space: ${required_space_human}"
|
|
echo " Available space: ${available_space_human}"
|
|
|
|
if (( available_space < required_space )); then
|
|
echo ""
|
|
echo "ERROR: Insufficient disk space!"
|
|
echo "Need ${required_space_human} but only ${available_space_human} available."
|
|
exit 1
|
|
fi
|
|
|
|
echo "✓ Disk space check passed"
|
|
echo ""
|
|
|
|
# Try Ghost's own credentials first
|
|
echo "Testing database export with Ghost's credentials..."
|
|
if test_mysql_dump "$mysql_host" "$mysql_database" "$ghost_mysql_user" "$ghost_mysql_password"; then
|
|
echo "✓ Ghost's credentials have sufficient privileges"
|
|
mysql_user="$ghost_mysql_user"
|
|
mysql_password="$ghost_mysql_password"
|
|
else
|
|
echo "Ghost's database user doesn't have sufficient privileges for export."
|
|
echo "Please provide credentials for a MySQL user with dump privileges."
|
|
echo ""
|
|
|
|
# Get MySQL credentials and validate
|
|
read -rp "MySQL user for database export (default: root): " mysql_user
|
|
mysql_user=${mysql_user:-root}
|
|
|
|
# Get password securely
|
|
echo -n "MySQL password for ${mysql_user}: "
|
|
read -rs mysql_password
|
|
echo ""
|
|
|
|
# Validate connection
|
|
if ! validate_mysql_connection "$mysql_host" "$mysql_database" "$mysql_user" "$mysql_password"; then
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "Could not connect to MySQL database."
|
|
echo ""
|
|
echo "Please verify:"
|
|
echo " • MySQL service is running"
|
|
echo " • Credentials are correct"
|
|
echo " • User has access from this host"
|
|
echo " • Database name is correct"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
exit 1
|
|
fi
|
|
|
|
# Test dump permissions
|
|
if ! test_mysql_dump "$mysql_host" "$mysql_database" "$mysql_user" "$mysql_password"; then
|
|
echo ""
|
|
echo "ERROR: The provided user doesn't have sufficient privileges for database export."
|
|
echo "Please ensure the user has the necessary privileges or try a different user."
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Create recovery script (with empty service name since we haven't stopped anything yet)
|
|
create_recovery_script ""
|
|
|
|
# Final confirmation before stopping Ghost
|
|
echo ""
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo "⚠️ YOUR SITE WILL BE UNAVAILABLE DURING MIGRATION"
|
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
echo ""
|
|
echo "The next steps will:"
|
|
echo " 1. Stop your Ghost service"
|
|
echo " 2. Migrate your content and database"
|
|
echo " a. Your new content directory will be at ${PWD}/data/ghost/"
|
|
echo " b. Your new MySQL database will be at ${PWD}/data/mysql/"
|
|
echo " 3. Start Ghost in Docker"
|
|
echo ""
|
|
echo "If anything goes wrong, run: bash $RECOVERY_SCRIPT"
|
|
echo ""
|
|
read -rp 'Continue with migration? This will make your site unavailable. (y/n): ' confirm
|
|
|
|
if [[ "${confirm,,}" != "y" ]]; then
|
|
echo "Migration cancelled."
|
|
rm -f "$RECOVERY_SCRIPT"
|
|
exit 0
|
|
fi
|
|
|
|
# Stop Ghost service
|
|
echo ""
|
|
echo "Stopping Ghost service..."
|
|
|
|
# Update recovery script with actual service name before stopping
|
|
create_recovery_script "$ghost_service_name"
|
|
|
|
if ! systemctl stop "$ghost_service_name"; then
|
|
echo "ERROR: Failed to stop Ghost service"
|
|
echo "Please check: systemctl status $ghost_service_name"
|
|
exit 1
|
|
fi
|
|
|
|
systemctl disable "$ghost_service_name" 2>/dev/null || true
|
|
echo "✓ Ghost service stopped"
|
|
|
|
# Start MySQL container
|
|
echo "Starting MySQL container for migration..."
|
|
docker compose up db -d
|
|
|
|
# Migrate content
|
|
echo ""
|
|
migrate_content
|
|
|
|
# Migrate database
|
|
echo ""
|
|
migrate_database
|
|
|
|
# Import configuration
|
|
echo ""
|
|
echo "Importing configuration from existing installation..."
|
|
echo ""
|
|
node "${PWD}/scripts/config-to-env.js" "${current_location}/config.production.json"
|
|
echo ""
|
|
|
|
echo -e "\n# Configuration imported from existing Ghost install at ${current_location}" >> "${PWD}/.env"
|
|
node "${PWD}/scripts/config-to-env.js" "${current_location}/config.production.json" >> "${PWD}/.env"
|
|
echo "✓ Configuration imported"
|
|
|
|
# Start Ghost
|
|
echo ""
|
|
echo "Starting Ghost container..."
|
|
docker compose up ghost -d
|
|
echo "✓ Ghost is running in Docker"
|
|
|
|
# Caddy setup
|
|
echo ""
|
|
read -rp 'Start Caddy Webserver for automatic HTTPS? This will stop Nginx. (y/n): ' confirm
|
|
if [[ "${confirm,,}" == "y" ]]; then
|
|
echo "Stopping Nginx..."
|
|
systemctl stop nginx -q || true
|
|
systemctl disable nginx -q || true
|
|
|
|
echo "Starting Caddy..."
|
|
docker compose up caddy -d
|
|
|
|
local domain
|
|
domain=$(grep 'DOMAIN' "${PWD}/.env" | cut -d '=' -f 2-)
|
|
echo ""
|
|
echo "✓ Caddy Webserver is running!"
|
|
echo "✓ Your site is available at: https://${domain}"
|
|
else
|
|
local ghost_port
|
|
ghost_port=$(grep 'GHOST_PORT' "${PWD}/.env" | cut -d '=' -f 2-)
|
|
echo ""
|
|
echo "✓ Ghost is now running"
|
|
echo " To finish migration, configure your webserver to forward traffic to 127.0.0.1:${ghost_port}"
|
|
fi
|
|
|
|
# Success! Remove recovery script
|
|
rm -f "$RECOVERY_SCRIPT"
|
|
|
|
echo ""
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo "✓ MIGRATION COMPLETED SUCCESSFULLY!"
|
|
echo "════════════════════════════════════════════════════════════"
|
|
echo ""
|
|
echo "Your Ghost site is now running in Docker!"
|
|
echo ""
|
|
echo "IMPORTANT INFORMATION:"
|
|
echo " • Original files: $current_location"
|
|
echo " • Original database: $mysql_database on $mysql_host"
|
|
echo " • New content location: ${PWD}/data/ghost/"
|
|
echo " • Configuration: ${PWD}/.env"
|
|
echo ""
|
|
echo "QUICK START COMMANDS:"
|
|
echo " View logs: docker compose logs -f ghost"
|
|
echo " Check status: docker compose ps"
|
|
echo " Stop Ghost: docker compose down"
|
|
echo " Start Ghost: docker compose up -d"
|
|
echo ""
|
|
echo "TROUBLESHOOTING:"
|
|
echo " • If site is unreachable, check: docker compose logs caddy"
|
|
echo " • For 502 errors, Ghost may still be starting (check logs)"
|
|
echo " • Database issues: docker compose logs db"
|
|
echo ""
|
|
echo "UPGRADES:"
|
|
echo " 1. git pull"
|
|
echo " 2. docker compose pull"
|
|
echo " 3. docker compose up -d"
|
|
echo " Always backup before major upgrades!"
|
|
echo ""
|
|
echo "HELP GUIDE:"
|
|
echo " For a comprehensive list of commands and troubleshooting tips:"
|
|
echo " ./help"
|
|
echo ""
|
|
echo "CLEANUP:"
|
|
echo "Once you're checked over the migration you can remove the old installation files and database by running:"
|
|
echo ""
|
|
echo " rm -r $current_location/"
|
|
echo " mysql -h$mysql_host -u$mysql_user -p -e 'DROP DATABASE IF EXISTS ${mysql_database}'"
|
|
echo ""
|
|
echo "This will remove the old Ghost CLI and Ghost 5.x installation"
|
|
echo ""
|
|
echo "════════════════════════════════════════════════════════════"
|
|
}
|
|
|
|
# Run main function
|
|
main "$@"
|