Production build fails for nextjs client · Issue #378 · api-platform/create-client · GitHub
Skip to content

Production build fails for nextjs client #378

Open

Description

@JDruery

API Platform version(s) affected: 3.2.16

Description
With a fresh installation, I was able to run the generator for the default Greeting entity. The app works in dev mode. When I try to build the app in production mode with http only, it fails with the following message:

9.052    Creating an optimized production build ...
38.73  ✓ Compiled successfully
38.73    Collecting page data ...
39.13 TypeError: Failed to parse URL from undefined/greetings
39.13     at node:internal/deps/undici/undici:12345:11
39.13     at async c (/srv/app/.next/server/pages/greetings/page/[page].js:1:7873)
39.13     at async c (/srv/app/.next/server/pages/greetings/page/[page].js:1:7119)
39.13     at async buildStaticPaths (/srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:786:33)
39.13     at async /srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:1215:110
39.13     at async Span.traceAsyncFn (/srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/trace/trace.js:151:20) {
39.13   [cause]: TypeError: Invalid URL
39.13       at new URL (node:internal/url:775:36)
39.13       at new Request (node:internal/deps/undici/undici:5853:25)
39.13       at fetch (node:internal/deps/undici/undici:10123:25)
39.13       at Object.fetch (node:internal/deps/undici/undici:12344:10)
39.13       at fetch (node:internal/process/pre_execution:336:27)
39.13       at c (/srv/app/.next/server/pages/greetings/page/[page].js:1:7892)
39.13       at c (/srv/app/.next/server/pages/greetings/page/[page].js:1:7133)
39.13       at buildStaticPaths (/srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:786:39)
39.13       at /srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:1215:116
39.13       at async Span.traceAsyncFn (/srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/trace/trace.js:151:20) {
39.13     code: 'ERR_INVALID_URL',
39.13     input: 'undefined/greetings'
39.13   }
39.13 }
39.13 TypeError: Failed to parse URL from undefined/greetings
39.13     at node:internal/deps/undici/undici:12345:11
39.13     at async o (/srv/app/.next/server/pages/greetings/[id].js:1:5312)
39.13     at async y (/srv/app/.next/server/pages/greetings/[id].js:1:4222)
39.13     at async buildStaticPaths (/srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:786:33)
39.13     at async /srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:1215:110
39.13     at async Span.traceAsyncFn (/srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/trace/trace.js:151:20) {
39.13   [cause]: TypeError: Invalid URL
39.13       at new URL (node:internal/url:775:36)
39.13       at new Request (node:internal/deps/undici/undici:5853:25)
39.13       at fetch (node:internal/deps/undici/undici:10123:25)
39.13       at Object.fetch (node:internal/deps/undici/undici:12344:10)
39.13       at fetch (node:internal/process/pre_execution:336:27)
39.13       at o (/srv/app/.next/server/pages/greetings/[id].js:1:5331)
39.13       at y (/srv/app/.next/server/pages/greetings/[id].js:1:4236)
39.13       at buildStaticPaths (/srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:786:39)
39.13       at /srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:1215:116
39.13       at async Span.traceAsyncFn (/srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/trace/trace.js:151:20) {
39.13     code: 'ERR_INVALID_URL',
39.13     input: 'undefined/greetings'
39.13   }
39.13 }
39.13
39.13 > Build error occurred
39.13 Error: Failed to collect page data for /greetings/page/[page]
39.13     at /srv/app/node_modules/.pnpm/next@14.1.2_@babel+core@7.24.0_react-dom@18.2.0_react@18.2.0/node_modules/next/dist/build/utils.js:1258:15 {
39.13   type: 'Error'
39.13 }
39.15  ELIFECYCLE  Command failed with exit code 1.
------
failed to solve: process "/bin/sh -c pnpm install --frozen-lockfile --offline --prod && \tpnpm run build" did not complete successfully: exit code: 1

How to reproduce

  • Download the 3.2.16 distribution
  • docker compose build --no-cache
  • docker compose up --wait
  • docker compose exec pwa pnpm create @api-platform/client --resource greeting -g next
  • go to localhost/greetings to verify that the greetings page works
  • docker compose down
  • SERVER_NAME=:80 APP_SECRET=ChangeMe CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey docker compose -f compose.yaml -f compose.prod.yaml up --build
  • TypeError: Failed to parse URL from undefined/greetings

Activity

  1. J3m5 commented on Mar 12, 2024

    @J3m5

    Hello @JDruery,

    Thank you for reporting this issue.
    The problem you're encountering during the production build appears to be related to the Next.js client's inability to access the API, which is essential for server-side generation (SSG) during the build process. Here's how to resolve it:

    1. Set the API Endpoint in the .env file

    First, we need to ensure that the Next.js client knows where to find the API. Create a .env file in the pwa directory and add the following line:

    NEXT_PUBLIC_ENTRYPOINT=http://php

    This environment variable (NEXT_PUBLIC_ENTRYPOINT) tells the Next.js client the base URL of your API, enabling it to make requests during the build and runtime.

    2. Configure Docker Compose for Network Access

    In the compose.prod.yaml file, we'll adjust the pwa service to ensure it can communicate with the php service during the build. Here's the modification:

      pwa:
        build:
          context: ./pwa
          target: prod
          network: host
          extra_hosts:
            - "php=127.0.0.1"

    These changes allow the pwa build process to access the php service by mapping the php hostname to the local machine, facilitating SSG.

    3. Adjust Environment Variables for the PHP Service

    For seamless operation of the API and Mercure Hub on a local setup without HTTPS, we need to tweak the php service configuration in the compose.yaml file. This adjustment ensures they can properly handle requests from localhost. The changes below include modifications to the environment variables, with the original settings preserved as comments for easy reference and reversal if needed:

      php:
        image: ${IMAGES_PREFIX:-}app-php
        depends_on:
          - database
        restart: unless-stopped
        environment:
          PWA_UPSTREAM: pwa:3000
          SERVER_NAME: ${SERVER_NAME:-localhost}, php:80
          MERCURE_PUBLISHER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
          MERCURE_SUBSCRIBER_JWT_KEY: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}
          TRUSTED_PROXIES: ${TRUSTED_PROXIES:-127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16}
          # TRUSTED_HOSTS: ^${SERVER_NAME:-example\.com|localhost}|php$$
          TRUSTED_HOSTS: ^localhost|php$$
          DATABASE_URL: postgresql://${POSTGRES_USER:-app}:${POSTGRES_PASSWORD:-!ChangeMe!}@database:5432/${POSTGRES_DB:-app}?serverVersion=${POSTGRES_VERSION:-15}&charset=${POSTGRES_CHARSET:-utf8}
          MERCURE_URL: ${CADDY_MERCURE_URL:-http://php/.well-known/mercure}
          # MERCURE_PUBLIC_URL: https://${SERVER_NAME:-localhost}/.well-known/mercure
          MERCURE_PUBLIC_URL: http://localhost/.well-known/mercure
          MERCURE_JWT_SECRET: ${CADDY_MERCURE_JWT_SECRET:-!ChangeThisMercureHubJWTSecretKey!}

    4. Build and start the php service

    Let's start the php service to make it accessible:

    SERVER_NAME=http://localhost APP_SECRET=!ChangeMe! CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey POSTGRES_PASSWORD=!ChangeMe! docker compose -f compose.yaml -f compose.prod.yaml up -d --build --wait php

    5. Build the pwa service

    docker compose -f compose.yaml -f compose.prod.yaml build pwa

    6. Bring up the full project

    SERVER_NAME=http://localhost  APP_SECRET=!ChangeMe! CADDY_MERCURE_JWT_SECRET=ChangeThisMercureHubJWTSecretKey POSTGRES_PASSWORD=!ChangeMe! docker compose -f compose.yaml -f compose.prod.yaml up -d --wait

    With these adjustments, your production build should succeed, and the Next.js client will be able to access the API during the build process and at runtime.

  2. J3m5 commented on Mar 13, 2024

    @J3m5

    I've updated my initial post due to additional issues encountered during runtime. For the API and Mercure to function correctly without HTTPS, it's necessary to revise the TRUSTED_HOSTS and MERCURE_PUBLIC_URL environment variables in the compose.yaml file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions