feat: Implement Docker-based deployment for ClinicPro on Coolify
- Added Dockerfile for multi-stage build including PHP, Node.js, and Nginx. - Created docker-compose.coolify.yaml for service orchestration with app, workers, MariaDB, and Redis. - Introduced entrypoint.sh for initialization tasks like JWT key generation and database migrations. - Configured Nginx with default.conf for handling requests and routing to PHP-FPM. - Added php.ini with production settings and opcache configuration. - Set up supervisord.conf to manage PHP-FPM and Nginx processes. - Created frontend-domains.json for managing allowed frontend domains. - Added gen-cors-env.php script to generate CORS environment variables from frontend domains. - Updated framework.yaml to configure trusted proxies and headers. - Created .dockerignore to exclude unnecessary files from the Docker context. - Added .env.coolify.example for environment variable configuration. - Documented deployment steps and troubleshooting in coolify.md.
This commit is contained in:
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
/**
|
||||
* Generates the multi-domain env values for Coolify from docker/frontend-domains.json.
|
||||
*
|
||||
* Usage:
|
||||
* php docker/gen-cors-env.php
|
||||
*
|
||||
* Output: CORS_ALLOW_ORIGIN (single regex, explicit alternation) and
|
||||
* ALLOWED_FRONTEND_HOSTS (comma-separated host list).
|
||||
* Paste both into the Coolify Environment Variables tab.
|
||||
*/
|
||||
|
||||
$jsonFile = __DIR__ . '/frontend-domains.json';
|
||||
if (!is_file($jsonFile)) {
|
||||
fwrite(STDERR, "Missing $jsonFile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
try {
|
||||
$data = json_decode(file_get_contents($jsonFile), true, 512, JSON_THROW_ON_ERROR);
|
||||
} catch (JsonException $e) {
|
||||
fwrite(STDERR, "Invalid JSON in $jsonFile: {$e->getMessage()}\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!isset($data['domains']) || !is_array($data['domains'])) {
|
||||
fwrite(STDERR, "Expected a \"domains\" array in $jsonFile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$domains = [];
|
||||
foreach ($data['domains'] as $entry) {
|
||||
$host = is_array($entry) ? ($entry['domain'] ?? null) : $entry;
|
||||
$host = is_string($host) ? trim($host) : '';
|
||||
if ($host === '') {
|
||||
continue;
|
||||
}
|
||||
if (!preg_match('/^[a-z0-9.-]+$/i', $host)) {
|
||||
fwrite(STDERR, "Skipping invalid domain: \"$host\"\n");
|
||||
continue;
|
||||
}
|
||||
$domains[strtolower($host)] = true; // dedupe, case-insensitive
|
||||
}
|
||||
$domains = array_keys($domains);
|
||||
sort($domains);
|
||||
|
||||
if (empty($domains)) {
|
||||
fwrite(STDERR, "No valid domains found in $jsonFile\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// CORS: explicit alternation, anchored, dots escaped. https only.
|
||||
$alternation = implode('|', array_map(static fn (string $d): string => preg_quote($d, '/'), $domains));
|
||||
$cors = "^https://($alternation)$";
|
||||
|
||||
// Frontend hosts: bare hostnames, comma-separated (matched via in_array in PaymentController).
|
||||
$hosts = implode(',', $domains);
|
||||
|
||||
echo "# ---- paste into Coolify env (" . count($domains) . " domains) ----\n\n";
|
||||
echo "CORS_ALLOW_ORIGIN='" . $cors . "'\n\n";
|
||||
echo "ALLOWED_FRONTEND_HOSTS=" . $hosts . "\n";
|
||||
Reference in New Issue
Block a user