nextpress-core 2.1.1 → 3.0.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.
Files changed (122) hide show
  1. package/cli/index.js +11 -0
  2. package/cli/meta.js +5 -0
  3. package/cli/np-down.js +10 -0
  4. package/cli/np-install.js +35 -0
  5. package/cli/np-log.js +12 -0
  6. package/cli/np-run-dev.js +34 -0
  7. package/cli/np-run-start.js +33 -0
  8. package/cli/np-run.js +10 -0
  9. package/cli/run-command.js +23 -0
  10. package/cli/start-composer.js +39 -0
  11. package/lib/container-lib/NextJS.Dockerfile +47 -0
  12. package/lib/container-lib/docker-compose.dev.yml +69 -0
  13. package/lib/container-lib/docker-compose.prod.yml +23 -0
  14. package/lib/container-lib/docker-compose.yml +161 -0
  15. package/lib/container-lib/mail.dev.ini +3 -0
  16. package/lib/container-lib/mail.prod.ini +3 -0
  17. package/lib/container-lib/nginx.conf +71 -0
  18. package/lib/container-lib/uploads.ini +3 -0
  19. package/lib/wp-lib/src/acf/acf.php +10 -0
  20. package/lib/wp-lib/src/acf/acf_add_options.php +18 -0
  21. package/lib/wp-lib/src/acf/load_acf_fields.php +34 -0
  22. package/lib/wp-lib/src/api/nextpress_get_admin_bar.php +260 -0
  23. package/lib/wp-lib/src/api/nextpress_validate_user_session.php +114 -0
  24. package/lib/wp-lib/src/index.php +26 -0
  25. package/lib/wp-lib/src/nextpress_dev_mailer_setup.php +17 -0
  26. package/lib/wp-lib/src/nextpress_disable_core_depency_updates.php +55 -0
  27. package/lib/wp-lib/src/nextpress_remove_comments.php +17 -0
  28. package/lib/wp-lib/src/nextpress_remove_menu_pages.php +32 -0
  29. package/lib/wp-lib/src/nextpress_revalidate_frontend.php +57 -0
  30. package/lib/wp-lib/src/nextpress_save_path.php +150 -0
  31. package/lib/wp-lib/src/theme.php +31 -0
  32. package/package.json +15 -10
  33. package/cli/install.js +0 -27
  34. /package/lib/{acf-functions → nextjs-lib/acf-functions}/core/acf-builder.ts +0 -0
  35. /package/lib/{acf-functions → nextjs-lib/acf-functions}/core/acf-component-autoloader.ts +0 -0
  36. /package/lib/{acf-functions → nextjs-lib/acf-functions}/core/acf-field-group-autoloader.ts +0 -0
  37. /package/lib/{acf-functions → nextjs-lib/acf-functions}/services/define-field-group.ts +0 -0
  38. /package/lib/{acf-functions → nextjs-lib/acf-functions}/services/define-layout.ts +0 -0
  39. /package/lib/{acf-functions → nextjs-lib/acf-functions}/services/map-fields/helpers/map-choice-object.ts +0 -0
  40. /package/lib/{acf-functions → nextjs-lib/acf-functions}/services/map-fields/map-fields.ts +0 -0
  41. /package/lib/{acf-functions → nextjs-lib/acf-functions}/types/acf-field-group.ts +0 -0
  42. /package/lib/{acf-functions → nextjs-lib/acf-functions}/types/acf-field.ts +0 -0
  43. /package/lib/{acf-functions → nextjs-lib/acf-functions}/types/acf-layout.ts +0 -0
  44. /package/lib/{acf-functions → nextjs-lib/acf-functions}/types/acf-values.ts +0 -0
  45. /package/lib/{acf-functions → nextjs-lib/acf-functions}/types/components/field-props.ts +0 -0
  46. /package/lib/{acf-functions → nextjs-lib/acf-functions}/types/components/nextpress-component.ts +0 -0
  47. /package/lib/{ambient.d.ts → nextjs-lib/ambient.d.ts} +0 -0
  48. /package/lib/{entities → nextjs-lib/entities}/common.ts +0 -0
  49. /package/lib/{entities → nextjs-lib/entities}/option/option.interface.ts +0 -0
  50. /package/lib/{entities → nextjs-lib/entities}/option/option.ts +0 -0
  51. /package/lib/{entities → nextjs-lib/entities}/post/post.interface.ts +0 -0
  52. /package/lib/{entities → nextjs-lib/entities}/post/post.ts +0 -0
  53. /package/lib/{entities → nextjs-lib/entities}/term/term.interface.ts +0 -0
  54. /package/lib/{entities → nextjs-lib/entities}/term/term.ts +0 -0
  55. /package/lib/{entities → nextjs-lib/entities}/user/user.interface.ts +0 -0
  56. /package/lib/{entities → nextjs-lib/entities}/user/user.ts +0 -0
  57. /package/lib/{globals → nextjs-lib/globals}/entity-loader/entity-loader-base.ts +0 -0
  58. /package/lib/{globals → nextjs-lib/globals}/entity-loader/entity-loader.ts +0 -0
  59. /package/lib/{globals → nextjs-lib/globals}/entity-loader/option-loader.ts +0 -0
  60. /package/lib/{globals → nextjs-lib/globals}/entity-loader/post-loader.ts +0 -0
  61. /package/lib/{globals → nextjs-lib/globals}/entity-loader/term-loader.ts +0 -0
  62. /package/lib/{globals → nextjs-lib/globals}/entity-loader/user-loader.ts +0 -0
  63. /package/lib/{globals → nextjs-lib/globals}/get-field/get-field.ts +0 -0
  64. /package/lib/{globals → nextjs-lib/globals}/globals.ts +0 -0
  65. /package/lib/{globals → nextjs-lib/globals}/nextpress-config/nextpress-config.interface.ts +0 -0
  66. /package/lib/{globals → nextjs-lib/globals}/nextpress-config/nextpress-config.ts +0 -0
  67. /package/lib/{globals → nextjs-lib/globals}/queried-object/queried-object.ts +0 -0
  68. /package/lib/{repository → nextjs-lib/repository}/optionquery/option-query-args.ts +0 -0
  69. /package/lib/{repository → nextjs-lib/repository}/optionquery/option-query.ts +0 -0
  70. /package/lib/{repository → nextjs-lib/repository}/postquery/post-query-args.ts +0 -0
  71. /package/lib/{repository → nextjs-lib/repository}/postquery/post-query.ts +0 -0
  72. /package/lib/{repository → nextjs-lib/repository}/termquery/term-query-args.ts +0 -0
  73. /package/lib/{repository → nextjs-lib/repository}/termquery/term-query.ts +0 -0
  74. /package/lib/{repository → nextjs-lib/repository}/userquery/user-query-args.ts +0 -0
  75. /package/lib/{repository → nextjs-lib/repository}/userquery/user-query.ts +0 -0
  76. /package/lib/{router → nextjs-lib/router}/helpers.ts +0 -0
  77. /package/lib/{router → nextjs-lib/router}/nextpress-layout.tsx +0 -0
  78. /package/lib/{router → nextjs-lib/router}/nextpress-not-found-route.tsx +0 -0
  79. /package/lib/{router → nextjs-lib/router}/nextpress-proxy.ts +0 -0
  80. /package/lib/{router → nextjs-lib/router}/nextpress-static-params.ts +0 -0
  81. /package/lib/{router → nextjs-lib/router}/router.tsx +0 -0
  82. /package/lib/{router → nextjs-lib/router}/routes/api/api-get-admin-bar.ts +0 -0
  83. /package/lib/{router → nextjs-lib/router}/routes/api/api-get-draft-mode.ts +0 -0
  84. /package/lib/{router → nextjs-lib/router}/routes/api/api-get-field-groups.ts +0 -0
  85. /package/lib/{router → nextjs-lib/router}/routes/api/api-post-revalidate.ts +0 -0
  86. /package/lib/{router → nextjs-lib/router}/routes/api/helpers.ts +0 -0
  87. /package/lib/{router → nextjs-lib/router}/routes/author-archive.tsx +0 -0
  88. /package/lib/{router → nextjs-lib/router}/routes/post-index-page.tsx +0 -0
  89. /package/lib/{router → nextjs-lib/router}/routes/singular-page.tsx +0 -0
  90. /package/lib/{router → nextjs-lib/router}/routes/site-front-page.tsx +0 -0
  91. /package/lib/{router → nextjs-lib/router}/routes/term-archive.tsx +0 -0
  92. /package/lib/{router → nextjs-lib/router}/types.ts +0 -0
  93. /package/lib/{services → nextjs-lib/services}/get-menu.ts +0 -0
  94. /package/lib/{services → nextjs-lib/services}/get-theme-mods.ts +0 -0
  95. /package/lib/{services → nextjs-lib/services}/metadata/get-blogname.ts +0 -0
  96. /package/lib/{services → nextjs-lib/services}/metadata/get-favicon-url.ts +0 -0
  97. /package/lib/{services → nextjs-lib/services}/metadata/get-language-attribute.ts +0 -0
  98. /package/lib/{services → nextjs-lib/services}/utilities/capitalise-first-letter.ts +0 -0
  99. /package/lib/{services → nextjs-lib/services}/utilities/esc-html.ts +0 -0
  100. /package/lib/{services → nextjs-lib/services}/utilities/get-date-time-formatter.ts +0 -0
  101. /package/lib/{services → nextjs-lib/services}/utilities/kses-post.ts +0 -0
  102. /package/lib/{services → nextjs-lib/services}/utilities/process-url.ts +0 -0
  103. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/_autoloader/template-autoloader.ts +0 -0
  104. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/archive/archive.tsx +0 -0
  105. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/archive/author.tsx +0 -0
  106. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/archive/category.tsx +0 -0
  107. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/archive/posttypearchive.tsx +0 -0
  108. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/archive/tag.tsx +0 -0
  109. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/archive/taxonomy.tsx +0 -0
  110. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/home/home.tsx +0 -0
  111. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/index.tsx +0 -0
  112. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/not-found.tsx/not-found.tsx +0 -0
  113. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/page/page.tsx +0 -0
  114. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/page/posttype.tsx +0 -0
  115. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/page/single.tsx +0 -0
  116. /package/lib/{template-heirarchy → nextjs-lib/template-heirarchy}/page/singular.tsx +0 -0
  117. /package/lib/{ui → nextjs-lib/ui}/render-attachment-image.tsx +0 -0
  118. /package/lib/{ui → nextjs-lib/ui}/render-components.tsx +0 -0
  119. /package/lib/{ui → nextjs-lib/ui}/render-the-admin-bar.tsx +0 -0
  120. /package/lib/{ui → nextjs-lib/ui}/render-the-logo.tsx +0 -0
  121. /package/lib/{wpdb → nextjs-lib/wpdb}/wpdb.interface.ts +0 -0
  122. /package/lib/{wpdb → nextjs-lib/wpdb}/wpdb.ts +0 -0
package/cli/index.js ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ const program = new Command();
4
+
5
+ program
6
+ .name('np')
7
+ .command('install', 'Install Nextpress')
8
+ .command('run', 'Run Nextpress')
9
+ .command('down', 'Terminate Nextpress')
10
+ .command('log', 'Log Nextpress in production')
11
+ .parse(process.argv);
package/cli/meta.js ADDED
@@ -0,0 +1,5 @@
1
+ import path from 'path';
2
+ import { fileURLToPath } from 'url';
3
+
4
+ export const __filename = fileURLToPath(import.meta.url);
5
+ export const __dirname = path.dirname(__filename);
package/cli/np-down.js ADDED
@@ -0,0 +1,10 @@
1
+ import path from 'path';
2
+ import { runCommand } from './run-command.js';
3
+ import { containerLibPath } from './start-composer.js';
4
+
5
+ await runCommand('docker', [
6
+ 'compose',
7
+ '--project-directory', process.cwd(),
8
+ '-f', path.join(containerLibPath, 'docker-compose.yml'),
9
+ 'down'
10
+ ]);
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from 'fs';
4
+ import path from 'path';
5
+ import { __dirname } from './meta.js';
6
+
7
+ function write(sourceDir, destDir) {
8
+ try {
9
+ if (!fs.existsSync(sourceDir)) {
10
+ console.error(`Error: Source folder does not exist at ${sourceDir}`);
11
+ process.exit(1);
12
+ }
13
+
14
+ if (fs.existsSync(destDir)) {
15
+ fs.rmSync(destDir, { recursive: true, force: true });
16
+ }
17
+
18
+ fs.cpSync(sourceDir, destDir, { recursive: true });
19
+ } catch (err) {
20
+ console.error('Error:', err.message);
21
+ process.exit(1);
22
+ }
23
+ }
24
+
25
+ // Copy nextjs library
26
+ write(
27
+ path.join(__dirname, '..', 'lib', 'nextjs-lib'),
28
+ path.join(process.cwd(), 'next-js', '.nextpress')
29
+ )
30
+
31
+ // Copy wordpress library
32
+ write(
33
+ path.join(__dirname, '..', 'lib', 'wp-lib', 'src'),
34
+ path.join(process.cwd(), 'wp', 'wp-content', 'themes', 'nextpress_theme', '.nextpress')
35
+ )
package/cli/np-log.js ADDED
@@ -0,0 +1,12 @@
1
+ import path from 'path';
2
+ import { runCommand } from './run-command.js';
3
+ import { containerLibPath } from './start-composer.js';
4
+
5
+ await runCommand('docker', [
6
+ 'compose',
7
+ '--project-directory', process.cwd(),
8
+ '-f', path.join(containerLibPath, 'docker-compose.yml'),
9
+ 'logs',
10
+ '-f',
11
+ '--tail=100'
12
+ ]);
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+
3
+ import path from 'path';
4
+ import { runCommand } from './run-command.js';
5
+ import { startComposer, containerLibPath } from './start-composer.js';
6
+
7
+ const composeBaseArgs = [
8
+ 'compose',
9
+ '--project-directory', process.cwd(),
10
+ '--env-file', path.join(process.cwd(), '.env'),
11
+ '-f', path.join(containerLibPath, 'docker-compose.yml'),
12
+ '-f', path.join(process.cwd(), 'docker-compose.extend.yml'),
13
+ '-f', path.join(containerLibPath, 'docker-compose.dev.yml'),
14
+ '-f', path.join(process.cwd(), 'docker-compose.dev.extend.yml'),
15
+ ]
16
+
17
+ async function startDev() {
18
+ await startComposer(composeBaseArgs,
19
+ async () => {
20
+ console.log('Running Nextpress in development mode');
21
+ const dockerArgs = [
22
+ ...composeBaseArgs,
23
+ 'up',
24
+ '--watch',
25
+ '--build',
26
+ '--menu=0',
27
+ 'next-js', 'wordpress', 'ready-check',
28
+ ];
29
+ await runCommand('docker', dockerArgs);
30
+ }
31
+ );
32
+ }
33
+
34
+ await startDev();
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env node
2
+
3
+ import path from 'path';
4
+ import { runCommand } from './run-command.js';
5
+ import { startComposer, containerLibPath } from './start-composer.js';
6
+
7
+ const composeBaseArgs = [
8
+ 'compose',
9
+ '--project-directory', process.cwd(),
10
+ '--env-file', path.join(process.cwd(), '.env'),
11
+ '-f', path.join(containerLibPath, 'docker-compose.yml'),
12
+ '-f', path.join(process.cwd(), 'docker-compose.extend.yml'),
13
+ '-f', path.join(containerLibPath, 'docker-compose.prod.yml'),
14
+ '-f', path.join(process.cwd(), 'docker-compose.prod.extend.yml'),
15
+ ]
16
+
17
+ async function start() {
18
+ await startComposer(composeBaseArgs,
19
+ async () => {
20
+ console.log('Running Nextpress in production mode');
21
+ const dockerArgs = [
22
+ ...composeBaseArgs,
23
+ 'up',
24
+ '--build',
25
+ '--detach',
26
+ ];
27
+ await runCommand('docker', dockerArgs);
28
+ console.log('\nNextpress services detached and running in background. Run npx np log to stream logs or npx np down to terminate the process');
29
+ }
30
+ );
31
+ }
32
+
33
+ await start();
package/cli/np-run.js ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ const program = new Command();
4
+
5
+ program
6
+ .name('np run')
7
+ .command('dev', 'Run Nextpress in development mode')
8
+ .command('start', 'Run Nextpress in production mode')
9
+ .parse(process.argv);
10
+
@@ -0,0 +1,23 @@
1
+ import { spawn } from 'child_process';
2
+
3
+ export const runCommand = (command, args) => {
4
+ return new Promise((resolve, reject) => {
5
+ const child = spawn(command, args, {
6
+ stdio: 'inherit'
7
+ });
8
+
9
+ child.on('exit', (code, signal) => {
10
+ if (code === 0) {
11
+ resolve();
12
+ }
13
+ else if (command === 'docker' && args.includes('down')) {
14
+ resolve();
15
+ }
16
+ else {
17
+ reject(new Error(`Command "${command} ${args.join(' ')}" failed with code ${code} / signal ${signal}`));
18
+ }
19
+ });
20
+
21
+ child.on('error', (err) => reject(err));
22
+ });
23
+ };
@@ -0,0 +1,39 @@
1
+ import path from 'path';
2
+ import { __dirname } from './meta.js';
3
+ import { runCommand } from './run-command.js';
4
+
5
+ export const containerLibPath = path.join(__dirname, '..', 'lib', 'container-lib');
6
+
7
+ export async function startComposer(composerArgs, callback) {
8
+ let isCleaningUp = false;
9
+
10
+ const cleanup = async () => {
11
+ if (isCleaningUp) return;
12
+ isCleaningUp = true;
13
+
14
+ console.log('\nStopping Nextpress services...\n');
15
+ try {
16
+ await runCommand('docker', [...composerArgs, 'down']);
17
+ console.log('\nNextpress services stopped successfully.');
18
+ } catch (err) {
19
+ console.error(`Error during cleanup: ${err.message}`);
20
+ }
21
+ process.exit(0);
22
+ };
23
+
24
+ process.on('SIGINT', cleanup);
25
+ process.on('SIGTERM', cleanup);
26
+
27
+ try {
28
+ console.log('Installing Next.js dependencies...');
29
+ await runCommand('npm', ['install', '--prefix', path.join(process.cwd(), 'next-js'), '--silent']);
30
+
31
+ console.log('Installing/Validating Nextpress...');
32
+ await runCommand('npx', ['np', 'install']);
33
+
34
+ await callback();
35
+ } catch (error) {
36
+ console.error(`Setup stopped: ${error.message}`);
37
+ await cleanup();
38
+ }
39
+ }
@@ -0,0 +1,47 @@
1
+ FROM node:24-alpine AS base
2
+ RUN apk add --no-cache libc6-compat
3
+ WORKDIR /app
4
+
5
+ ENV NEXT_TELEMETRY_DISABLED 1
6
+
7
+ FROM base AS deps
8
+ COPY package*.json ./
9
+ RUN npm ci
10
+
11
+ FROM base AS builder
12
+ ARG WP_SERVICE_URL
13
+ ENV WP_SERVICE_URL=$WP_SERVICE_URL
14
+
15
+ COPY --from=deps /app/node_modules ./node_modules
16
+ COPY . .
17
+ RUN npm run compile
18
+
19
+ # --- Final Production Stage ---
20
+ FROM base AS production
21
+ ENV NODE_ENV production
22
+
23
+ RUN addgroup --system --gid 1001 nodejs && \
24
+ adduser --system --uid 1001 nextjs
25
+
26
+ RUN chown nextjs:nodejs /app
27
+
28
+ COPY --from=deps --chown=nextjs:nodejs /app/node_modules ./node_modules
29
+ COPY --from=builder --chown=nextjs:nodejs /app ./
30
+
31
+ USER nextjs
32
+
33
+ ENV HOSTNAME "0.0.0.0"
34
+
35
+ EXPOSE 3000
36
+ ENV PORT 3000
37
+
38
+ CMD npm run generate && npm run start
39
+
40
+ # --- Final Development Stage ---
41
+ FROM base AS development
42
+ ENV NODE_ENV=development
43
+
44
+ COPY --from=deps /app/node_modules ./node_modules
45
+ COPY . .
46
+ EXPOSE 3000
47
+ CMD ["npm", "run", "dev"]
@@ -0,0 +1,69 @@
1
+ services:
2
+ wordpress:
3
+ command: >
4
+ sh -c "
5
+ # Check if Xdebug is already compiled. If not, install it quietly.
6
+ if [ ! -f /usr/local/lib/php/extensions/*/xdebug.so ]; then
7
+ pecl install xdebug > /dev/null && docker-php-ext-enable xdebug;
8
+ fi;
9
+
10
+ echo 'ServerName localhost' >> /etc/apache2/apache2.conf;
11
+ docker-entrypoint.sh apache2-foreground;
12
+ "
13
+ volumes:
14
+ - ./node_modules/nextpress-core/lib/container-lib/mail.dev.ini:/usr/local/etc/php/conf.d/mail.ini:ro
15
+ environment:
16
+ XDEBUG_MODE: debug
17
+ XDEBUG_SESSION: 1
18
+ XDEBUG_TRIGGER: 1
19
+ XDEBUG_CONFIG: "client_host=host.docker.internal client_port=9003 start_with_request=yes log_level=0"
20
+ WORDPRESS_DEBUG: true
21
+ extra_hosts:
22
+ - "host.docker.internal:host-gateway"
23
+ next-js:
24
+ build:
25
+ target: development
26
+ develop:
27
+ watch:
28
+ - action: rebuild
29
+ path: ./next-js/package.json
30
+ - action: sync
31
+ path: ./next-js
32
+ target: /app
33
+ ignore:
34
+ - node_modules/
35
+ - .next/
36
+ - src/lib/nextpress/types/wpdb/
37
+ - package.json
38
+ mailpit:
39
+ image: axllent/mailpit:latest
40
+ depends_on:
41
+ wordpress:
42
+ condition: service_healthy
43
+ environment:
44
+ - MP_WEBROOT=/mailpit-admin/
45
+ - MP_API_CORS=http://localhost:8080
46
+ restart: always
47
+ ports:
48
+ - "8025:8025"
49
+ - "1025:1025"
50
+ gateway:
51
+ depends_on:
52
+ mailpit:
53
+ condition: service_started
54
+ ready-check:
55
+ command: >
56
+ sh -c '
57
+ printf "\n"
58
+ printf "\033[92m===============================================\n"
59
+ printf "\033[92mDEPLOYMENT SUCCESSFUL\033[0m\n"
60
+ printf "\033[92mOpen site: ${WP_SITE_URL}\033[0m\n"
61
+ printf "\033[92mWP Admin: ${WP_SITE_URL}/wp-admin\033[0m\n"
62
+ printf "\033[92mDB Admin: ${WP_SITE_URL}/db-admin\033[0m\n"
63
+ printf "\033[92mMailpit Admin: ${WP_SITE_URL}/mailpit-admin\033[0m\n"
64
+ printf "\033[92m===============================================\033[0m\n"
65
+ printf "\033[92mDEVELOPMENT ENVIRONMENT ACTIVE\033[0m\n"
66
+ printf "\033[92mWatching for changes in next-js\033[0m\n"
67
+ printf "\033[92m===============================================\033[0m\n"
68
+ printf "\n"
69
+ '
@@ -0,0 +1,23 @@
1
+ services:
2
+ wordpress:
3
+ command: sh -c "echo 'ServerName localhost' >> /etc/apache2/apache2.conf && docker-entrypoint.sh apache2-foreground"
4
+ volumes:
5
+ - ./node_modules/nextpress-core/lib/container-lib/mail.prod.ini:/usr/local/etc/php/conf.d/mail.ini:ro
6
+ environment:
7
+ WORDPRESS_DEBUG: true
8
+ next-js:
9
+ build:
10
+ target: production
11
+ ready-check:
12
+ command: >
13
+ sh -c '
14
+ printf "\n"
15
+ printf "\033[92m===============================================\n"
16
+ printf "\033[92mDEPLOYMENT SUCCESSFUL\033[0m\n"
17
+ printf "\033[92mOpen site: ${WP_SITE_URL}\033[0m\n"
18
+ printf "\033[92mWP Admin: ${WP_SITE_URL}/wp-admin\033[0m\n"
19
+ printf "\033[92mDB Admin: ${WP_SITE_URL}/db-admin\033[0m\n"
20
+ printf "\033[92m===============================================\033[0m\n"
21
+ printf "\n"
22
+ '
23
+
@@ -0,0 +1,161 @@
1
+ services:
2
+ db:
3
+ image: mysql:8.0
4
+ restart: always
5
+ command: --max-connections=200
6
+ volumes:
7
+ - db:/var/lib/mysql
8
+ environment:
9
+ MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
10
+ MYSQL_DATABASE: ${MYSQL_DATABASE}
11
+ healthcheck:
12
+ test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$${MYSQL_ROOT_PASSWORD}"]
13
+ interval: 30s
14
+ timeout: 5s
15
+ retries: 5
16
+ start_period: 15s
17
+
18
+ adminer:
19
+ image: adminer:latest
20
+ depends_on:
21
+ db:
22
+ condition: service_healthy
23
+ ports:
24
+ - "8000:80"
25
+ wordpress:
26
+ image: wordpress:6.9.4-php8.4
27
+ depends_on:
28
+ db:
29
+ condition: service_healthy
30
+ extra_hosts:
31
+ - "host.docker.internal:host-gateway"
32
+ volumes:
33
+ - ./wp:/var/www/html
34
+ - ./node_modules/nextpress-core/lib/container-lib/uploads.ini:/usr/local/etc/php/conf.d/uploads.ini
35
+ environment:
36
+ WORDPRESS_DB_HOST: db
37
+ WORDPRESS_DB_USER: root
38
+ WORDPRESS_DB_PASSWORD: ${MYSQL_ROOT_PASSWORD}
39
+ WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
40
+ NEXTJS_SERVICE_URL: http://next-js:3000
41
+ CROSS_CONTAINER_API_KEY: ${CROSS_CONTAINER_API_KEY}
42
+ WORDPRESS_ADMIN_USERNAME: ${WP_ADMIN_USER}
43
+ WORDPRESS_ADMIN_PASSWORD: ${WP_ADMIN_PASSWORD}
44
+ WORDPRESS_ADMIN_EMAIL: ${WP_ADMIN_EMAIL}
45
+ healthcheck:
46
+ test: ["CMD-SHELL", "php -r 'echo (file_get_contents(\"wp-login.php\") !== false ? 0 : 1);'"]
47
+ interval: 30s
48
+ timeout: 5s
49
+ retries: 5
50
+ start_period: 15s
51
+
52
+ wp-cli:
53
+ image: wordpress:cli-php8.4
54
+ tty: true
55
+ user: "33:33"
56
+ depends_on:
57
+ db:
58
+ condition: service_healthy
59
+ wordpress:
60
+ condition: service_healthy
61
+ volumes:
62
+ - ./wp:/var/www/html
63
+ environment:
64
+ WORDPRESS_DB_HOST: db
65
+ WORDPRESS_DB_USER: root
66
+ WORDPRESS_DB_PASSWORD: ${MYSQL_ROOT_PASSWORD}
67
+ WORDPRESS_DB_NAME: ${MYSQL_DATABASE}
68
+ WORDPRESS_ADMIN_USERNAME: ${WP_ADMIN_USER}
69
+ WORDPRESS_ADMIN_PASSWORD: ${WP_ADMIN_PASSWORD}
70
+ WORDPRESS_ADMIN_EMAIL: ${WP_ADMIN_EMAIL}
71
+ command: >
72
+ /bin/sh -c '
73
+ while [ ! -f /var/www/html/wp-config.php ]; do sleep 2; done;
74
+
75
+ if ! wp core is-installed --path="/var/www/html"; then
76
+ wp core install --path="/var/www/html" --url="${WP_SITE_URL}" --title="${WP_SITE_TITLE}" --admin_user="${WP_ADMIN_USER}" --admin_password="${WP_ADMIN_PASSWORD}" --admin_email="${WP_ADMIN_EMAIL}" --skip-email;
77
+ fi;
78
+
79
+ wp option update siteurl "${WP_SITE_URL}" --path="/var/www/html";
80
+ wp option update home "${WP_SITE_URL}" --path="/var/www/html";
81
+
82
+ wp plugin delete akismet hello --path="/var/www/html" 2>/dev/null;
83
+ wp theme delete twentytwentythree twentytwentyfour twentytwentyfive --path="/var/www/html" 2>/dev/null;
84
+
85
+ wp rewrite structure "/%postname%/" --path="/var/www/html" --hard;
86
+ wp rewrite flush --path="/var/www/html" --hard;
87
+
88
+ if ! wp plugin is-active secure-custom-fields --path="/var/www/html" 2>/dev/null; then
89
+ wp plugin install secure-custom-fields --version=6.8.5 --activate --path="/var/www/html";
90
+ fi;
91
+
92
+ if ! wp plugin is-active svg-support --path="/var/www/html" 2>/dev/null; then
93
+ wp plugin install svg-support --version=2.5.16 --activate --path="/var/www/html";
94
+ fi;
95
+
96
+ wp theme activate nextpress_theme --path="/var/www/html";
97
+ '
98
+
99
+ next-js:
100
+ depends_on:
101
+ db:
102
+ condition: service_healthy
103
+ wordpress:
104
+ condition: service_healthy
105
+ wp-cli:
106
+ condition: service_completed_successfully
107
+ build:
108
+ context: ./next-js
109
+ dockerfile: ../node_modules/nextpress-core/lib/container-lib/NextJS.Dockerfile
110
+ args:
111
+ - WP_SERVICE_URL=http://wordpress:80
112
+ working_dir: /app
113
+ environment:
114
+ MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
115
+ MYSQL_DATABASE: ${MYSQL_DATABASE}
116
+ DATABASE_URL: mysql://root:${MYSQL_ROOT_PASSWORD}@db:3306/${MYSQL_DATABASE}
117
+ WP_SERVICE_URL: http://wordpress:80
118
+ WP_SITE_URL: ${WP_SITE_URL}
119
+ CROSS_CONTAINER_API_KEY: ${CROSS_CONTAINER_API_KEY}
120
+ healthcheck:
121
+ test: ["CMD-SHELL", "wget --spider -q http://0.0.0.0:3000 || exit 1"]
122
+ interval: 30s
123
+ timeout: 5s
124
+ retries: 10
125
+ start_period: 15s
126
+
127
+ gateway:
128
+ image: nginx:alpine
129
+ depends_on:
130
+ db:
131
+ condition: service_healthy
132
+ adminer:
133
+ condition: service_started
134
+ wordpress:
135
+ condition: service_healthy
136
+ wp-cli:
137
+ condition: service_completed_successfully
138
+ next-js:
139
+ condition: service_healthy
140
+ ports:
141
+ - "8080:80"
142
+ volumes:
143
+ - ./node_modules/nextpress-core/lib/container-lib/nginx.conf:/etc/nginx/conf.d/default.conf:ro
144
+ - ./nginx.extend.conf:/etc/nginx/snippets/extend.conf:ro
145
+ healthcheck:
146
+ test: ["CMD-SHELL", "pgrep nginx || exit 1"]
147
+ interval: 30s
148
+ timeout: 5s
149
+ retries: 5
150
+ start_period: 15s
151
+
152
+ ready-check:
153
+ image: alpine
154
+ depends_on:
155
+ gateway:
156
+ condition: service_healthy
157
+ environment:
158
+ - NODE_ENV=${NODE_ENV:-development}
159
+
160
+ volumes:
161
+ db:
@@ -0,0 +1,3 @@
1
+ ; Redirect native PHP mail to the host machine's SMTP port
2
+ SMTP = host.docker.internal
3
+ smtp_port = 1025
@@ -0,0 +1,3 @@
1
+ ; Redirect native PHP mail to the host machine's SMTP port
2
+ SMTP = host.docker.internal
3
+ smtp_port = 25
@@ -0,0 +1,71 @@
1
+ server {
2
+ listen 80;
3
+ access_log off;
4
+ client_max_body_size 256M;
5
+
6
+ include /etc/nginx/snippets/extend.conf*;
7
+
8
+ # Route WordPress Backend and Core Assets
9
+ location ~* ^/(wp-admin|wp-login\.php|wp-content|wp-includes|wp-json) {
10
+ proxy_pass http://wordpress:80;
11
+ proxy_set_header Host $http_host;
12
+ proxy_set_header X-Forwarded-Host $http_host;
13
+
14
+ proxy_set_header X-Real-IP $remote_addr;
15
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
16
+ proxy_set_header X-Forwarded-Proto $scheme;
17
+ }
18
+
19
+ # Route everything else to the Next.JS app
20
+ location / {
21
+ proxy_pass http://next-js:3000;
22
+ proxy_set_header Host $http_host;
23
+ proxy_set_header X-Forwarded-Host $http_host;
24
+ proxy_set_header X-Real-IP $remote_addr;
25
+ }
26
+
27
+ # Route Next.JS websockets
28
+ location /_next/webpack-hmr {
29
+ proxy_pass http://next-js:3000/_next/webpack-hmr;
30
+ proxy_http_version 1.1;
31
+ proxy_set_header Upgrade $http_upgrade;
32
+ proxy_set_header Connection "upgrade";
33
+ }
34
+
35
+ # Route Adminer Database Manager
36
+ location /db-admin {
37
+ proxy_pass http://adminer:8080;
38
+ proxy_set_header Host $http_host;
39
+ proxy_set_header X-Forwarded-Host $http_host;
40
+
41
+ proxy_set_header X-Real-IP $remote_addr;
42
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
43
+ proxy_set_header X-Forwarded-Proto $scheme;
44
+ }
45
+
46
+ location = /mailpit-admin {
47
+ return 301 $scheme://$http_host/mailpit-admin/;
48
+ }
49
+
50
+ location /mailpit-admin/ {
51
+ resolver 127.0.0.11 valid=30s;
52
+ set $mailpit_host "mailpit";
53
+
54
+ proxy_pass http://$mailpit_host:8025;
55
+
56
+ proxy_hide_header Content-Security-Policy;
57
+ add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' 'unsafe-eval'";
58
+
59
+ proxy_set_header Host $host;
60
+ proxy_set_header X-Real-IP $remote_addr;
61
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
62
+ proxy_set_header X-Forwarded-Proto $scheme;
63
+
64
+ # WebSockets (Crucial for Mailpit dashboard updates)
65
+ proxy_http_version 1.1;
66
+ proxy_set_header Upgrade $http_upgrade;
67
+ proxy_set_header Connection "upgrade";
68
+
69
+ proxy_buffering off;
70
+ }
71
+ }
@@ -0,0 +1,3 @@
1
+ upload_max_filesize = 256M
2
+ post_max_size = 128M
3
+ memory_limit = 256M
@@ -0,0 +1,10 @@
1
+ <?php
2
+
3
+ namespace Nextpress\ACF;
4
+
5
+ require_once __DIR__ . '/load_acf_fields.php';
6
+ require_once __DIR__ . '/acf_add_options.php';
7
+
8
+ add_filter('acf/settings/show_admin', '__return_false');
9
+ add_action('acf/init', fn() => load_acf_fields_from_api());
10
+ add_action('acf/init', fn() => acf_add_options());
@@ -0,0 +1,18 @@
1
+ <?php
2
+
3
+ namespace Nextpress\ACF;
4
+
5
+ /**
6
+ * Registers a custom global ACF options page for App Options.
7
+ *
8
+ * @return void
9
+ */
10
+ function acf_add_options(): void {
11
+ \acf_add_options_page([
12
+ 'page_title' => "App Options",
13
+ 'menu_title' => "App Options",
14
+ 'menu_slug' => "app_options",
15
+ 'capability' => "manage_options",
16
+ 'redirect' => false,
17
+ ]);
18
+ }
@@ -0,0 +1,34 @@
1
+ <?php
2
+
3
+ namespace Nextpress\ACF;
4
+
5
+ /**
6
+ * Loads ACF field groups remotely from the fronend API service.
7
+ *
8
+ * @return void
9
+ */
10
+
11
+ function load_acf_fields_from_api(): void {
12
+ $nextjs_service_url = getenv_docker('NEXTJS_SERVICE_URL', '');
13
+ $api_key = getenv_docker('CROSS_CONTAINER_API_KEY', '');
14
+ if (!$nextjs_service_url || !\is_scalar($nextjs_service_url) || !\is_scalar($api_key)) return;
15
+
16
+ $response = wp_remote_get($nextjs_service_url . '/api/field-groups', [
17
+ 'headers' => [
18
+ 'Authorization' => 'api-key ' . $api_key,
19
+ 'Content-Type' => 'application/json'
20
+ ]
21
+ ]);
22
+
23
+ if (!is_wp_error($response)) {
24
+ $body = wp_remote_retrieve_body($response);
25
+ $field_groups_data = json_decode($body, true);
26
+ if (!\is_array($field_groups_data)) return;
27
+
28
+ foreach ($field_groups_data as $field_group) {
29
+ if (!\is_array($field_group)) continue;
30
+
31
+ acf_add_local_field_group($field_group);
32
+ }
33
+ }
34
+ }