Repository navigation
Expand file tree
/
Copy pathdocker-entrypoint.sh
More file actions
266 lines (226 loc) · 9.16 KB
/
Copy pathdocker-entrypoint.sh
File metadata and controls
266 lines (226 loc) · 9.16 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
#!/bin/bash
# docker-entrypoint.sh
set -e
# DB-Passwort ueber die Umgebung an den mysql-Client geben statt per -p auf der
# Kommandozeile, wo es fuer jeden Prozess im Container per ps sichtbar waere.
export MYSQL_PWD="${DB_PASSWORD:-syncpassword}"
# Verzeichnis ausserhalb des Webroots fuer Dateien mit Zugangsdaten
SECRETS_DIR=/etc/divera-sync
mkdir -p "$SECRETS_DIR"
# Debian trixie liefert den Client als "mariadb"; den "mysql"-Wrapper gibt es
# nur noch ueber ein Kompatibilitaetspaket. Beides unterstuetzen.
MYSQL_CLI=$(command -v mariadb || command -v mysql || true)
if [ -z "$MYSQL_CLI" ]; then
echo "❌ Kein MariaDB/MySQL-Client im Image gefunden (default-mysql-client fehlt?)"
exit 1
fi
mysql() { "$MYSQL_CLI" "$@"; }
echo "Starting Divera-Stein Sync Container..."
echo "========================================="
# Function to wait for database
wait_for_db() {
echo "⏳ Waiting for database to be ready..."
local max_attempts=30
local attempt=0
while [ $attempt -lt $max_attempts ]; do
if mysql -h"${DB_HOST:-db}" -u"${DB_USER:-syncuser}" -e "SELECT 1" &>/dev/null; then
echo "✅ Database connection successful!"
return 0
fi
attempt=$((attempt + 1))
echo " Attempt $attempt/$max_attempts - Database not ready, waiting..."
sleep 2
done
echo "❌ Database connection failed after $max_attempts attempts"
exit 1
}
# Function to check if database is initialized
check_db_initialized() {
mysql -h"${DB_HOST:-db}" -u"${DB_USER:-syncuser}" \
"${DB_NAME:-divera_stein_sync}" -e "SELECT COUNT(*) FROM system_status" &>/dev/null
return $?
}
# Function to initialize database
initialize_database() {
echo "📦 Initializing database structure..."
if [ -f /var/www/html/install.sql ]; then
echo " Found install.sql, importing..."
# First create database if it doesn't exist
mysql -h"${DB_HOST:-db}" -u"${DB_USER:-syncuser}" \
-e "CREATE DATABASE IF NOT EXISTS ${DB_NAME:-divera_stein_sync} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" 2>/dev/null || true
# Import the install.sql
if mysql -h"${DB_HOST:-db}" -u"${DB_USER:-syncuser}" \
"${DB_NAME:-divera_stein_sync}" < /var/www/html/install.sql; then
echo "✅ Database structure created successfully!"
return 0
else
echo "❌ Failed to import install.sql"
return 1
fi
else
echo "❌ install.sql not found!"
return 1
fi
}
# Wait for database
wait_for_db
# Check and initialize database if needed
echo "🔍 Checking database initialization status..."
if ! check_db_initialized; then
echo " Database not initialized, setting up..."
if initialize_database; then
echo "✅ Database initialization complete!"
else
echo "⚠️ Database initialization failed, but continuing..."
fi
else
echo "✅ Database already initialized!"
fi
# Verify database structure
echo "🔍 Verifying database structure..."
TABLES_CHECK=$(mysql -h"${DB_HOST:-db}" -u"${DB_USER:-syncuser}" \
"${DB_NAME:-divera_stein_sync}" -N -e "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='${DB_NAME:-divera_stein_sync}' AND table_name IN ('sync_log', 'sync_config', 'system_status')" 2>/dev/null || echo "0")
if [ "$TABLES_CHECK" -eq "3" ]; then
echo "✅ All required tables exist!"
else
echo "⚠️ Warning: Not all required tables exist (found $TABLES_CHECK/3)"
echo " Attempting to recreate missing tables..."
initialize_database
fi
# Create config directory if it doesn't exist
mkdir -p /var/www/html/config
# Generate PHP config file from environment variables
echo "⚙️ Generating config.php from environment variables..."
cat > /var/www/html/config/config.php << EOF
<?php
// Auto-generated config file from Docker environment variables
// Generated at: $(date)
// DO NOT EDIT - This file is regenerated on container restart
return [
'database' => [
'host' => '${DB_HOST:-db}',
'name' => '${DB_NAME:-divera_stein_sync}',
'user' => '${DB_USER:-syncuser}',
'pass' => '${DB_PASSWORD:-syncpassword}'
],
'divera' => [
'accesskey' => '${DIVERA_ACCESS_KEY:-your_divera_access_key}'
],
'stein' => [
'buname' => ${STEIN_BU_ID:-12345},
'apikey' => '${STEIN_API_KEY:-your_stein_api_key}'
],
'auth' => [
'user' => '${DASHBOARD_USER:-admin}',
'password' => '${DASHBOARD_PASSWORD:-}'
],
'sync' => [
'auto_sync_interval' => ${SYNC_INTERVAL:-300},
'log_retention_days' => ${LOG_RETENTION_DAYS:-30},
'max_retries' => ${MAX_RETRIES:-3}
],
'timezone' => '${TZ:-Europe/Berlin}'
];
EOF
echo "✅ Config file generated!"
# Validate config
if [ "${DIVERA_ACCESS_KEY}" = "your_divera_access_key" ] || [ -z "${DIVERA_ACCESS_KEY}" ]; then
echo "⚠️ WARNING: DIVERA_ACCESS_KEY not set or using default value!"
fi
if [ "${STEIN_API_KEY}" = "your_stein_api_key" ] || [ -z "${STEIN_API_KEY}" ]; then
echo "⚠️ WARNING: STEIN_API_KEY not set or using default value!"
fi
if [ -z "${DASHBOARD_PASSWORD}" ]; then
echo "⚠️ WARNING: DASHBOARD_PASSWORD not set - api.php is reachable WITHOUT authentication!"
fi
# Altlast entfernen: fruehere Versionen legten diese Datei mit allen Zugangsdaten
# im Webroot ab, wo Apache sie als Klartext auslieferte.
rm -f /var/www/html/cron-env.sh
# Also create a shell script with exports for cron environment
# (ausserhalb des Webroots, nur fuer www-data lesbar)
echo "📝 Creating cron environment file..."
cat > "$SECRETS_DIR/cron-env.sh" << EOF
#!/bin/bash
# Environment variables for cron jobs
export DB_HOST="${DB_HOST:-db}"
export DB_NAME="${DB_NAME:-divera_stein_sync}"
export DB_USER="${DB_USER:-syncuser}"
export DB_PASSWORD="${DB_PASSWORD:-syncpassword}"
export DIVERA_ACCESS_KEY="${DIVERA_ACCESS_KEY:-your_divera_access_key}"
export STEIN_BU_ID="${STEIN_BU_ID:-12345}"
export STEIN_API_KEY="${STEIN_API_KEY:-your_stein_api_key}"
export DASHBOARD_USER="${DASHBOARD_USER:-admin}"
export DASHBOARD_PASSWORD="${DASHBOARD_PASSWORD:-}"
export TZ="${TZ:-Europe/Berlin}"
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
EOF
chown www-data:www-data "$SECRETS_DIR/cron-env.sh"
chmod 0500 "$SECRETS_DIR/cron-env.sh"
# Create cron job with environment variables
echo "⏰ Setting up cron jobs..."
cat > /etc/cron.d/sync-cron << EOF
# Divera-Stein Sync Cron Job
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Run sync every 5 minutes
*/5 * * * * www-data /bin/bash -c 'source $SECRETS_DIR/cron-env.sh && /usr/local/bin/php /var/www/html/cron.php >> /var/www/html/logs/cron.log 2>&1'
# Clean old logs daily at 2 AM
0 2 * * * www-data /bin/bash -c 'source $SECRETS_DIR/cron-env.sh && /usr/local/bin/php /var/www/html/cleanup.php >> /var/www/html/logs/cleanup.log 2>&1'
# Health check every hour (mit Basic-Auth, falls DASHBOARD_PASSWORD gesetzt ist)
0 * * * * www-data /bin/bash -c 'source $SECRETS_DIR/cron-env.sh && curl -s -u "\$DASHBOARD_USER:\$DASHBOARD_PASSWORD" http://localhost/api.php?action=health >> /var/www/html/logs/health.log 2>&1'
EOF
chmod 0644 /etc/cron.d/sync-cron
# Create logs directory and files
echo "📁 Setting up log directory..."
mkdir -p /var/www/html/logs
touch /var/www/html/logs/cron.log
touch /var/www/html/logs/cleanup.log
touch /var/www/html/logs/app.log
touch /var/www/html/logs/health.log
# Set proper permissions
echo "🔐 Setting permissions..."
chown -R www-data:www-data /var/www/html
chmod -R 755 /var/www/html
chmod -R 777 /var/www/html/logs
chown www-data:www-data /var/www/html/logs/*.log
# Generierte Config mit Zugangsdaten nur fuer www-data lesbar
chmod 0400 /var/www/html/config/config.php
# Test database connection from PHP
echo "🧪 Testing PHP database connection..."
php -r "
try {
\$config = require '/var/www/html/config/config.php';
\$pdo = new PDO(
'mysql:host=' . \$config['database']['host'] . ';dbname=' . \$config['database']['name'],
\$config['database']['user'],
\$config['database']['pass']
);
echo '✅ PHP can connect to database successfully!' . PHP_EOL;
} catch (Exception \$e) {
echo '❌ PHP database connection failed: ' . \$e->getMessage() . PHP_EOL;
exit(1);
}
"
# Mark as initialized
touch /var/www/html/.initialized
# Cron wird nicht hier gestartet, sondern von supervisord (cron -f),
# siehe supervisord.conf. Ein zusaetzlicher "service cron start" wuerde
# einen zweiten Daemon erzeugen.
# Show final status
echo ""
echo "========================================="
echo "✅ Container initialization complete!"
echo "========================================="
echo "📊 Dashboard: http://localhost:${APP_PORT:-8080}"
echo "🗄️ phpMyAdmin: http://localhost:${PHPMYADMIN_PORT:-8081}"
echo "📁 Logs: /var/www/html/logs/"
echo "========================================="
echo ""
# An CMD uebergeben (supervisord startet Apache und Cron). Faellt auf
# apache2-foreground zurueck, wenn der Container ohne CMD gestartet wird.
if [ "$#" -gt 0 ]; then
echo "🌐 Starting: $*"
exec "$@"
fi
echo "🌐 Starting Apache web server..."
exec apache2-foreground