@styleflow.app/flowpress-deploy 1.0.0-beta.2 → 1.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/README.md +5 -0
- package/containers/cms/Dockerfile +35 -0
- package/containers/cms/Dockerfile.dockerignore +20 -0
- package/containers/cms/healthz.php +17 -0
- package/containers/cms/install-languages.sh +16 -0
- package/containers/cms/mpm.conf +10 -0
- package/containers/cms/php.ini +16 -0
- package/containers/cms/sanitize.php +37 -0
- package/containers/cms/smtp.php +13 -0
- package/containers/cms/vhost.conf +58 -0
- package/containers/cms/wp-cli.yml +1 -0
- package/containers/php-runtime/Dockerfile +21 -0
- package/containers/web-ssr/Dockerfile +25 -0
- package/containers/web-ssr/Dockerfile.dockerignore +10 -0
- package/containers/web-static/Caddyfile +40 -0
- package/containers/web-static/Dockerfile +15 -0
- package/containers/web-static/Dockerfile.dockerignore +7 -0
- package/dist/ops/bootstrap.d.ts +21 -0
- package/dist/ops/bootstrap.d.ts.map +1 -0
- package/dist/ops/bootstrap.js +106 -0
- package/dist/ops/bootstrap.js.map +1 -0
- package/dist/ops/build.d.ts +30 -0
- package/dist/ops/build.d.ts.map +1 -0
- package/dist/ops/build.js +99 -0
- package/dist/ops/build.js.map +1 -0
- package/dist/ops/cli.d.ts +3 -0
- package/dist/ops/cli.d.ts.map +1 -0
- package/dist/ops/cli.js +137 -0
- package/dist/ops/cli.js.map +1 -0
- package/dist/ops/config.d.ts +54 -0
- package/dist/ops/config.d.ts.map +1 -0
- package/dist/ops/config.js +163 -0
- package/dist/ops/config.js.map +1 -0
- package/dist/ops/coolify.d.ts +2 -0
- package/dist/ops/coolify.d.ts.map +1 -0
- package/dist/ops/coolify.js +44 -0
- package/dist/ops/coolify.js.map +1 -0
- package/dist/ops/data.d.ts +27 -0
- package/dist/ops/data.d.ts.map +1 -0
- package/dist/ops/data.js +145 -0
- package/dist/ops/data.js.map +1 -0
- package/dist/ops/deploy.d.ts +18 -0
- package/dist/ops/deploy.d.ts.map +1 -0
- package/dist/ops/deploy.js +92 -0
- package/dist/ops/deploy.js.map +1 -0
- package/dist/ops/editorial.d.ts +23 -0
- package/dist/ops/editorial.d.ts.map +1 -0
- package/dist/ops/editorial.js +79 -0
- package/dist/ops/editorial.js.map +1 -0
- package/dist/ops/environment.d.ts +29 -0
- package/dist/ops/environment.d.ts.map +1 -0
- package/dist/ops/environment.js +159 -0
- package/dist/ops/environment.js.map +1 -0
- package/dist/ops/health.d.ts +25 -0
- package/dist/ops/health.d.ts.map +1 -0
- package/dist/ops/health.js +22 -0
- package/dist/ops/health.js.map +1 -0
- package/dist/ops/monitor.d.ts +23 -0
- package/dist/ops/monitor.d.ts.map +1 -0
- package/dist/ops/monitor.js +142 -0
- package/dist/ops/monitor.js.map +1 -0
- package/dist/ops/process.d.ts +9 -0
- package/dist/ops/process.d.ts.map +1 -0
- package/dist/ops/process.js +48 -0
- package/dist/ops/process.js.map +1 -0
- package/dist/ops/provision.d.ts +38 -0
- package/dist/ops/provision.d.ts.map +1 -0
- package/dist/ops/provision.js +251 -0
- package/dist/ops/provision.js.map +1 -0
- package/dist/ops/release.d.ts +26 -0
- package/dist/ops/release.d.ts.map +1 -0
- package/dist/ops/release.js +79 -0
- package/dist/ops/release.js.map +1 -0
- package/dist/ops/s3.d.ts +8 -0
- package/dist/ops/s3.d.ts.map +1 -0
- package/dist/ops/s3.js +38 -0
- package/dist/ops/s3.js.map +1 -0
- package/dist/ops/static-config.d.ts +14 -0
- package/dist/ops/static-config.d.ts.map +1 -0
- package/dist/ops/static-config.js +96 -0
- package/dist/ops/static-config.js.map +1 -0
- package/flowpress-deploy.php +2 -2
- package/includes/automatic-build.php +22 -5
- package/package.json +26 -6
- package/schema/deployment.schema.json +45 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.4 — 2026-10-19
|
|
4
|
+
|
|
5
|
+
- Add published FlowPress Ops CLI, readable deployment manifests, shared MariaDB bindings, reusable container runtimes, isolated environment loading, immutable releases, backup verification and on-demand preview.
|
|
6
|
+
- [Canonical report](https://github.com/StyleFlow-App/styleflow-docs/blob/main/dev/rapporti/2026-10-19-piattaforma-container-flowpress.md).
|
|
7
|
+
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
- Agent rules only, no runtime or API change: `AGENTS.md` names the canonical
|
|
11
|
+
docs vault path (2026-10-18) and requires every published change to be
|
|
12
|
+
merged into `main`, with its branches, worktrees and stashes removed in the
|
|
13
|
+
same task.
|
|
14
|
+
[Canonical report](https://github.com/StyleFlow-App/styleflow-docs/blob/main/dev/rapporti/2026-10-19-branch-residui-e-regole-di-chiusura.md).
|
|
15
|
+
|
|
16
|
+
## 1.0.0-beta.3 — 2026-10-14
|
|
17
|
+
|
|
18
|
+
- Queue complete builds for term-only changes to published content, including withdrawal after a visibility change. Keep unchanged assignments idle and avoid private data in the queue.
|
|
19
|
+
- Verified public → private → public on disposable WordPress with all outbound HTTP intercepted.
|
|
20
|
+
- [Canonical integration report](https://github.com/StyleFlow-App/styleflow-docs/blob/main/dev/rapporti/2026-10-14-consolidamento-tessari.md).
|
|
21
|
+
|
|
3
22
|
## 1.0.0-beta.2 — 2026-10-14
|
|
4
23
|
|
|
5
24
|
- Automatic debounced editorial builds and public asset validation/history.
|
package/README.md
CHANGED
|
@@ -4,3 +4,8 @@ Official npm/Composer integration for FlowPress.
|
|
|
4
4
|
|
|
5
5
|
- [Canonical guide](https://github.com/StyleFlow-App/styleflow-docs/blob/main/wiki/flowpress-routing-deploy.md)
|
|
6
6
|
- [Release and verification report](https://github.com/StyleFlow-App/styleflow-docs/blob/main/dev/rapporti/2026-10-14-consolidamento-tessari.md)
|
|
7
|
+
|
|
8
|
+
- [Container platform and FlowPress Ops](https://github.com/StyleFlow-App/styleflow-docs/blob/main/wiki/piattaforma-container-flowpress.md)
|
|
9
|
+
|
|
10
|
+
The npm package also provides the flowpress-ops binary, reusable container
|
|
11
|
+
recipes and the ./ops/environment API. Run flowpress-ops --help for commands.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
# The reusable PHP runtime is built once by platform build-base.
|
|
3
|
+
ARG FLOWPRESS_PHP_IMAGE
|
|
4
|
+
FROM $FLOWPRESS_PHP_IMAGE AS build
|
|
5
|
+
USER root
|
|
6
|
+
RUN apt-get update && apt-get install -y --no-install-recommends git && rm -rf /var/lib/apt/lists/*
|
|
7
|
+
COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer
|
|
8
|
+
WORKDIR /srv/cms
|
|
9
|
+
COPY apps/cms/ ./
|
|
10
|
+
RUN --mount=type=secret,id=composer_auth,required=true \
|
|
11
|
+
--mount=type=cache,target=/root/.composer/cache \
|
|
12
|
+
COMPOSER_AUTH="$(cat /run/secrets/composer_auth)" \
|
|
13
|
+
composer install --no-dev --no-interaction --prefer-dist --optimize-autoloader --no-progress
|
|
14
|
+
COPY --from=flowpress /cms/install-languages.sh /usr/local/bin/install-languages
|
|
15
|
+
RUN sh /usr/local/bin/install-languages /srv/cms/web
|
|
16
|
+
ARG WP_CLI_VERSION=2.12.0
|
|
17
|
+
ARG WP_CLI_SHA256=ce34ddd838f7351d6759068d09793f26755463b4a4610a5a5c0a97b68220d85c
|
|
18
|
+
RUN curl -fsSL "https://github.com/wp-cli/wp-cli/releases/download/v$WP_CLI_VERSION/wp-cli-$WP_CLI_VERSION.phar" -o /wp-cli.phar \
|
|
19
|
+
&& echo "$WP_CLI_SHA256 /wp-cli.phar" | sha256sum -c - && chmod 755 /wp-cli.phar
|
|
20
|
+
FROM $FLOWPRESS_PHP_IMAGE
|
|
21
|
+
WORKDIR /srv/cms
|
|
22
|
+
COPY --from=build /srv/cms/ ./
|
|
23
|
+
COPY --from=build /wp-cli.phar /usr/local/bin/wp
|
|
24
|
+
COPY --from=flowpress /cms/wp-cli.yml /srv/cms/wp-cli.yml
|
|
25
|
+
COPY --from=flowpress /cms/healthz.php /srv/cms/web/healthz.php
|
|
26
|
+
COPY --from=flowpress /cms/smtp.php /usr/local/share/flowpress-smtp.php
|
|
27
|
+
RUN mkdir -p web/app/uploads web/app/webp-express web/app/cache web/app/upgrade \
|
|
28
|
+
&& chown -R www-data:www-data web/app/uploads web/app/webp-express web/app/cache web/app/upgrade \
|
|
29
|
+
&& echo 'auto_prepend_file=/usr/local/share/flowpress-smtp.php' > /usr/local/etc/php/conf.d/zz-smtp.ini
|
|
30
|
+
ARG RELEASE_SHA=unknown
|
|
31
|
+
ENV RELEASE_SHA=$RELEASE_SHA
|
|
32
|
+
LABEL org.opencontainers.image.revision=$RELEASE_SHA
|
|
33
|
+
USER www-data
|
|
34
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=5 CMD curl -fsS http://127.0.0.1:8080/healthz.php > /dev/null || exit 1
|
|
35
|
+
CMD ["apache2-foreground"]
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.git
|
|
2
|
+
node_modules
|
|
3
|
+
.env*
|
|
4
|
+
.secrets
|
|
5
|
+
.local
|
|
6
|
+
.styleflow
|
|
7
|
+
apps/web
|
|
8
|
+
packages
|
|
9
|
+
docs
|
|
10
|
+
apps/cms/vendor
|
|
11
|
+
apps/cms/auth.json
|
|
12
|
+
apps/cms/.env*
|
|
13
|
+
apps/cms/web/wp
|
|
14
|
+
apps/cms/web/app/plugins
|
|
15
|
+
apps/cms/web/app/uploads
|
|
16
|
+
apps/cms/web/app/webp-express
|
|
17
|
+
apps/cms/web/app/cache
|
|
18
|
+
apps/cms/web/app/upgrade
|
|
19
|
+
apps/cms/web/app/mu-plugins/flowpress-*
|
|
20
|
+
apps/cms/web/app/mu-plugins/flowpress-core
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
declare(strict_types=1);
|
|
3
|
+
header('Content-Type: application/json');
|
|
4
|
+
header('Cache-Control: no-store');
|
|
5
|
+
try {
|
|
6
|
+
define('SHORTINIT', true);
|
|
7
|
+
require __DIR__ . '/wp/wp-load.php';
|
|
8
|
+
global $wpdb;
|
|
9
|
+
$installed = $wpdb->get_var("SELECT option_value FROM {$wpdb->options} WHERE option_name = 'siteurl'");
|
|
10
|
+
if (!$installed || !is_readable(__DIR__ . '/app/mu-plugins/flowpress-core/flowpress-core.php')) {
|
|
11
|
+
throw new RuntimeException('CMS not initialized.');
|
|
12
|
+
}
|
|
13
|
+
echo json_encode(['status' => 'ok', 'environment' => getenv('APP_ENV'), 'release' => getenv('RELEASE_SHA')]);
|
|
14
|
+
} catch (Throwable $error) {
|
|
15
|
+
http_response_code(503);
|
|
16
|
+
echo json_encode(['status' => 'error', 'release' => getenv('RELEASE_SHA')]);
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Installs the Italian WordPress core translation matching the installed core.
|
|
3
|
+
# Languages are gitignored and DISALLOW_FILE_MODS blocks installing them at
|
|
4
|
+
# runtime, so they are part of the image.
|
|
5
|
+
set -eu
|
|
6
|
+
web_root="$1"
|
|
7
|
+
version="$(php -r "include '$web_root/wp/wp-includes/version.php'; echo \$wp_version;")"
|
|
8
|
+
package="$(curl -fsSL "https://api.wordpress.org/translations/core/1.0/?version=$version" \
|
|
9
|
+
| php -r '$d = json_decode(stream_get_contents(STDIN), true);
|
|
10
|
+
foreach ($d["translations"] ?? [] as $t) { if ($t["language"] === "it_IT") { echo $t["package"]; exit; } }
|
|
11
|
+
exit(1);')"
|
|
12
|
+
mkdir -p "$web_root/app/languages"
|
|
13
|
+
curl -fsSL "$package" -o /tmp/it_IT.zip
|
|
14
|
+
unzip -oq /tmp/it_IT.zip -d "$web_root/app/languages"
|
|
15
|
+
rm /tmp/it_IT.zip
|
|
16
|
+
echo "Installed it_IT core translation for WordPress $version."
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Sized for a 1536m container limit: 8 workers at up to 256M PHP memory each,
|
|
2
|
+
# typical WordPress requests use far less.
|
|
3
|
+
<IfModule mpm_prefork_module>
|
|
4
|
+
StartServers 2
|
|
5
|
+
MinSpareServers 2
|
|
6
|
+
MaxSpareServers 4
|
|
7
|
+
ServerLimit 8
|
|
8
|
+
MaxRequestWorkers 8
|
|
9
|
+
MaxConnectionsPerChild 500
|
|
10
|
+
</IfModule>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
expose_php = Off
|
|
2
|
+
display_errors = Off
|
|
3
|
+
log_errors = On
|
|
4
|
+
error_log = /proc/self/fd/2
|
|
5
|
+
memory_limit = 256M
|
|
6
|
+
upload_max_filesize = 64M
|
|
7
|
+
post_max_size = 68M
|
|
8
|
+
max_execution_time = 120
|
|
9
|
+
max_input_vars = 3000
|
|
10
|
+
session.save_path = /tmp
|
|
11
|
+
; Code is immutable inside the image: never stat files for changes.
|
|
12
|
+
opcache.enable = 1
|
|
13
|
+
opcache.validate_timestamps = 0
|
|
14
|
+
opcache.memory_consumption = 128
|
|
15
|
+
opcache.interned_strings_buffer = 16
|
|
16
|
+
opcache.max_accelerated_files = 20000
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
// Executed only against a disposable copy, never against the source.
|
|
3
|
+
declare(strict_types=1);
|
|
4
|
+
if (getenv('FLOWPRESS_RUNTIME_POLICY') !== 'container' || getenv('APP_ENV') === 'production') {
|
|
5
|
+
throw new RuntimeException('Refusing to sanitize a production database.');
|
|
6
|
+
}
|
|
7
|
+
global $wpdb;
|
|
8
|
+
foreach (get_users(['fields' => 'ID']) as $user_id) {
|
|
9
|
+
$wpdb->update($wpdb->users, ['user_pass' => wp_hash_password(wp_generate_password(64, true, true)), 'user_activation_key' => ''], ['ID' => $user_id]);
|
|
10
|
+
delete_user_meta((int) $user_id, 'session_tokens');
|
|
11
|
+
delete_user_meta((int) $user_id, '_application_passwords');
|
|
12
|
+
}
|
|
13
|
+
$plugins = get_option('active_plugins', []);
|
|
14
|
+
update_option('active_plugins', array_values(array_filter($plugins, static fn (string $plugin): bool
|
|
15
|
+
=> !preg_match('~^(advanced-media-offloader|wp-mail-smtp|wp-migrate-db-pro)/~', $plugin))));
|
|
16
|
+
foreach (['advmo_settings', 'wp_mail_smtp', 'cron'] as $option) {
|
|
17
|
+
delete_option($option);
|
|
18
|
+
}
|
|
19
|
+
update_option('home', getenv('WP_HOME'));
|
|
20
|
+
update_option('siteurl', getenv('WP_SITEURL'));
|
|
21
|
+
update_option('blog_public', '0');
|
|
22
|
+
$wpdb->query("DELETE FROM {$wpdb->options} WHERE option_name LIKE 'flowpress%queue%' OR option_name LIKE '%_transient_%'");
|
|
23
|
+
$attachments = get_posts(['post_type' => 'attachment', 'post_status' => 'any', 'numberposts' => -1, 'fields' => 'ids']);
|
|
24
|
+
foreach ($attachments as $id) {
|
|
25
|
+
$relative = get_post_meta($id, '_wp_attached_file', true);
|
|
26
|
+
if (is_string($relative) && $relative !== '' && !str_contains($relative, '..') && !str_contains($relative, '://')) {
|
|
27
|
+
$wpdb->update($wpdb->posts, ['guid' => rtrim(getenv('WP_HOME'), '/') . '/app/uploads/' . ltrim($relative, '/')], ['ID' => $id]);
|
|
28
|
+
}
|
|
29
|
+
foreach (array_keys(get_post_meta($id)) as $key) {
|
|
30
|
+
if (preg_match('/advmo|offload/i', $key)) delete_post_meta($id, $key);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
echo json_encode([
|
|
34
|
+
'tables' => count($wpdb->get_col($wpdb->prepare('SHOW TABLES LIKE %s', $wpdb->esc_like($wpdb->prefix) . '%'))),
|
|
35
|
+
'published' => (int) $wpdb->get_var("SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_status='publish'"),
|
|
36
|
+
'attachments' => count($attachments),
|
|
37
|
+
]) . "\n";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<?php
|
|
2
|
+
// Runs before Bedrock without reading any project file or persisted option.
|
|
3
|
+
if (getenv('FLOWPRESS_RUNTIME_POLICY') === 'container' && getenv('FLOWPRESS_MAIL_MODE') === 'smtp' && getenv('APP_ENV') === 'production') {
|
|
4
|
+
foreach ([
|
|
5
|
+
'WPMS_ON' => true, 'WPMS_MAILER' => 'smtp',
|
|
6
|
+
'WPMS_SMTP_HOST' => getenv('SMTP_HOST'), 'WPMS_SMTP_PORT' => (int) getenv('SMTP_PORT'),
|
|
7
|
+
'WPMS_SMTP_SSL' => getenv('SMTP_ENCRYPTION'), 'WPMS_SMTP_AUTH' => true,
|
|
8
|
+
'WPMS_SMTP_USER' => getenv('SMTP_USER'), 'WPMS_SMTP_PASS' => getenv('SMTP_PASSWORD'),
|
|
9
|
+
'WPMS_MAIL_FROM' => getenv('SMTP_FROM'), 'WPMS_MAIL_FROM_NAME' => getenv('SMTP_FROM_NAME'),
|
|
10
|
+
] as $key => $value) {
|
|
11
|
+
if (!defined($key)) define($key, $value);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Apache vhost for the container CMS. .htaccess files are ignored
|
|
2
|
+
# (AllowOverride None): every rule WordPress needs is declared here.
|
|
3
|
+
<VirtualHost *:8080>
|
|
4
|
+
ServerName localhost
|
|
5
|
+
DocumentRoot /srv/cms/web
|
|
6
|
+
|
|
7
|
+
<Directory /srv/cms/web>
|
|
8
|
+
AllowOverride None
|
|
9
|
+
Options +FollowSymLinks -Indexes
|
|
10
|
+
Require all granted
|
|
11
|
+
DirectoryIndex index.php
|
|
12
|
+
|
|
13
|
+
RewriteEngine On
|
|
14
|
+
# Application Passwords (cms:template) and Bearer callbacks need the
|
|
15
|
+
# Authorization header inside PHP.
|
|
16
|
+
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
|
|
17
|
+
RewriteRule ^index\.php$ - [L]
|
|
18
|
+
RewriteCond %{REQUEST_FILENAME} !-f
|
|
19
|
+
RewriteCond %{REQUEST_FILENAME} !-d
|
|
20
|
+
RewriteRule . /index.php [L]
|
|
21
|
+
</Directory>
|
|
22
|
+
|
|
23
|
+
# Uploaded files are data, never code.
|
|
24
|
+
<Directory /srv/cms/web/app/uploads>
|
|
25
|
+
<FilesMatch "\.(php[0-9]?|phtml|phar|pht)$">
|
|
26
|
+
Require all denied
|
|
27
|
+
</FilesMatch>
|
|
28
|
+
</Directory>
|
|
29
|
+
<FilesMatch "^\.|^(auth\.json|composer\.(json|lock)|wp-cli\.yml)$">
|
|
30
|
+
Require all denied
|
|
31
|
+
</FilesMatch>
|
|
32
|
+
<Files "xmlrpc.php">
|
|
33
|
+
Require all denied
|
|
34
|
+
</Files>
|
|
35
|
+
|
|
36
|
+
# Traefik (Docker network) sits in front; Cloudflare adds CF-Connecting-IP.
|
|
37
|
+
# Only the private proxy hop is trusted, see docs/wiki/deploy/07-sicurezza-e-accessi.md.
|
|
38
|
+
RemoteIPHeader CF-Connecting-IP
|
|
39
|
+
RemoteIPInternalProxy 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16
|
|
40
|
+
SetEnvIfNoCase X-Forwarded-Proto "^https$" HTTPS=on
|
|
41
|
+
|
|
42
|
+
<IfModule mod_expires.c>
|
|
43
|
+
ExpiresActive On
|
|
44
|
+
ExpiresByType image/webp "access plus 30 days"
|
|
45
|
+
ExpiresByType image/avif "access plus 30 days"
|
|
46
|
+
ExpiresByType image/jpeg "access plus 30 days"
|
|
47
|
+
ExpiresByType image/png "access plus 30 days"
|
|
48
|
+
ExpiresByType image/svg+xml "access plus 30 days"
|
|
49
|
+
ExpiresByType font/woff2 "access plus 1 year"
|
|
50
|
+
</IfModule>
|
|
51
|
+
|
|
52
|
+
Header always set X-Content-Type-Options "nosniff"
|
|
53
|
+
Header always set Referrer-Policy "strict-origin-when-cross-origin"
|
|
54
|
+
|
|
55
|
+
LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\" %D" container
|
|
56
|
+
ErrorLog /proc/self/fd/2
|
|
57
|
+
CustomLog /proc/self/fd/1 container
|
|
58
|
+
</VirtualHost>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
path: web/wp
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
FROM php:8.3-apache-bookworm
|
|
3
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
4
|
+
ca-certificates curl default-mysql-client libicu-dev libjpeg62-turbo-dev \
|
|
5
|
+
libpng-dev libwebp-dev libzip-dev unzip webp \
|
|
6
|
+
&& docker-php-ext-configure gd --with-jpeg --with-webp \
|
|
7
|
+
&& docker-php-ext-install exif gd intl mysqli opcache pdo_mysql zip \
|
|
8
|
+
&& a2enmod expires headers remoteip rewrite \
|
|
9
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
10
|
+
COPY cms/vhost.conf /etc/apache2/sites-available/000-default.conf
|
|
11
|
+
COPY cms/mpm.conf /etc/apache2/mods-available/mpm_prefork.conf
|
|
12
|
+
COPY cms/php.ini /usr/local/etc/php/conf.d/zz-container.ini
|
|
13
|
+
RUN sed -i 's/^Listen 80$/Listen 8080/' /etc/apache2/ports.conf \
|
|
14
|
+
&& sed -i '/Listen 443/d' /etc/apache2/ports.conf \
|
|
15
|
+
&& echo 'ServerName localhost' > /etc/apache2/conf-available/servername.conf \
|
|
16
|
+
&& a2enconf servername \
|
|
17
|
+
&& mkdir -p /tmp/apache2 \
|
|
18
|
+
&& chown www-data:www-data /tmp/apache2 \
|
|
19
|
+
&& find / -xdev -perm /6000 -type f -exec chmod a-s {} + 2>/dev/null
|
|
20
|
+
ENV APACHE_RUN_DIR=/tmp/apache2 APACHE_PID_FILE=/tmp/apache2/apache2.pid APACHE_LOCK_DIR=/tmp/apache2
|
|
21
|
+
EXPOSE 8080
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
FROM node:22-bookworm-slim AS dependencies
|
|
3
|
+
RUN corepack enable && corepack prepare pnpm@9.15.4 --activate
|
|
4
|
+
WORKDIR /workspace
|
|
5
|
+
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
|
|
6
|
+
COPY apps/web/package.json apps/web/package.json
|
|
7
|
+
COPY apps/cms/package.json apps/cms/package.json
|
|
8
|
+
COPY packages/ui packages/ui
|
|
9
|
+
ARG WEB_PACKAGE
|
|
10
|
+
RUN --mount=type=cache,target=/root/.local/share/pnpm/store pnpm --filter $WEB_PACKAGE --prod deploy /deploy
|
|
11
|
+
FROM node:22-bookworm-slim
|
|
12
|
+
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl \
|
|
13
|
+
&& rm -rf /var/lib/apt/lists/* \
|
|
14
|
+
&& find / -xdev -perm /6000 -type f -exec chmod a-s {} + 2>/dev/null
|
|
15
|
+
WORKDIR /srv/web
|
|
16
|
+
COPY --from=dependencies /deploy/node_modules ./node_modules
|
|
17
|
+
ARG DIST_DIR
|
|
18
|
+
COPY $DIST_DIR/ ./dist/
|
|
19
|
+
ARG RELEASE_SHA=unknown
|
|
20
|
+
ENV NODE_ENV=production HOST=0.0.0.0 PORT=8080 RELEASE_SHA=$RELEASE_SHA
|
|
21
|
+
LABEL org.opencontainers.image.revision=$RELEASE_SHA
|
|
22
|
+
USER node
|
|
23
|
+
EXPOSE 8080
|
|
24
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 CMD curl -fsS http://127.0.0.1:8080/healthz.json > /dev/null || exit 1
|
|
25
|
+
CMD ["node", "dist/server/entry.mjs"]
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Static production frontend. Cloudflare terminates TLS and caches at the edge;
|
|
2
|
+
# Traefik forwards plain HTTP to port 8080.
|
|
3
|
+
{
|
|
4
|
+
admin off
|
|
5
|
+
auto_https off
|
|
6
|
+
persist_config off
|
|
7
|
+
servers {
|
|
8
|
+
trusted_proxies static private_ranges
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
:8080 {
|
|
13
|
+
header X-Content-Type-Options nosniff
|
|
14
|
+
header Referrer-Policy strict-origin-when-cross-origin
|
|
15
|
+
@internal path /.container* /.flowpress* /.env* /server/*
|
|
16
|
+
respond @internal 404
|
|
17
|
+
root * /srv/site
|
|
18
|
+
encode zstd gzip
|
|
19
|
+
|
|
20
|
+
# Redirects, headers and media proxies generated from the Astro build.
|
|
21
|
+
import /srv/site/.container/routes.caddy
|
|
22
|
+
|
|
23
|
+
header /healthz.json Cache-Control "no-store"
|
|
24
|
+
header /_astro/* Cache-Control "public, max-age=31536000, immutable"
|
|
25
|
+
# HTML revalidates in browsers; Cloudflare keeps it at the edge until the
|
|
26
|
+
# deploy purge (see docs/wiki/deploy/06-cloudflare.md).
|
|
27
|
+
@html path / *.html */
|
|
28
|
+
header @html Cache-Control "public, max-age=0, must-revalidate"
|
|
29
|
+
|
|
30
|
+
file_server {
|
|
31
|
+
hide .container .flowpress-baseline.json .flowpress-fingerprint _redirects _headers _routes.json
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
handle_errors 404 {
|
|
35
|
+
header Cache-Control "no-store"
|
|
36
|
+
header CDN-Cache-Control "no-store"
|
|
37
|
+
rewrite * /404.html
|
|
38
|
+
file_server
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
FROM caddy:2.10-alpine
|
|
3
|
+
RUN apk add --no-cache libcap && setcap -r /usr/bin/caddy && apk del libcap \
|
|
4
|
+
&& find / -xdev -perm /6000 -type f -exec chmod a-s {} + 2>/dev/null
|
|
5
|
+
COPY --from=flowpress /web-static/Caddyfile /etc/caddy/Caddyfile
|
|
6
|
+
ARG DIST_DIR
|
|
7
|
+
COPY $DIST_DIR/ /srv/site/
|
|
8
|
+
RUN test -f /srv/site/.container/routes.caddy && caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile
|
|
9
|
+
ARG RELEASE_SHA=unknown
|
|
10
|
+
ENV RELEASE_SHA=$RELEASE_SHA
|
|
11
|
+
LABEL org.opencontainers.image.revision=$RELEASE_SHA
|
|
12
|
+
USER 65534:65534
|
|
13
|
+
EXPOSE 8080
|
|
14
|
+
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 CMD wget -q -O /dev/null http://127.0.0.1:8080/healthz.json || exit 1
|
|
15
|
+
CMD ["caddy", "run", "--config", "/etc/caddy/Caddyfile", "--adapter", "caddyfile"]
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function provisionRegistry(root: any, manifest: any, { file, apply }?: {
|
|
2
|
+
apply?: boolean | undefined;
|
|
3
|
+
}): Promise<{
|
|
4
|
+
changes: string[];
|
|
5
|
+
applied: boolean;
|
|
6
|
+
credentials?: undefined;
|
|
7
|
+
} | {
|
|
8
|
+
changes: string[];
|
|
9
|
+
applied: boolean;
|
|
10
|
+
credentials: string;
|
|
11
|
+
}>;
|
|
12
|
+
export function provisionDns(root: any, manifest: any, name: any, { file, apply }?: {
|
|
13
|
+
apply?: boolean | undefined;
|
|
14
|
+
}): Promise<{
|
|
15
|
+
host: string;
|
|
16
|
+
exists: boolean;
|
|
17
|
+
applied: boolean;
|
|
18
|
+
target: any;
|
|
19
|
+
frontendChanged: boolean;
|
|
20
|
+
}>;
|
|
21
|
+
//# sourceMappingURL=bootstrap.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/ops/bootstrap.js"],"names":[],"mappings":"AAIA;;;;;;;;;;GA8DC;AACD;;;;;;;;GAqBC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { identity, operatorEnvironment, platformConfig, publicPlatform, writeJson, readJson } from "./config.js";
|
|
4
|
+
export async function provisionRegistry(root, manifest, { file, apply = false } = {}) {
|
|
5
|
+
const platform = platformConfig(root, manifest, file), operator = operatorEnvironment(root);
|
|
6
|
+
const username = operator.HARBOR_ADMIN_USER, password = operator.HARBOR_ADMIN_PASSWORD;
|
|
7
|
+
if (!username || !password || !operator.HARBOR_API_URL)
|
|
8
|
+
throw new Error("Set private HARBOR_API_URL/HARBOR_ADMIN_USER/HARBOR_ADMIN_PASSWORD.");
|
|
9
|
+
const api = async (method, path, body) => {
|
|
10
|
+
const response = await fetch(operator.HARBOR_API_URL.replace(/\/$/, "") + "/api/v2.0" + path, {
|
|
11
|
+
method, redirect: "error", signal: AbortSignal.timeout(30000),
|
|
12
|
+
headers: { authorization: "Basic " + Buffer.from(username + ":" + password).toString("base64"), "content-type": "application/json" },
|
|
13
|
+
...(body ? { body: JSON.stringify(body) } : {}),
|
|
14
|
+
});
|
|
15
|
+
if (!response.ok)
|
|
16
|
+
throw new Error("Harbor " + method + " " + path + " refused (HTTP " + response.status + ").");
|
|
17
|
+
const text = await response.text();
|
|
18
|
+
return text ? JSON.parse(text) : {};
|
|
19
|
+
};
|
|
20
|
+
const projects = [platform.registryProject, "flowpress"];
|
|
21
|
+
const changes = [];
|
|
22
|
+
const existing = await api("GET", "/projects?page_size=100");
|
|
23
|
+
for (const name of projects) {
|
|
24
|
+
if (!/^[a-z0-9][a-z0-9_.-]+$/.test(name))
|
|
25
|
+
throw new Error("Invalid Harbor project.");
|
|
26
|
+
if (!existing.some(project => project.name === name)) {
|
|
27
|
+
changes.push("Create private Harbor project " + name);
|
|
28
|
+
if (apply)
|
|
29
|
+
await api("POST", "/projects", { project_name: name, public: false, storage_limit: (name === "flowpress" ? 2 : 5) * 1024 ** 3 });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (!apply)
|
|
33
|
+
return { changes, applied: false };
|
|
34
|
+
const current = await api("GET", "/projects?page_size=100");
|
|
35
|
+
const robots = await api("GET", "/robots?page_size=100");
|
|
36
|
+
const privateFile = join(root, ".secrets/registry-created.json");
|
|
37
|
+
const created = readJson(privateFile, {});
|
|
38
|
+
for (const name of projects) {
|
|
39
|
+
const project = current.find(item => item.name === name);
|
|
40
|
+
const robotName = name === "flowpress" ? "flowpress-ci" : "ci";
|
|
41
|
+
const expected = "robot$" + name + "+" + robotName;
|
|
42
|
+
if (!robots.some(robot => robot.name === expected)) {
|
|
43
|
+
const robot = await api("POST", "/robots", {
|
|
44
|
+
name: robotName, description: "FlowPress build/push for " + name, duration: 365, level: "project",
|
|
45
|
+
permissions: [{ kind: "project", namespace: name, access: [{ resource: "repository", action: "pull" }, { resource: "repository", action: "push" }] }],
|
|
46
|
+
});
|
|
47
|
+
created[name] = { name: robot.name, secret: robot.secret };
|
|
48
|
+
writeJson(privateFile, created, 0o600);
|
|
49
|
+
}
|
|
50
|
+
const metadata = await api("GET", "/projects/" + project.project_id);
|
|
51
|
+
if (!metadata.metadata?.retention_id)
|
|
52
|
+
await api("POST", "/retentions", {
|
|
53
|
+
algorithm: "or", scope: { level: "project", ref: project.project_id },
|
|
54
|
+
trigger: { kind: "Schedule", settings: { cron: "0 0 1 * * *" } },
|
|
55
|
+
rules: [
|
|
56
|
+
{ id: 0, priority: 0, disabled: false, action: "retain", template: "always", tag_selectors: [{ kind: "doublestar", decoration: "matches", pattern: "{staging,production,preview,latest}" }], scope_selectors: { repository: [{ kind: "doublestar", decoration: "repoMatches", pattern: "**" }] } },
|
|
57
|
+
{ id: 0, priority: 0, disabled: false, action: "retain", template: "latestPushedK", params: { latestPushedK: 3 }, tag_selectors: [{ kind: "doublestar", decoration: "matches", pattern: "**" }], scope_selectors: { repository: [{ kind: "doublestar", decoration: "repoMatches", pattern: "**" }] } },
|
|
58
|
+
],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
// Add pull scope without replacing permissions belonging to existing installations.
|
|
62
|
+
const nodes = robots.find(robot => robot.name === "robot$nodes-pull");
|
|
63
|
+
if (!nodes)
|
|
64
|
+
throw new Error("The existing nodes-pull robot was not found.");
|
|
65
|
+
const detail = await api("GET", "/robots/" + nodes.id);
|
|
66
|
+
let changed = false;
|
|
67
|
+
for (const name of projects)
|
|
68
|
+
if (!detail.permissions.some(permission => permission.namespace === name)) {
|
|
69
|
+
detail.permissions.push({ kind: "project", namespace: name, access: [{ resource: "repository", action: "pull" }] });
|
|
70
|
+
changed = true;
|
|
71
|
+
}
|
|
72
|
+
if (changed)
|
|
73
|
+
await api("PUT", "/robots/" + nodes.id, { name: detail.name, description: detail.description, duration: detail.duration, disable: detail.disable, permissions: detail.permissions });
|
|
74
|
+
if (Object.keys(created).length)
|
|
75
|
+
writeJson(privateFile, created, 0o600);
|
|
76
|
+
return { changes, applied: true, credentials: Object.keys(created).length ? ".secrets/registry-created.json" : "existing" };
|
|
77
|
+
}
|
|
78
|
+
export async function provisionDns(root, manifest, name, { file, apply = false } = {}) {
|
|
79
|
+
const target = manifest.environments[name];
|
|
80
|
+
if (!target?.publish.includes("cms"))
|
|
81
|
+
throw new Error("CMS publication is disabled.");
|
|
82
|
+
const platform = platformConfig(root, manifest, file), operator = operatorEnvironment(root);
|
|
83
|
+
const { coolifyClient } = await import("./coolify.js");
|
|
84
|
+
const server = await coolifyClient(platform.coolifyUrl, operator.COOLIFY_TOKEN)("GET", "/servers/" + platform.serverUuid);
|
|
85
|
+
const host = new URL(target.backendUrl).hostname;
|
|
86
|
+
const api = async (method, path, body) => {
|
|
87
|
+
const res = await fetch("https://api.cloudflare.com/client/v4" + path, { method, redirect: "error", signal: AbortSignal.timeout(30000), headers: { authorization: "Bearer " + operator.CLOUDFLARE_API_TOKEN, "content-type": "application/json" }, ...(body ? { body: JSON.stringify(body) } : {}) });
|
|
88
|
+
const data = await res.json();
|
|
89
|
+
if (!res.ok || !data.success)
|
|
90
|
+
throw new Error("DNS API refused " + method + " (HTTP " + res.status + ").");
|
|
91
|
+
return data.result;
|
|
92
|
+
};
|
|
93
|
+
let zone;
|
|
94
|
+
const labels = host.split(".");
|
|
95
|
+
for (let offset = 0; offset < labels.length - 1 && !zone; offset++)
|
|
96
|
+
zone = (await api("GET", "/zones?name=" + labels.slice(offset).join(".")))[0];
|
|
97
|
+
if (!zone)
|
|
98
|
+
throw new Error("No accessible DNS zone for the staging backend.");
|
|
99
|
+
const existing = await api("GET", "/zones/" + zone.id + "/dns_records?name=" + host);
|
|
100
|
+
if (existing.length && !existing.some(item => item.type === "A" && item.content === server.ip))
|
|
101
|
+
throw new Error("An existing DNS record has a different target; no record was changed.");
|
|
102
|
+
if (!existing.length && apply)
|
|
103
|
+
await api("POST", "/zones/" + zone.id + "/dns_records", { type: "A", name: host, content: server.ip, proxied: true, ttl: 1, comment: "FlowPress staging backend" });
|
|
104
|
+
return { host, exists: Boolean(existing.length), applied: apply, target: server.ip, frontendChanged: false };
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=bootstrap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/ops/bootstrap.js"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export function registryLogin(platform: any, operator: any): void;
|
|
2
|
+
export function inspectDigest(image: any): any;
|
|
3
|
+
export function buildBase(root: any, platform: any, { push }?: {
|
|
4
|
+
push?: boolean | undefined;
|
|
5
|
+
}): {
|
|
6
|
+
image: string;
|
|
7
|
+
};
|
|
8
|
+
export function frontendBuild(root: any, manifest: any, name: any, { sha, buildId }: {
|
|
9
|
+
sha: any;
|
|
10
|
+
buildId: any;
|
|
11
|
+
}): {
|
|
12
|
+
env: any;
|
|
13
|
+
dist: any;
|
|
14
|
+
};
|
|
15
|
+
export function build(root: any, manifest: any, name: any, component: any, { sha, buildId, push, file, skipFrontend }?: {
|
|
16
|
+
push?: boolean | undefined;
|
|
17
|
+
skipFrontend?: boolean | undefined;
|
|
18
|
+
}): {
|
|
19
|
+
component: any;
|
|
20
|
+
environment: any;
|
|
21
|
+
repository: string;
|
|
22
|
+
tag: string;
|
|
23
|
+
digest: any;
|
|
24
|
+
sha: any;
|
|
25
|
+
buildId: any;
|
|
26
|
+
pushed: boolean;
|
|
27
|
+
};
|
|
28
|
+
export const packageRoot: string;
|
|
29
|
+
export const containers: string;
|
|
30
|
+
//# sourceMappingURL=build.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../../src/ops/build.js"],"names":[],"mappings":"AAUA,kEAGC;AACD,+CAKC;AACD;;;;EAMC;AACD;;;;;;EAqBC;AACD;;;;;;;;;;;;EAqCC;AA9ED,iCAA6E;AAC7E,gCAA0D"}
|