kizlo 0.20.0 → 0.20.1
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/dist/cli/wp/compose/apache-listen.conf +15 -0
- package/dist/cli/wp/compose/docker-compose.test.ts +66 -0
- package/dist/cli/wp/compose/docker-compose.yml +10 -0
- package/dist/cli/wp/compose/uploads.ini +12 -0
- package/dist/cli/wp/constants.d.ts +5 -1
- package/dist/cli/wp/constants.js +5 -1
- package/dist/package.js +1 -1
- package/dist/test.d.ts +2 -2
- package/dist/test.js +2 -2
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Kizlo local WordPress — make same-site server requests reach Apache.
|
|
2
|
+
#
|
|
3
|
+
# WordPress builds internal, server-side requests (e.g. a plugin calling its own
|
|
4
|
+
# admin_url()) against the browser-facing URL, which carries the *published* host
|
|
5
|
+
# port — say http://localhost:8890. Inside the container that request loops back to
|
|
6
|
+
# localhost:8890, but Apache only listens on 80 (Docker maps the host port to 80),
|
|
7
|
+
# so the call fails with cURL error 7 and the plugin stalls.
|
|
8
|
+
#
|
|
9
|
+
# Listening on the published port as well makes localhost:<port> resolve inside the
|
|
10
|
+
# container exactly as it does from the browser. Apache keeps its port-80 listener
|
|
11
|
+
# for Docker's port mapping and the health check; this only adds a second one.
|
|
12
|
+
#
|
|
13
|
+
# WP_PORT is passed into the wordpress service by the CLI (and defaulted in the base
|
|
14
|
+
# Compose file), so Apache expands ${WP_PORT} from the container environment.
|
|
15
|
+
Listen ${WP_PORT}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from "node:fs"
|
|
2
|
+
import { describe, expect, test } from "vitest"
|
|
3
|
+
import { parse } from "yaml"
|
|
4
|
+
import { APACHE_LISTEN_CONF, COMPOSE_FILE, UPLOADS_INI } from "../constants"
|
|
5
|
+
|
|
6
|
+
interface Service {
|
|
7
|
+
environment?: Record<string, string>
|
|
8
|
+
ports?: string[]
|
|
9
|
+
volumes?: string[]
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const wordpress = (): Service => parse(fs.readFileSync(COMPOSE_FILE, "utf8")).services.wordpress
|
|
13
|
+
|
|
14
|
+
/** Parse a `key=value` INI (comments/blank lines dropped) into a lookup. */
|
|
15
|
+
function ini(file: string): Record<string, string> {
|
|
16
|
+
const out: Record<string, string> = {}
|
|
17
|
+
for (const line of fs.readFileSync(file, "utf8").split("\n")) {
|
|
18
|
+
const trimmed = line.trim()
|
|
19
|
+
if (!trimmed || trimmed.startsWith(";")) continue
|
|
20
|
+
const eq = trimmed.indexOf("=")
|
|
21
|
+
if (eq !== -1) out[trimmed.slice(0, eq).trim()] = trimmed.slice(eq + 1).trim()
|
|
22
|
+
}
|
|
23
|
+
return out
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** PHP size shorthand (`2G`, `2100M`, `512K`) to bytes. */
|
|
27
|
+
function bytes(size: string): number {
|
|
28
|
+
const match = /^(\d+)([KMG]?)$/i.exec(size)
|
|
29
|
+
if (!match) throw new Error(`not a PHP size: ${size}`)
|
|
30
|
+
const scale = { "": 1, K: 1024, M: 1024 ** 2, G: 1024 ** 3 }[match[2]?.toUpperCase() ?? ""] ?? 1
|
|
31
|
+
return Number(match[1]) * scale
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
describe("base compose wordpress service", () => {
|
|
35
|
+
test("receives the published port so Apache can listen on it", () => {
|
|
36
|
+
// Defaulted to the same value as the port mapping so a standalone `up` still parses.
|
|
37
|
+
// The `${...}` here are literal Compose interpolation tokens, not JS templates.
|
|
38
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: literal Compose interpolation
|
|
39
|
+
expect(wordpress().environment?.WP_PORT).toBe("${WP_PORT:-8080}")
|
|
40
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: literal Compose interpolation
|
|
41
|
+
expect(wordpress().ports).toContain("${WP_PORT:-8080}:80")
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
test("mounts both local-only config assets read-only", () => {
|
|
45
|
+
const volumes = wordpress().volumes ?? []
|
|
46
|
+
expect(volumes).toContain("./uploads.ini:/usr/local/etc/php/conf.d/zz-kizlo-uploads.ini:ro")
|
|
47
|
+
expect(volumes).toContain("./apache-listen.conf:/etc/apache2/conf-enabled/zz-kizlo-listen.conf:ro")
|
|
48
|
+
})
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
describe("uploads.ini", () => {
|
|
52
|
+
test("raises the upload ceiling to 2 GB", () => {
|
|
53
|
+
expect(ini(UPLOADS_INI).upload_max_filesize).toBe("2G")
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test("allows POST overhead above the file limit for the multipart envelope", () => {
|
|
57
|
+
const values = ini(UPLOADS_INI)
|
|
58
|
+
expect(bytes(values.post_max_size ?? "")).toBeGreaterThan(bytes(values.upload_max_filesize ?? ""))
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
describe("apache-listen.conf", () => {
|
|
63
|
+
test("listens on the injected published port", () => {
|
|
64
|
+
expect(fs.readFileSync(APACHE_LISTEN_CONF, "utf8")).toMatch(/^\s*Listen\s+\$\{WP_PORT\}\s*$/m)
|
|
65
|
+
})
|
|
66
|
+
})
|
|
@@ -40,6 +40,11 @@ services:
|
|
|
40
40
|
WORDPRESS_DB_NAME: ${MYSQL_DATABASE:-wordpress}
|
|
41
41
|
WORDPRESS_DB_USER: ${MYSQL_USER:-wordpress}
|
|
42
42
|
WORDPRESS_DB_PASSWORD: ${MYSQL_PASSWORD:-wppass}
|
|
43
|
+
# Published host port, handed to Apache so `apache-listen.conf` can add a
|
|
44
|
+
# second listener on it (see that file). Defaulted here to match the port
|
|
45
|
+
# mapping above so a standalone `docker compose up` still parses the config;
|
|
46
|
+
# every path through the CLI supplies the resolved port as WP_PORT.
|
|
47
|
+
WP_PORT: ${WP_PORT:-8080}
|
|
43
48
|
# The wordpress image eval()s WORDPRESS_CONFIG_EXTRA at runtime, and Compose
|
|
44
49
|
# interpolates `$` in this file first — so every PHP variable below is written
|
|
45
50
|
# `$$` to survive Compose and reach PHP as a literal `$`.
|
|
@@ -56,6 +61,11 @@ services:
|
|
|
56
61
|
}
|
|
57
62
|
volumes:
|
|
58
63
|
- wp_data:/var/www/html
|
|
64
|
+
# Real PHP upload limits and the extra Apache listener, both shipped next to
|
|
65
|
+
# this file (relative binds resolve against the compose file's directory) and
|
|
66
|
+
# mounted read-only. In the base compose so dev and test stacks both get them.
|
|
67
|
+
- ./uploads.ini:/usr/local/etc/php/conf.d/zz-kizlo-uploads.ini:ro
|
|
68
|
+
- ./apache-listen.conf:/etc/apache2/conf-enabled/zz-kizlo-listen.conf:ro
|
|
59
69
|
healthcheck:
|
|
60
70
|
# wp-login.php always returns 200 unauthenticated; /wp-json can be gated to 401
|
|
61
71
|
# by plugins, so it's not a reliable liveness probe.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
; Kizlo local WordPress — raise PHP's upload ceiling for large imports.
|
|
2
|
+
;
|
|
3
|
+
; PHP rejects an oversized request before WordPress (or an upload plugin) ever
|
|
4
|
+
; sees it, so a WordPress hook that only changes the *displayed* limit is not
|
|
5
|
+
; enough. These are the real server limits the local stacks enforce.
|
|
6
|
+
;
|
|
7
|
+
; post_max_size is deliberately larger than upload_max_filesize: a file upload
|
|
8
|
+
; arrives as a multipart POST, so the whole request is a little bigger than the
|
|
9
|
+
; file itself. 2100M leaves headroom above the 2G (2048M) file limit for that
|
|
10
|
+
; envelope. Nothing else (memory_limit, execution time) is touched.
|
|
11
|
+
upload_max_filesize=2G
|
|
12
|
+
post_max_size=2100M
|
|
@@ -24,6 +24,10 @@ declare function kizloRelease(slug: string): string;
|
|
|
24
24
|
declare const COMPOSE_FILE: string;
|
|
25
25
|
/** PHP OPcache config, shipped alongside this module and bind-mounted into the local WordPress. */
|
|
26
26
|
declare const OPCACHE_INI: string;
|
|
27
|
+
/** PHP upload-limit config, shipped alongside this module and bind-mounted into the local WordPress. */
|
|
28
|
+
declare const UPLOADS_INI: string;
|
|
29
|
+
/** Apache extra-listener config, shipped alongside this module and bind-mounted into the local WordPress. */
|
|
30
|
+
declare const APACHE_LISTEN_CONF: string;
|
|
27
31
|
/** Linux-only entrypoint that retags www-data to the host user (see the script for why). */
|
|
28
32
|
declare const REMAP_ENTRYPOINT: string;
|
|
29
33
|
declare const CONFIG_FILES: string[];
|
|
@@ -54,4 +58,4 @@ declare const DEFAULT_PLUGINS: PluginSource[];
|
|
|
54
58
|
declare const TEST_ADMIN: Omit<TestAdminUser, "id" | "applicationPassword">;
|
|
55
59
|
declare const TEST_USER: Omit<TestUser, "id">;
|
|
56
60
|
//#endregion
|
|
57
|
-
export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease };
|
|
61
|
+
export { APACHE_LISTEN_CONF, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, UPLOADS_INI, githubRelease, kizloRelease };
|
package/dist/cli/wp/constants.js
CHANGED
|
@@ -30,6 +30,10 @@ const HERE = dirname(fileURLToPath(import.meta.url));
|
|
|
30
30
|
const COMPOSE_FILE = resolve(HERE, "compose/docker-compose.yml");
|
|
31
31
|
/** PHP OPcache config, shipped alongside this module and bind-mounted into the local WordPress. */
|
|
32
32
|
const OPCACHE_INI = resolve(HERE, "compose/opcache.ini");
|
|
33
|
+
/** PHP upload-limit config, shipped alongside this module and bind-mounted into the local WordPress. */
|
|
34
|
+
const UPLOADS_INI = resolve(HERE, "compose/uploads.ini");
|
|
35
|
+
/** Apache extra-listener config, shipped alongside this module and bind-mounted into the local WordPress. */
|
|
36
|
+
const APACHE_LISTEN_CONF = resolve(HERE, "compose/apache-listen.conf");
|
|
33
37
|
/** Linux-only entrypoint that retags www-data to the host user (see the script for why). */
|
|
34
38
|
const REMAP_ENTRYPOINT = resolve(HERE, "compose/remap-entrypoint.sh");
|
|
35
39
|
const CONFIG_FILES = [
|
|
@@ -81,4 +85,4 @@ const TEST_USER = {
|
|
|
81
85
|
};
|
|
82
86
|
|
|
83
87
|
//#endregion
|
|
84
|
-
export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease };
|
|
88
|
+
export { APACHE_LISTEN_CONF, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, UPLOADS_INI, githubRelease, kizloRelease };
|
package/dist/package.js
CHANGED
package/dist/test.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DevPluginSource, Fixture, FixtureCleanupFn, FixtureSeedFn, FixtureSettleFn, JsonValue, LocalPlugin, PluginSource, SeedContext, SettleContext, TestAdminUser, TestCredentials, TestUser, defineFixture, isLocalPlugin } from "./cli/wp/types.js";
|
|
2
|
-
import { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease } from "./cli/wp/constants.js";
|
|
2
|
+
import { APACHE_LISTEN_CONF, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, UPLOADS_INI, githubRelease, kizloRelease } from "./cli/wp/constants.js";
|
|
3
3
|
import { DockerStack, DockerStatus, RunResult, Stack, StackStatus, compose, composeDown, composePull, composeStop, composeUp, createStack, dockerAvailable, dockerHint, dockerStatus, runningProjectContainers, stackStatus, stopProjectContainers, wpCli, wpEval } from "./cli/wp/docker.js";
|
|
4
4
|
import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, isSeeded, recordedPort, resolvePluginSource, settleFixtures } from "./cli/wp/utils.js";
|
|
5
5
|
import { TestAuthAdapterUser, toTestUser } from "./test/users.js";
|
|
@@ -8,4 +8,4 @@ import { CAPTCHA_TEST_TOKEN_PASS, captchaMock } from "./test/captcha.js";
|
|
|
8
8
|
import { menuFixture } from "./menu/fixture.js";
|
|
9
9
|
import { postFixture } from "./post/fixture.js";
|
|
10
10
|
import { coreFixtures } from "./test/fixtures.js";
|
|
11
|
-
export { CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, DevPluginSource, DockerStack, DockerStatus, Fixture, FixtureCleanupFn, FixtureSeedFn, FixtureSettleFn, INTROSPECTION_META_REL, JsonValue, LOCAL_DIR_REL, LocalPlugin, OPCACHE_INI, PluginSource, REMAP_ENTRYPOINT, RunResult, SEED_MARKER_OPTION, SEED_VERSION, SeedContext, SettleContext, Stack, StackStatus, TEST_ADMIN, TEST_USER, TestAdminUser, TestAuthAdapterUser, TestCredentials, TestUser, activateLocalPlugin, captchaMock, compose, composeDown, composePull, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, dockerHint, dockerStatus, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, runningProjectContainers, settleFixtures, stackStatus, stopProjectContainers, testAuthAdapter, toTestUser, wpCli, wpEval };
|
|
11
|
+
export { APACHE_LISTEN_CONF, CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, DevPluginSource, DockerStack, DockerStatus, Fixture, FixtureCleanupFn, FixtureSeedFn, FixtureSettleFn, INTROSPECTION_META_REL, JsonValue, LOCAL_DIR_REL, LocalPlugin, OPCACHE_INI, PluginSource, REMAP_ENTRYPOINT, RunResult, SEED_MARKER_OPTION, SEED_VERSION, SeedContext, SettleContext, Stack, StackStatus, TEST_ADMIN, TEST_USER, TestAdminUser, TestAuthAdapterUser, TestCredentials, TestUser, UPLOADS_INI, activateLocalPlugin, captchaMock, compose, composeDown, composePull, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, dockerHint, dockerStatus, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, runningProjectContainers, settleFixtures, stackStatus, stopProjectContainers, testAuthAdapter, toTestUser, wpCli, wpEval };
|
package/dist/test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineFixture, isLocalPlugin } from "./cli/wp/types.js";
|
|
2
|
-
import { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease } from "./cli/wp/constants.js";
|
|
2
|
+
import { APACHE_LISTEN_CONF, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, UPLOADS_INI, githubRelease, kizloRelease } from "./cli/wp/constants.js";
|
|
3
3
|
import { compose, composeDown, composePull, composeStop, composeUp, createStack, dockerAvailable, dockerHint, dockerStatus, runningProjectContainers, stackStatus, stopProjectContainers, wpCli, wpEval } from "./cli/wp/docker.js";
|
|
4
4
|
import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, isSeeded, recordedPort, resolvePluginSource, settleFixtures } from "./cli/wp/utils.js";
|
|
5
5
|
import { testAuthAdapter } from "./test/auth.js";
|
|
@@ -9,4 +9,4 @@ import { postFixture } from "./post/fixture.js";
|
|
|
9
9
|
import { coreFixtures } from "./test/fixtures.js";
|
|
10
10
|
import { toTestUser } from "./test/users.js";
|
|
11
11
|
|
|
12
|
-
export { CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, activateLocalPlugin, captchaMock, compose, composeDown, composePull, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, dockerHint, dockerStatus, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, runningProjectContainers, settleFixtures, stackStatus, stopProjectContainers, testAuthAdapter, toTestUser, wpCli, wpEval };
|
|
12
|
+
export { APACHE_LISTEN_CONF, CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DEFAULT_WORDPRESS_TAG, INTROSPECTION_META_REL, LOCAL_DIR_REL, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, UPLOADS_INI, activateLocalPlugin, captchaMock, compose, composeDown, composePull, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, dockerHint, dockerStatus, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, runningProjectContainers, settleFixtures, stackStatus, stopProjectContainers, testAuthAdapter, toTestUser, wpCli, wpEval };
|