Azure App Service Next.Js Frontend cannot call Flask API Backend

Lawton Mizell 20 Reputation points
2024-01-28T21:32:06.35+00:00

Hello,

I have three services deployed via azure app services, they are all being deployed via docker containers and github actions workflow files (https://docs.github.com/en/actions/deployment/deploying-to-your-cloud-provider/deploying-to-azure/deploying-docker-to-azure-app-service)

  1. Next.js 14 Frontend
  2. Python Flask API
  3. Python Celery Worker

The focus is on the frontend and API. Both are deployed and running successfully. All environment variables are correctly set. However, the frontend calling the backend API results in an 404 Not Found undefined URL. Everything is publicly accessible. I can hit the API in the browser and postman, I can use the API locally in my running frontend application but the deployed instance does not work.

When the call is made this is how it looks

GET https://mysite.azurewebsites.net/undefined/records

It appears the other environment variables are being read in successfully because I have some set specifically for auth. For my Next.Js Application I have

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/dashboard
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/dashboard
NEXT_PUBLIC_PEEL_API=https://mysite-api.azurewebsites.net

Where https://mysite-api.azurewebsites.net can be hit in my browser and postman

https://mysite-api.azurewebsites.net

The other NEXT_PUBLIC_ variable work because they redirect when appropriate. I have CORS configured in my Flask API to allow origin from my frontend

https://mysite.azurewebsites.net

I'm lost as to why this is not working

Azure App Service
Azure App Service
Azure App Service is a service used to create and deploy scalable, mission-critical web apps.
7,205 questions
{count} votes

Accepted answer
  1. brtrach-MSFT 15,696 Reputation points Microsoft Employee
    2024-02-01T20:29:55.53+00:00

    @Lawton Mizell I'm glad that you were able to resolve your issue and thank you for posting your solution so that others experiencing the same thing can easily reference this! Since the Microsoft Q&A community has a policy that "The question author cannot accept their own answer. They can only accept answers by others ", I'll repost your solution in case you'd like to "Accept " the answer.

    Issue: Your next.Js frontend was not able to call your flask API backend.

    Solution: I have fixed my issue. According to the Next Documentation https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser
    if you build and deploy a single Docker image to multiple environments, all NEXT_PUBLIC_ variables will be frozen with the value evaluated at build time, so these values need to be set appropriately when the project is built. If you need access to runtime environment values, you'll have to setup your own API to provide them to the client (either on demand or during initialization)

    When building a containerized application for a Next application you must pass environment variable as a build argument for docker then pass it before running yarn build In my Github settings I setup a secret for the environment variable

    Then in my actions I exposed the variable as a build argument for docker

    - name: Build and push container image to registry
            uses: docker/build-push-action@v4
            with:
              push: true
              tags: ghcr.io/${{ env.REPO }}/myContainerName:${{ github.sha }}
              file: ./Dockerfile
              context: .
              build-args: |
                NEXT_PUBLIC_API_URL=${{ secrets.NEXT_PUBLIC_API_URL }}
            env:
              NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
    

    In my dockerfile before running yarn build

    # Rebuild the source code only when needed
    FROM base AS builder
    WORKDIR /app
    COPY --from=deps /app/node_modules ./node_modules
    COPY . .
    ARG NEXT_PUBLIC_API_URL
    ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
    RUN echo "NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}"
    Run yarn build
    
    

    See this for more information on Next docker buildtime vs runtime and what is exposed to server and client https://www.saltycrane.com/blog/2021/04/buildtime-vs-runtime-environment-variables-nextjs-docker/" If you have any other questions or are still running into more issues, please let me know.
    Thank you again for your time and patience throughout this issue. Please remember to "Accept Answer" if any answer/reply helped, so that others in the community facing similar issues can easily find the solution.

    1 person found this answer helpful.
    0 comments No comments

4 additional answers

Sort by: Most helpful
  1. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  2. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  3. Deleted

    This answer has been deleted due to a violation of our Code of Conduct. The answer was manually reported or identified through automated detection before action was taken. Please refer to our Code of Conduct for more information.


    Comments have been turned off. Learn more

  4. Lawton Mizell 20 Reputation points
    2024-02-01T15:22:25.0733333+00:00

    I have fixed my issue. According to the Next Documentation https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables#bundling-environment-variables-for-the-browser
    if you build and deploy a single Docker image to multiple environments, all NEXT_PUBLIC_ variables will be frozen with the value evaluated at build time, so these values need to be set appropriately when the project is built. If you need access to runtime environment values, you'll have to setup your own API to provide them to the client (either on demand or during initialization)

    When building a containerized application for a Next application you must pass environment variable as a build argument for docker then pass it before running yarn build In my Github settings I setup a secret for the environment variable

    Then in my actions I exposed the variable as a build argument for docker

          - name: Build and push container image to registry
            uses: docker/build-push-action@v4
            with:
              push: true
              tags: ghcr.io/${{ env.REPO }}/myContainerName:${{ github.sha }}
              file: ./Dockerfile
              context: .
              build-args: |
                NEXT_PUBLIC_API_URL=${{ secrets.NEXT_PUBLIC_API_URL }}
            env:
              NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
    

    In my dockerfile before running yarn build

    # Rebuild the source code only when needed
    FROM base AS builder
    WORKDIR /app
    COPY --from=deps /app/node_modules ./node_modules
    COPY . .
    ARG NEXT_PUBLIC_API_URL
    ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
    RUN echo "NEXT_PUBLIC_API_URL=${NEXT_PUBLIC_API_URL}"
    Run yarn build
    

    See this for more information on Next docker buildtime vs runtime and what is exposed to server and client

    https://www.saltycrane.com/blog/2021/04/buildtime-vs-runtime-environment-variables-nextjs-docker/

    0 comments No comments