-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-entrypoint.sh
More file actions
274 lines (242 loc) · 12.3 KB
/
Copy pathdocker-entrypoint.sh
File metadata and controls
274 lines (242 loc) · 12.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
#!/bin/bash
# WordPress Docker Entrypoint Script
#
# This script runs on container startup and handles:
# 1. Waiting for MariaDB and Redis to be ready
# 2. Downloading WordPress core files (first run)
# 3. Creating wp-config.php with proper settings
# 4. Updating configuration on container restarts/migrations
# 5. Setting up HTTPS detection for reverse proxy environments
# 6. Managing file permissions
#
# Environment variables required:
# - SERVICE_USER_WORDPRESS: Database username
# - SERVICE_PASSWORD_WORDPRESS: Database password
# - SERVICE_PASSWORD_REDIS: Redis password
# - DISABLE_WP_CRON: (optional) Disable WP cron
#
set -e
echo "=== WordPress Container Startup ==="
# ============================================================================
# Wait for dependent services to be ready
# ============================================================================
echo "Waiting for MariaDB..."
until mysqladmin ping -h"mariadb" -u"${SERVICE_USER_WORDPRESS}" -p"${SERVICE_PASSWORD_WORDPRESS}" --silent 2>/dev/null; do
echo -n "."
sleep 1
done
echo " Connected!"
echo "Waiting for Redis..."
REDIS_PASS="${SERVICE_PASSWORD_REDIS:-${REDIS_PASSWORD}}"
until redis-cli -h redis -a "${REDIS_PASS}" ping > /dev/null 2>&1; do
echo -n "."
sleep 1
done
echo " Connected!"
# ============================================================================
# Download WordPress core (first run only)
# ============================================================================
if [ ! -f "/var/www/html/index.php" ]; then
echo "Downloading WordPress..."
wp core download --allow-root
fi
# ============================================================================
# Create wp-config.php (first run only)
# Sets memory limits, action scheduler, and reverse proxy HTTPS detection
# ============================================================================
if [ ! -f "/var/www/html/wp-config.php" ]; then
echo "Creating wp-config.php..."
wp config create \
--dbname="${WORDPRESS_DB_NAME:-wordpress}" \
--dbuser="${SERVICE_USER_WORDPRESS}" \
--dbpass="${SERVICE_PASSWORD_WORDPRESS}" \
--dbhost="mariadb" \
--skip-check \
--allow-root
# Memory limits for typical WordPress sites
wp config set WP_MEMORY_LIMIT '384M' --type=constant --allow-root
wp config set WP_MAX_MEMORY_LIMIT '512M' --type=constant --allow-root
# Action Scheduler tuning (used by WooCommerce, plugins for background tasks)
wp config set ACTION_SCHEDULER_MAX_EXECUTION_TIME 300 --type=constant --raw --allow-root
wp config set ACTION_SCHEDULER_BATCH_SIZE 10 --type=constant --raw --allow-root
# HTTPS detection for Coolify/Traefik/Cloudflare reverse proxies
# Without this, WordPress admin cookies and redirects break behind HTTPS proxies
cat >> /var/www/html/wp-config.php <<'WPCONFIG'
// Enhanced HTTPS detection for reverse proxy environments
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
if (isset($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] === 'on') {
$_SERVER['HTTPS'] = 'on';
}
if (isset($_SERVER['HTTP_CF_VISITOR'])) {
$cf_visitor = json_decode($_SERVER['HTTP_CF_VISITOR'], true);
if (isset($cf_visitor['scheme']) && $cf_visitor['scheme'] === 'https') {
$_SERVER['HTTPS'] = 'on';
}
}
WPCONFIG
if [ "${DISABLE_WP_CRON}" = "true" ]; then
wp config set DISABLE_WP_CRON true --type=constant --raw --allow-root
fi
# ============================================================================
# Update existing wp-config.php (container restart/migration)
# Updates database credentials, Redis config, and ensures proper settings
# Includes automatic migration detection from Apache to Nginx
# ============================================================================
else
echo "Updating configuration..."
# ========================================================================
# MIGRATION DETECTION: Check if this is a migration from apache-stable
# ========================================================================
MIGRATION_DETECTED=false
# Check if Redis object cache exists but igbinary setting is missing
if [ -f "/var/www/html/wp-content/object-cache.php" ]; then
if ! wp config has WP_REDIS_IGBINARY --allow-root 2>/dev/null || \
[ "$(wp config get WP_REDIS_IGBINARY --allow-root 2>/dev/null)" != "true" ]; then
MIGRATION_DETECTED=true
else
echo "Container already configured for nginx-stable (no migration needed)"
fi
fi
if [ "$MIGRATION_DETECTED" = "true" ]; then
echo ""
echo "========================================="
echo "MIGRATION DETECTED: Apache → Nginx"
echo "========================================="
echo "Performing automatic migration tasks..."
echo ""
# Check if required environment variables are set
if [ -z "$SERVICE_USER_WORDPRESS" ] || [ -z "$SERVICE_PASSWORD_WORDPRESS" ]; then
echo "⚠️ WARNING: Missing required environment variables!"
echo ""
echo "Please set these variables in Coolify:"
echo " - SERVICE_USER_WORDPRESS (database username)"
echo " - SERVICE_PASSWORD_WORDPRESS (database password)"
echo " - SERVICE_PASSWORD_ROOT (database root password)"
echo " - SERVICE_PASSWORD_REDIS (Redis password)"
echo ""
echo "Migration will continue but may fail without proper credentials."
echo "========================================="
echo ""
sleep 5
fi
# Step 1: Disable object cache to prevent corruption during migration
echo "→ Disabling Redis object cache temporarily..."
wp redis disable --allow-root 2>/dev/null || true
# Step 2: Flush Redis to remove corrupted serialized data
echo "→ Flushing Redis cache..."
REDIS_PASS="${SERVICE_PASSWORD_REDIS:-${REDIS_PASSWORD}}"
if [ -n "$REDIS_PASS" ]; then
redis-cli -h redis -a "$REDIS_PASS" FLUSHDB >/dev/null 2>&1 || echo " (Redis flush skipped - not critical)"
fi
# Step 3: Clear WordPress file caches
echo "→ Clearing WordPress file caches..."
find /var/www/html/wp-content/cache/* -maxdepth 0 -type d ! -name 'matomo' -exec rm -rf {} + 2>/dev/null || true
rm -rf /var/www/html/wp-content/uploads/cache/* 2>/dev/null || true
echo "→ Migration tasks completed!"
echo "========================================="
echo ""
fi
# ========================================================================
# Update database credentials
# ========================================================================
wp config set DB_NAME "${WORDPRESS_DB_NAME:-wordpress}" --allow-root 2>/dev/null || true
wp config set DB_USER "${SERVICE_USER_WORDPRESS}" --allow-root 2>/dev/null || true
wp config set DB_PASSWORD "${SERVICE_PASSWORD_WORDPRESS}" --allow-root 2>/dev/null || true
wp config set DB_HOST "mariadb" --allow-root 2>/dev/null || true
# ========================================================================
# Configure Redis if object cache drop-in is present
# (installed via Redis Object Cache plugin)
# ========================================================================
if [ -f "/var/www/html/wp-content/object-cache.php" ]; then
echo "Configuring Redis object cache..."
wp config set WP_REDIS_HOST redis --type=constant --allow-root 2>/dev/null || true
wp config set WP_REDIS_PORT 6379 --type=constant --raw --allow-root 2>/dev/null || true
wp config set WP_REDIS_PASSWORD "${SERVICE_PASSWORD_REDIS:-${REDIS_PASSWORD}}" --type=constant --allow-root 2>/dev/null || true
wp config set WP_REDIS_TIMEOUT 1 --type=constant --raw --allow-root 2>/dev/null || true
wp config set WP_REDIS_READ_TIMEOUT 1 --type=constant --raw --allow-root 2>/dev/null || true
wp config set WP_REDIS_DATABASE 0 --type=constant --raw --allow-root 2>/dev/null || true
# CRITICAL: Enable igbinary serialization for compatibility
# This must match the Redis extension configuration
wp config set WP_REDIS_IGBINARY true --type=constant --raw --allow-root 2>/dev/null || true
wp config set WP_CACHE true --type=constant --raw --allow-root 2>/dev/null || true
# Re-enable object cache after migration if it was disabled
if [ "$MIGRATION_DETECTED" = "true" ]; then
echo "→ Re-enabling Redis object cache with new configuration..."
wp redis enable --allow-root 2>/dev/null || echo " (Object cache already enabled)"
fi
fi
if ! wp config has WP_MAX_MEMORY_LIMIT --allow-root 2>/dev/null; then
wp config set WP_MAX_MEMORY_LIMIT '512M' --type=constant --allow-root
fi
# SSL Admin enforcement
# Only enable if we can prove the site is behind HTTPS
# Otherwise causes redirect loops and authentication failures
if ! wp config has FORCE_SSL_ADMIN --allow-root 2>/dev/null; then
if [ "${SERVICE_URL_WORDPRESS#https://}" != "${SERVICE_URL_WORDPRESS}" ] || [ "${HTTP_X_FORWARDED_PROTO}" = "https" ]; then
wp config set FORCE_SSL_ADMIN true --type=constant --raw --allow-root
fi
fi
# Ensure debug mode is off in production
wp config set WP_DEBUG false --type=constant --raw --allow-root 2>/dev/null || true
wp config set WP_DEBUG_LOG false --type=constant --raw --allow-root 2>/dev/null || true
wp config set WP_DEBUG_DISPLAY false --type=constant --raw --allow-root 2>/dev/null || true
# Add HTTPS detection code if not already present
if ! grep -q "HTTP_X_FORWARDED_PROTO" /var/www/html/wp-config.php 2>/dev/null; then
sed -i "/That's all, stop editing/i\\
// Enhanced HTTPS detection for reverse proxy environments\\
if (isset(\$_SERVER['HTTP_X_FORWARDED_PROTO']) && \$_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {\\
\$_SERVER['HTTPS'] = 'on';\\
}\\
if (isset(\$_SERVER['HTTP_X_FORWARDED_SSL']) && \$_SERVER['HTTP_X_FORWARDED_SSL'] === 'on') {\\
\$_SERVER['HTTPS'] = 'on';\\
}\\
if (isset(\$_SERVER['HTTP_CF_VISITOR'])) {\\
\$cf_visitor = json_decode(\$_SERVER['HTTP_CF_VISITOR'], true);\\
if (isset(\$cf_visitor['scheme']) && \$cf_visitor['scheme'] === 'https') {\\
\$_SERVER['HTTPS'] = 'on';\\
}\\
}\\
" /var/www/html/wp-config.php
fi
# Auto-migrate HTTP URLs to HTTPS if site is installed
# Prevents mixed content warnings after SSL setup
if wp core is-installed --allow-root 2>/dev/null; then
SITE_URL=$(wp option get siteurl --allow-root 2>/dev/null || echo "")
if [[ "$SITE_URL" == http://* ]]; then
HTTPS_URL=${SITE_URL/http:/https:}
wp option update siteurl "$HTTPS_URL" --allow-root
wp option update home "$HTTPS_URL" --allow-root
fi
fi
fi
# ============================================================================
# Display installation message if WordPress not yet installed
# ============================================================================
if ! wp core is-installed --allow-root 2>/dev/null; then
echo ""
echo "========================================="
echo "WordPress is ready for installation!"
echo "========================================="
echo "Visit /wp-admin/install.php to complete"
echo "the installation using the GUI installer."
echo "========================================="
echo ""
fi
# ============================================================================
# Set file permissions (first run only)
# Volume permissions persist, so we only do this once
# Note: nginx blocks PHP execution in uploads directory via config
# ============================================================================
if [ ! -f "/var/www/html/.permissions-set" ]; then
echo "Setting file permissions (first run)..."
chown -R www-data:www-data /var/www/html 2>/dev/null || true
if [ -d "/var/www/html/wp-content" ]; then
find /var/www/html/wp-content -type d -exec chmod 755 {} + 2>/dev/null || true
find /var/www/html/wp-content -type f -exec chmod 644 {} + 2>/dev/null || true
fi
touch /var/www/html/.permissions-set
fi
echo "=== Startup complete ==="
exec "$@"