another / entrypoint.sh
sohom004's picture
INIT
c20b8de
#!/usr/bin/env bash
set -euo pipefail
# Increase PHP memory for WP-CLI tasks
export WP_CLI_PHP_ARGS="-d memory_limit=256M"
# === Config ===
PORT="${PORT:-7860}"
WP_PATH="/var/www/html"
DB_DIR="$WP_PATH/wp-content/database"
export DB_FILE="$DB_DIR/.ht.sqlite"
UPLOADS_DIR="$WP_PATH/wp-content/uploads"
# LOG
log() { echo "[space] $(date -Iseconds) $*"; }
lognew() { echo "$1 $(date -Iseconds) $2"; }
export -f lognew
# Load .public
PUBLIC_FILE_PATH=/root/.public
if [ -f "$PUBLIC_FILE_PATH" ]; then
log "source ${PUBLIC_FILE_PATH}"
eval "source $PUBLIC_FILE_PATH"
else
echo "File '$PUBLIC_FILE_PATH' not present!"
export SITE_TITLE="WordPress SQLite"
export ARCHIVE_ITEM_ID="wp-sqlite-backup-enc"
fi
# Configure Wordpress
ADMIN_USER="${ADMIN_USER:-codersall}"
ADMIN_PASS="${ADMIN_PASS:-codersAll.com}"
ADMIN_EMAIL="${ADMIN_EMAIL:-admin@codersAll.com}"
log "ADMIN_USER: $ADMIN_USER"
# Configure Internet Archive
if [[ -v IA_EMAIL ]] && [[ -v IA_PASSWORD ]]; then
log "Configuring Internet Archive"
ia configure -u $IA_EMAIL -p $IA_PASSWORD
history -c
export IA="exist"
else
log "Skipped Configuring Internet Archive!"
export IA=""
fi
# Configure Dropbox (via RClone)
if [[ -n "$RCLONE_DROPBOX_TOKEN" ]]; then
log "Configuring Dropbox (via RClone)"
mkdir -p .config/rclone/
cat <<EOF >.config/rclone/rclone.conf
[my-dropbox]
type = dropbox
token = ${RCLONE_DROPBOX_TOKEN}
EOF
chmod 600 .config/rclone/rclone.conf
export DBRC="exist"
else
log "Skipped Configuring Dropbox (via RClone)"
export DBRC=""
fi
# Configure HuggingFace Repo (to persist themes & plugins)
REPO_NAME="wp-persist"
export SITE_URL="${SITE_URL:-}"
export HF_USER=$(echo "$SITE_URL" | cut -d'/' -f3 | cut -d'-' -f1)
HF_TOKEN="${HF_TOKEN:-}"
if [[ -n "$HF_USER" ]] && [[ -n "$HF_TOKEN" ]]; then
log "creating Repo: $REPO_NAME (if doesn't exists)"
hf repo create $HF_USER/$REPO_NAME --repo-type space --space-sdk static --private --token $HF_TOKEN --exist-ok
git lfs install
git clone https://$HF_USER:$HF_TOKEN@huggingface.co/spaces/$HF_USER/$REPO_NAME /tmp/wp-store || {
log "ERROR: Failed to clone repo. Make sure the space exists and HF_TOKEN has write access."
exit 1
}
cd /tmp/wp-store
# Configure git identity
git config user.email "$HF_USER@users.noreply.huggingface.co"
git config user.name "$HF_USER"
# Configure git auth persistence
git config credential.helper store
echo "https://$HF_USER:$HF_TOKEN@huggingface.co" > ~/.git-credentials
#echo "https://$HF_USER:$HF_TOKEN@huggingface.co" >> ~/.git-credentials
# Initialize folder structure if missing
if [[ ! -d wp-content ]]; then
log "Initializing wp-content directory in repo"
mkdir -p wp-content/themes
mkdir -p wp-content/plugins
touch wp-content/themes/.empty
touch wp-content/plugins/.empty
echo -en "*.woff2 filter=lfs diff=lfs merge=lfs -text\n*.webp filter=lfs diff=lfs merge=lfs -text\n*.png filter=lfs diff=lfs merge=lfs -text\n*.ttf filter=lfs diff=lfs merge=lfs -text\n*.gif filter=lfs diff=lfs merge=lfs -text\n*.jpg filter=lfs diff=lfs merge=lfs -text" >> .gitattributes
git add .
git commit -m "Initialize empty wp-content"
git push
log "Initial push completed"
cd -
else
log "HF repo already contains wp-content"
cd -
rsync -aq --delete /tmp/wp-store/wp-content/themes/ /var/www/html/wp-content/themes/
rsync -aq --delete /tmp/wp-store/wp-content/plugins/ /var/www/html/wp-content/plugins/
log "Sync completed"
fi
else
log "Skipping HF sync: HF_USER or HF_TOKEN missing"
fi
#
export ARCHIVE_ITEM_ID="$ARCHIVE_ITEM_ID-$HF_USER"
log "SITE_URL: $SITE_URL"
log "ARCHIVE_ITEM_ID: $ARCHIVE_ITEM_ID"
if [[ -n "$SITE_URL" ]]; then
export HTTP_HOST=$(echo "$SITE_URL" | sed -E 's~https?://([^/]+).*~\1~')
export HTTPS=on
export SERVER_PORT=443
log "Running in HTTPS mode for proxied environment. SITE_URL: $SITE_URL, HTTP_HOST: $HTTP_HOST"
else
export HTTP_HOST="127.0.0.1"
export SITE_URL="http://127.0.0.1"
export HTTPS=off
export SERVER_PORT=80
log "Running in local HTTP mode (no proxy detected)"
fi
# === 1) Make Apache listen on $PORT ===
log "Configuring Apache to listen on port ${PORT}"
# --- EARLY FIX: force HTTPS perception before mod_dir runs ---
if [[ "$SITE_URL" != "http://127.0.0.1" && "$HTTP_HOST" != "127.0.0.1" ]]; then
cat <<EOF >/etc/apache2/conf-enabled/00-early-https.conf
<IfModule mod_setenvif.c>
SetEnvIf X-Forwarded-Proto https HTTPS=on
SetEnvIf X-Forwarded-Proto https SERVER_PORT=443
</IfModule>
<IfModule mod_headers.c>
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</IfModule>
UseCanonicalName Off
UseCanonicalPhysicalPort Off
EOF
else
log "Skipping early HTTPS header config (local mode)"
fi
VHOST_7860=/etc/apache2/sites-available/000-default-${PORT}.conf
# ensure 7860 is listened on
if [[ "${PORT}" != "80" ]]; then
sed -ri "s/^Listen 80$/Listen 80\nListen ${PORT}/" /etc/apache2/ports.conf || true
# create a copy of the default vhost for the runtime port (if not already present)
if [[ ! -f "${VHOST_7860}" ]]; then
cp /etc/apache2/sites-available/000-default.conf "${VHOST_7860}"
sed -ri "s/<VirtualHost \*:80>/<VirtualHost *:${PORT}>/g" "${VHOST_7860}"
# Inject manual /wp-admin → /wp-admin/ redirect near top of VirtualHost (before DirectoryIndex)
if ! grep -q "RewriteCond %{REQUEST_URI} ^/wp-admin$" "${VHOST_7860}"; then
log "Injecting early wp-admin redirect inside VirtualHost"
sed -i "/<VirtualHost/a \\
<IfModule mod_rewrite.c>\\n\
RewriteEngine On\\n\
RewriteCond %{REQUEST_URI} ^/wp-admin$\\n\
RewriteRule ^/wp-admin$ /wp-admin/ [R=301,L]\\n\
</IfModule>\\n" "${VHOST_7860}"
fi
a2ensite "000-default-${PORT}.conf" >/dev/null 2>&1 || true
fi
fi
# --- 🔧 Inject canonical ServerName/Port inside VirtualHost to remove :7860 redirects ---
if [[ -f "${VHOST_7860}" ]]; then
log "Injecting canonical ServerName/Port into ${VHOST_7860}"
sed -i "/<\/VirtualHost>/i \\
ServerName ${HTTP_HOST}\\n\
UseCanonicalName Off\\n\
UseCanonicalPhysicalPort Off\\n\
RequestHeader set X-Forwarded-Proto https\\n\
RequestHeader set X-Forwarded-Port 443\\n\
SetEnv HTTPS on\\n\
SetEnv SERVER_PORT 443\\n" "${VHOST_7860}"
fi
# --- Skip HTTPS enforcement if running locally ---
if [[ "$SITE_URL" == "http://127.0.0.1" || "$HTTP_HOST" == "127.0.0.1" ]]; then
log "Detected local environment — disabling all HTTPS and proxy forcing."
echo "SetEnv HTTPS off" >> /etc/apache2/apache2.conf
echo "SetEnv SERVER_PORT 80" >> /etc/apache2/apache2.conf
export HTTPS=off
export SERVER_PORT=80
else
# --- Force Apache to believe it runs on HTTPS:443 globally (fixes :7860 + http redirects) ---
log "Enforcing global HTTPS canonical scheme and port"
cat <<EOF >/etc/apache2/conf-enabled/force-canonical-https.conf
# Global canonicalization fix for HuggingFace reverse proxy
UseCanonicalName Off
UseCanonicalPhysicalPort Off
ServerTokens Prod
ServerSignature Off
ServerName ${HTTP_HOST}
ServerAdmin webmaster@localhost
# Pretend Apache runs on 443 by overriding canonical name/port behavior
<IfModule mod_dir.c>
DirectorySlash On
UseCanonicalPhysicalPort Off
</IfModule>
<IfModule mod_env.c>
SetEnv HTTPS on
SetEnv SERVER_PORT 443
</IfModule>
<IfModule mod_headers.c>
RequestHeader set X-Forwarded-Proto https
RequestHeader set X-Forwarded-Port 443
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
# Ensure all self-generated redirects use https://
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{REQUEST_SCHEME} =http
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
EOF
# --- Reverse proxy environment ---
cat <<EOF >/etc/apache2/conf-enabled/remoteip-proxy.conf
<IfModule mod_remoteip.c>
RemoteIPHeader X-Forwarded-For
RemoteIPTrustedProxy 10.0.0.0/8
RemoteIPTrustedProxy 172.16.0.0/12
RemoteIPTrustedProxy 192.168.0.0/16
</IfModule>
# Force Apache to believe it's HTTPS and on port 443 for generated redirects
SetEnv HTTPS on
SetEnv SERVER_PORT 443
UseCanonicalName Off
UseCanonicalPhysicalPort Off
EOF
# --- HTTPS rewrite logic ---
cat <<'EOF' >/etc/apache2/conf-enabled/global-https-rewrite.conf
<IfModule mod_rewrite.c>
RewriteEngine On
# Force HTTPS canonical scheme and trailing slash if directory
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{REQUEST_SCHEME} =http [OR]
RewriteCond %{SERVER_PORT} !^443$
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Ensure trailing slash for directories (manual replacement of DirectorySlash)
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !/$
RewriteRule (.*[^/])$ https://%{HTTP_HOST}/$1/ [R=301,L]
</IfModule>
EOF
fi
# --- Force HTTPS early (preempt DirectorySlash before rewrite phase) ---
if [[ "$SITE_URL" == "http://127.0.0.1" || "$HTTP_HOST" == "127.0.0.1" ]]; then
log "Skipping HTTPS envvar patch (local HTTP mode)"
sed -i '/export HTTPS=on/d' /etc/apache2/envvars 2>/dev/null || true
sed -i '/export SERVER_PORT=443/d' /etc/apache2/envvars 2>/dev/null || true
echo "export HTTPS=off" >> /etc/apache2/envvars
echo "export SERVER_PORT=80" >> /etc/apache2/envvars
else
log "Hard-setting HTTPS environment defaults inside Apache envvars"
if ! grep -q "export HTTPS=on" /etc/apache2/envvars 2>/dev/null; then
cat <<'EOF' >> /etc/apache2/envvars
# Added by space-entrypoint for HuggingFace proxy
export HTTPS=on
export SERVER_PORT=443
EOF
fi
fi
# --- Globally force Apache to treat all VirtualHosts as HTTPS:443 for canonical redirects ---
# log "Forcing Apache global canonical port to 443"
# cat <<EOF >/etc/apache2/conf-enabled/force-global-canonical-port.conf
# UseCanonicalName Off
# UseCanonicalPhysicalPort Off
# # Tell Apache its canonical scheme and port
# ServerTokens Prod
# ServerSignature Off
# ServerName ${HTTP_HOST}
# ServerAdmin webmaster@localhost
# <VirtualHost *:${PORT}>
# UseCanonicalPhysicalPort Off
# RequestHeader set X-Forwarded-Proto https
# RequestHeader set X-Forwarded-Port 443
# </VirtualHost>
# EOF
# --- Manually redirect /wp-admin → /wp-admin/ to replace disabled DirectorySlash ---
# cat <<EOF >/etc/apache2/conf-enabled/fix-wp-admin-noslash.conf
# <IfModule mod_rewrite.c>
# RewriteEngine On
# RewriteCond %{REQUEST_URI} ^/wp-admin$
# RewriteRule ^/wp-admin$ /wp-admin/ [R=301,L]
# </IfModule>
# EOF
# --- Enable Apache modules needed for HTTPS proxy logic ---
a2enmod rewrite headers >/dev/null 2>&1 || true
# --- Globally enable rewrite engine early ---
cat <<'EOF' >/etc/apache2/conf-enabled/00-global-rewrite.conf
<IfModule mod_rewrite.c>
RewriteEngine On
</IfModule>
EOF
# --- Fix Apache self-redirects under reverse proxy (HuggingFace) ---
a2enmod remoteip >/dev/null 2>&1 || true
# --- Disable global DirectorySlash to prevent early HTTP redirects ---
cat <<'EOF' >/etc/apache2/conf-enabled/disable-global-dirslash.conf
<Directory "/var/www/html">
DirectorySlash Off
AllowOverride All
</Directory>
EOF
# --- Override Apache's mod_dir default to disable global DirectorySlash early ---
cat <<'EOF' >/etc/apache2/conf-enabled/00-global-noslash.conf
<IfModule mod_dir.c>
DirectorySlash Off
</IfModule>
EOF
# --- Inject canonical rewrite directly into vhost for /wp-admin ---
VHOST_CONF="/etc/apache2/sites-available/000-default-${PORT}.conf"
if ! grep -q "RewriteCond %{REQUEST_URI} ^/wp-admin$" "$VHOST_CONF"; then
log "Patching default vhost with wp-admin rewrite rule"
sed -i '/<\/VirtualHost>/i \
<IfModule mod_rewrite.c>\n\
RewriteEngine On\n\
RewriteCond %{REQUEST_URI} ^/wp-admin$\n\
RewriteRule ^/wp-admin$ /wp-admin/ [R=301,L]\n\
</IfModule>\n' "$VHOST_CONF"
fi
# --- Enforce canonical HTTPS and hide internal port ---
# cat <<EOF >/etc/apache2/conf-enabled/force-https-proxy.conf
# <IfModule mod_rewrite.c>
# RewriteEngine On
# # Redirect plain HTTP requests to HTTPS
# RewriteCond %{HTTPS} !=on
# RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# </IfModule>
# # Treat the canonical port as 443 even if Apache listens on ${PORT}
# UseCanonicalName Off
# UseCanonicalPhysicalPort Off
# # Force Apache to always assume HTTPS and canonical host
# ServerName ${HTTP_HOST}
# RequestHeader set X-Forwarded-Proto "https"
# RequestHeader set X-Forwarded-Port "443"
# EOF
echo "UseCanonicalName Off" >> /etc/apache2/apache2.conf
#echo "ServerName localhost" >> /etc/apache2/apache2.conf
echo "ServerName ${HTTP_HOST:-localhost}" >> /etc/apache2/apache2.conf
# cat <<'EOF' >/etc/apache2/conf-enabled/override-canonical-port.conf
# <IfModule mod_dir.c>
# DirectorySlash On
# </IfModule>
# UseCanonicalPhysicalPort Off
# EOF
# Disable DirectorySlash for wp-admin and rewrite cleanly to /wp-admin/
# cat <<'EOF' >/etc/apache2/conf-enabled/no-dirslash.conf
# <Directory "/var/www/html/wp-admin">
# DirectorySlash Off
# Options -Indexes
# AllowOverride All
# </Directory>
# # Force /wp-admin to redirect with HTTPS and trailing slash
# <IfModule mod_rewrite.c>
# RewriteEngine On
# RewriteCond %{REQUEST_URI} ^/wp-admin$
# RewriteRule ^/wp-admin$ https://%{HTTP_HOST}/wp-admin/ [R=301,L]
# </IfModule>
# EOF
# --- Fix /wp-admin directory handling (index + trailing slash) ---
cat <<'EOF' >/etc/apache2/conf-enabled/wp-admin-fix.conf
<Directory "/var/www/html/wp-admin">
# Ensure WordPress admin directory resolves correctly
DirectoryIndex index.php
Options -Indexes
AllowOverride All
# Re-enable DirectorySlash *only* here
<IfModule mod_dir.c>
DirectorySlash On
</IfModule>
# Explicit rewrite to /wp-admin/ if missing slash (final fallback)
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_URI} ^/wp-admin$
RewriteRule ^/wp-admin$ /wp-admin/ [R=301,L]
</IfModule>
</Directory>
EOF
# --- Ensure Apache knows the index for wp-admin to avoid autoindex 403 ---
# cat <<'EOF' >/etc/apache2/conf-enabled/wp-admin-dirindex.conf
# <Directory "/var/www/html/wp-admin">
# DirectoryIndex index.php
# Options -Indexes
# AllowOverride All
# </Directory>
# EOF
# export HTTPS=${HTTPS:-on}
# export SERVER_PORT=${SERVER_PORT:-443}
export HTTPS=$HTTPS
export SERVER_PORT=$SERVER_PORT
# add hf proxy conf that only sets env values (no syntax issues)
if [[ "$SITE_URL" != "http://127.0.0.1" && "$HTTP_HOST" != "127.0.0.1" ]]; then
cat <<'EOF' > /etc/apache2/conf-enabled/hf-proxy.conf
# Proxy environment (trusted front proxy will serve TLS)
SetEnvIf X-Forwarded-Proto https HTTPS=on
SetEnvIf X-Forwarded-Proto https SERVER_PORT=443
PassEnv HTTPS
PassEnv SERVER_PORT
EOF
else
log "Skipping hf-proxy.conf (local HTTP mode)"
fi
# === 2) Prepare WordPress paths ===
mkdir -p "$DB_DIR" "$UPLOADS_DIR"
chown -R www-data:www-data "$WP_PATH/wp-content" || true
chmod -R 775 "$WP_PATH/wp-content" || true
# === 3)
export SQLITE_ENC_PASSWORD=${SQLITE_ENC_PASSWORD:-"pzTDUd7iBJygH8zldBDw3ZzkNpe8kQ/+epSNFoaFck0l6aUjNUO5zgzi+O5EiKdq9eVjUBxhHayQ8pvd9xXd51JGK8X4LbP5zfxSIfvW3I5MazPYVwTHySV1scXcvcii"}
#SQLITE_ZIP_PASSWORD=iPgXNCzSxoSrFG41IAoNRY5/4znAJp5DUeHCV77qolyAh8EhiGsHoq/stq19R4kX
restore_sqlite_backup() {
log "Checking for existing SQLite backup on Archive.org..."
if ia metadata "${ARCHIVE_ITEM_ID}" >/dev/null 2>&1; then
log "Backup found — downloading .ht.sqlite..."
mkdir -p "$(dirname "$DB_FILE")"
ia download "${ARCHIVE_ITEM_ID}" --destdir "$(dirname "$DB_FILE")" --glob "*.zip" --no-directories || {
log "Download failed, skipping restore."
#return
exit 1
}
if [[ -f "$(dirname "$DB_FILE")/sqlite_backup.zip" ]]; then
log "Extracting SQLite backup..."
unzip -j -qo "$(dirname "$DB_FILE")/sqlite_backup.zip" -d "/tmp"
log "Decrypting SQLite Content..."
openssl enc -d -aes-256-cbc -pbkdf2 \
-in /tmp/.ht.sqlite.enc \
-out "$DB_FILE" \
-pass pass:"$SQLITE_ENC_PASSWORD"
chown www-data:www-data "$DB_FILE" || true
chmod 660 "$DB_FILE" || true
log "SQLite DB restored successfully ✅"
else
log "No valid sqlite_backup.zip found, skipping restore."
fi
else
log "No previous backup found — fresh install will proceed."
fi
}
# === 4) First-boot WP setup + SQLite plugin ===
setup_wp_sqlite() {
(
cd "$WP_PATH" || exit
# SITE_URL may be provided by HF Space secret (https://<user>-<space>.hf.space)
export SITE_URL="${SITE_URL:-}"
# If SITE_URL provided use it; otherwise default to http://127.0.0.1
if [[ -n "$SITE_URL" ]]; then
INSTALL_URL="$SITE_URL"
else
INSTALL_URL="http://127.0.0.1"
fi
# Ensure WordPress core is present
if [[ ! -f "$WP_PATH/wp-settings.php" ]]; then
if [[ -d /usr/src/wordpress && -f /usr/src/wordpress/wp-settings.php ]]; then
log "Populating WordPress core from /usr/src/wordpress"
cp -a /usr/src/wordpress/. "$WP_PATH"/
chown -R www-data:www-data "$WP_PATH"
else
log "WARNING: /usr/src/wordpress not found — falling back to wp core download"
export WP_CLI_PHP_ARGS="-d memory_limit=256M"
wp core download --allow-root --path="$WP_PATH"
fi
fi
log "WordPress core present ✅"
# Create wp-config.php if it does not exist
if [[ ! -f "$WP_PATH/wp-config.php" ]]; then
log "Generating wp-config.php"
wp config create \
--dbname="sqlite" \
--dbuser="dummy" \
--dbpass="dummy" \
--dbhost="localhost" \
--dbprefix="wp_" \
--skip-check \
--allow-root
fi
# Apply persistent SQLite wp-config patch if present
if [[ -x /usr/local/bin/wp-config-patch.sh ]]; then
log "Applying SQLite wp-config patch..."
/usr/local/bin/wp-config-patch.sh || log "Warning: wp-config patch failed (continuing)..."
fi
# Patch wp-config.php once only (legacy helper file)
# if ! grep -q "AUTOMATIC_UPDATER_DISABLED" "$WP_PATH/wp-config.php"; then
# log "Appending hardening defaults to wp-config.php"
# cat /tmp/wp-config-patches.php >> "$WP_PATH/wp-config.php" || true
# fi
# Download plugin zip directly (we need files to copy db.php drop-in)
log "Downloading SQLite plugin package"
curl -sSL https://downloads.wordpress.org/plugin/sqlite-database-integration.latest-stable.zip -o /tmp/sqlite.zip
unzip -qo /tmp/sqlite.zip -d /tmp/
rm -f /tmp/sqlite.zip
# Ensure DB exists early
if [[ ! -f "$DB_FILE" ]]; then
log "Creating SQLite DB file"
mkdir -p "$DB_DIR"
touch "$DB_FILE"
chown -R www-data:www-data "$DB_DIR"
fi
# Copy REAL db.php drop-in + helper files
DBPLUGINSRC="/tmp/sqlite-database-integration/wp-includes/sqlite"
DBPLUGINDEST="$WP_PATH/wp-content"
if [[ -f "$DBPLUGINSRC/db.php" ]]; then
log "Installing REAL SQLite drop-in and dependencies"
cp "$DBPLUGINSRC"/*.php "$DBPLUGINDEST"/
cp "$DBPLUGINSRC/db.php" "$DBPLUGINDEST/db.php"
# patch absolute path quirks (safe)
sed -i \
-e "s|dirname( __DIR__, 2 ) . '/version.php'|'/var/www/html/wp-includes/version.php'|" \
-e "s|dirname( __DIR__, 2 ) . '/constants.php'|'/tmp/sqlite-database-integration/constants.php'|" \
-e "s|require_once dirname( __DIR__, 2 ) . '/integrations/query-monitor/boot.php';|// require_once '/tmp/sqlite-database-integration/integrations/query-monitor/boot.php';|" \
"$DBPLUGINDEST/db.php"
chown -R www-data:www-data "$DBPLUGINDEST"
else
log "ERROR: db.php drop-in missing inside plugin"
fi
# Install/activate plugin via WP-CLI (ok if already active)
log "Installing SQLite Database Integration plugin"
wp plugin install sqlite-database-integration --activate --allow-root || true
log "SQLite plugin installed ✅"
# Final step: install WordPress if not already installed
if ! wp core is-installed --allow-root; then
log "👉 Performing first WordPress install (SQLite) with URL: $INSTALL_URL"
wp core install \
--url="$INSTALL_URL" \
--title="$SITE_TITLE" \
--admin_user="$ADMIN_USER" \
--admin_password="$ADMIN_PASS" \
--admin_email="$ADMIN_EMAIL" \
--skip-email \
--allow-root
else
log "WordPress already installed, skipping core install"
fi
# === activate essential plugin
log "Activating HF Sync plugin"
wp plugin activate wp-hf-sync --allow-root || true
# ===== SANITIZE siteurl/home to remove container port and ensure SITE_URL if provided =====
if [[ -n "$SITE_URL" ]]; then
CLEAN_SITE="$(echo "$SITE_URL" | sed 's:/*$::')"
log "Setting DB siteurl/home -> $CLEAN_SITE"
wp option update siteurl "$CLEAN_SITE" --allow-root || true
wp option update home "$CLEAN_SITE" --allow-root || true
else
# If siteurl ends with :7860, strip it (common in container installs)
CUR_SITE="$(wp option get siteurl --allow-root 2>/dev/null || true)"
if [[ "$CUR_SITE" =~ :7860$ ]]; then
NEW_SITE="$(echo "$CUR_SITE" | sed 's/:7860$//')"
log "Stripping :7860 from DB siteurl/home -> $NEW_SITE"
wp option update siteurl "$NEW_SITE" --allow-root || true
wp option update home "$NEW_SITE" --allow-root || true
fi
fi
)
# --- Fix ownership and permissions for wp-content after WP-CLI actions ---
log "Fixing ownership and permissions for wp-content..."
chown -R www-data:www-data "$WP_PATH/wp-content" || true
chmod -R 775 "$WP_PATH/wp-content" || true
log "SQLite setup completed ✅"
}
# === 4) First-boot WP setup + Remote MySQL/MariaDB ===
setup_wp_mysql() {
(
cd "$WP_PATH" || exit
# Remote DB credentials (expect provided via environment variables)
DB_NAME="${DB_NAME:-wordpress}"
DB_USER="${DB_USER:-avnadmin}"
DB_PASS="${DB_PASS:-YOUR_PASSWORD}"
DB_HOST="${DB_HOST:-DB_IP_OR_DOMAIN}"
DB_PORT="${DB_PORT:-3306}"
export SITE_URL="${SITE_URL:-http://127.0.0.1}"
log "Using remote DB: ${DB_USER}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
# Ensure WordPress core is present
if [[ ! -f "$WP_PATH/wp-settings.php" ]]; then
if [[ -d /usr/src/wordpress && -f /usr/src/wordpress/wp-settings.php ]]; then
log "Populating WordPress core from /usr/src/wordpress"
cp -a /usr/src/wordpress/. "$WP_PATH"/
chown -R www-data:www-data "$WP_PATH"
else
log "Downloading WordPress core (fallback)"
wp core download --allow-root --path="$WP_PATH"
fi
fi
# Generate wp-config.php (for MySQL)
if [[ ! -f "$WP_PATH/wp-config.php" ]]; then
log "Generating wp-config.php for MySQL"
wp config create \
--dbname="$DB_NAME" \
--dbuser="$DB_USER" \
--dbpass="$DB_PASS" \
--dbhost="$DB_HOST:$DB_PORT" \
--dbprefix="wp_" \
--allow-root
fi
# Optional: add SSL enforcement for Aiven
if ! grep -q "MYSQL_CLIENT_FLAGS" "$WP_PATH/wp-config.php"; then
log "Adding SSL enforcement for Aiven MySQL"
cat <<'EOC' >> "$WP_PATH/wp-config.php"
# Enforce SSL for Aiven MySQL
define('MYSQL_CLIENT_FLAGS', MYSQLI_CLIENT_SSL);
EOC
fi
# Run installation if not already installed
if ! wp core is-installed --allow-root; then
log "Installing WordPress (remote MySQL)"
wp core install \
--url="$SITE_URL" \
--title="$SITE_TITLE" \
--admin_user="$ADMIN_USER" \
--admin_password="$ADMIN_PASS" \
--admin_email="$ADMIN_EMAIL" \
--skip-email \
--allow-root
else
log "WordPress already installed, skipping core install"
fi
# Fix site URLs
log "Setting DB siteurl/home -> $SITE_URL"
wp option update siteurl "$SITE_URL" --allow-root || true
wp option update home "$SITE_URL" --allow-root || true
# Fix ownership and permissions
chown -R www-data:www-data "$WP_PATH/wp-content" || true
chmod -R 775 "$WP_PATH/wp-content" || true
log "Remote MySQL setup completed ✅"
)
}
backup_sqlite_to_archive() {
lognew "[sqlite-backup]" "ARCHIVE_ITEM_ID: $ARCHIVE_ITEM_ID"
lognew "[sqlite-backup]" "Encrypting Sqlite Content..."
openssl enc -aes-256-cbc -salt -pbkdf2 \
-in "$DB_FILE" \
-out /tmp/.ht.sqlite.enc \
-pass pass:"$SQLITE_ENC_PASSWORD"
lognew "[sqlite-backup]" "Creating compressed SQLite backup..."
mkdir -p /tmp/sqlite-backups
ZIP_PATH="/tmp/sqlite-backups/sqlite_backup.zip"
zip -j -q "$ZIP_PATH" "/tmp/.ht.sqlite.enc"
lognew "[sqlite-backup]" "Uploading backup to Archive.org..."
ia upload "${ARCHIVE_ITEM_ID}" "$ZIP_PATH" \
--metadata="collection:opensource_media" \
--metadata="mediatype:data" \
--metadata="title:WordPress SQLite ENC Backup" \
--metadata="creator:Automated HF Space" \
--retries=3 --delete --no-backup --sleep 30
lognew "[sqlite-backup]" "SQLite DB backup uploaded successfully ✅"
}
export -f backup_sqlite_to_archive
#--- Backup trggered by hook
backup_themes_and_plugins_to_hf() {
# --- Initial backup (Note: .empty will only exist for 1st time and will be removed during rsync operation)
if [[ -f /var/www/html/wp-content/uploads/hf_sync_needed ]]; then
backup_sqlite_to_archive
lognew "[wp-sync]" "Detected change — syncing to HF..."
cd /tmp/wp-store
git pull --rebase
# Sync updated wp-content back to store
rsync -aq --delete /var/www/html/wp-content/themes/ wp-content/themes/
rsync -aq --delete /var/www/html/wp-content/plugins/ wp-content/plugins/
git add .
git commit -m "Auto-sync: $(date)"
git push origin main
rm -f /var/www/html/wp-content/uploads/hf_sync_needed
lognew "[wp-sync]" "Sync completed."
cd -
else
lognew "[wp-sync]" "No Changes"
fi
}
export -f backup_themes_and_plugins_to_hf
mkdir -p "$WP_PATH/wp-content/plugins/wp-hf-sync/"
log "Creating custom plugin: wp-hf-sync.php"
cat /tmp/wp-hf-sync.php > "$WP_PATH/wp-content/plugins/wp-hf-sync/wp-hf-sync.php" || true
# Run setup
if [[ -n "$IA" ]]; then
restore_sqlite_backup
fi
setup_wp_sqlite
#setup_wp_mysql
# Exec Apache in foreground (base image behaviour)
log "Launching Apache on port ${PORT}"
# --- Ensure WordPress and Apache both believe they are on HTTPS 443 ---
# export HTTPS=on
# export SERVER_PORT=443
# Start sync loop AFTER Apache is launched
{
sleep 5
/usr/local/bin/hf-sync-loop &
/usr/local/bin/backup-loop &
} &
exec "$@"