skip to Main Content

I’m having a issue building and deploying a NextJS14 app to Azure App Service in my Turbo Mono Repo and I seek help understanding the correct way to do that. I tried numerous things and everytime I’m missing a dependencie or the node_module is too big and the deployment fails. So can any of you give me the correct sequence to do in my YAML to build from a mono repo and send it to my azure web app so it can run.

What I tried is since I can’t send the App itself only, since building it creates weird simplink in the node_module to the root node_module, I decided to add a .npmrc with the node-linker=hoisted
symlink=false inside and the I do my pnpm install and copy the root node_module in my project then send that to the azure web app. Right now the bundle is around 500MB zipped and fails around the 40 minutes mark to send it to my machine (B1 Linux Service Plan). So I’m kind of a lost n the way to do it from a mono repo.

Just remember I’m no expert and just started this journey.

Thank you for the help

My yml scripts

azure-pipeline.yml

trigger:
  branches:
    include:
      - main
  paths:
    include:
      - apps/frontend/*

variables:
  - name: projectRoot
    value: $(Build.SourcesDirectory)/apps/frontend

stages:

  - stage: IdentifyAndSetVariables
    displayName: 'Identify Changes and Set Variables'
    jobs:
      - job: IdentifyChanges
        displayName: 'Identify Changes'
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - checkout: self
            submodules: true
            fetchDepth: 2
          - bash: |
              echo "Identifying modified projects..."
              MODIFIED_PROJECTS=$(git diff --name-only HEAD~1 -- apps/frontend | awk -F/ '{print $3}' | sort -u | tr 'n' ';')
              echo "Modified projects: $MODIFIED_PROJECTS"
              # -- Only for testing 
              MODIFIED_PROJECTS='transfert-passages' 
              IFS=';' read -r -a projectArray <<< "$MODIFIED_PROJECTS"
              for project in "${projectArray[@]}"
              do
                projectName=${project}
                echo "##vso[task.setvariable variable=${projectName}Changed;isOutput=true]true"
              done
            displayName: 'Get the modified projects'
            name: IdentifyChangesOutput
            env:
              SYSTEM_ACCESSTOKEN: $(System.AccessToken)

  - stage: Build
    displayName: 'Build Projects'
    dependsOn: [Prepare, IdentifyAndSetVariables]
    condition: succeeded()
    jobs:
      - job: DeployInfoSecur
        condition: eq(stageDependencies.IdentifyAndSetVariables.IdentifyChanges.outputs['IdentifyChangesOutput.info-securChanged'], 'true')
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - template: info-secur-build-deploy.yml

      - job: DeployGestionAdresses
        condition: eq(stageDependencies.IdentifyAndSetVariables.IdentifyChanges.outputs['IdentifyChangesOutput.gestion-adressesChanged'], 'true')
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - script: echo "Deploying Gestion-Adresses..."
          - template: gestion-adresses-build-deploy.yml

      - job: DeployTransfertPassages
        condition: eq(stageDependencies.IdentifyAndSetVariables.IdentifyChanges.outputs['IdentifyChangesOutput.transfert-passagesChanged'], 'true')
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - template: transfert-passages-build-deploy.yml
      - job: DeployGestionDemandes
        condition: eq(stageDependencies.IdentifyAndSetVariables.IdentifyChanges.outputs['IdentifyChangesOutput.gestion-demandesChanged'], 'true')
        pool:
          vmImage: 'ubuntu-latest'
        steps:
          - template: transfert-passages-build-deploy.yml

transfert-passage-build-deploy.yml

parameters:
  - name: projectName
    type: string
    default: 'transfert-passages'
  - name: appLocation
    type: string
    default: apps/frontend/transfert-passages
  - name: azureSubscription
    type: string
    default: ''
  - name: webAppName
    type: string
    default: 'Transfert-Passages'

steps:
  - checkout: self
    submodules: true
  - task: NodeTool@0
    inputs:
      versionSpec: '20.x'
    displayName: 'Install Node.js'
  - script: |
      curl -L https://unpkg.com/@pnpm/self-installer | node
    displayName: 'Install pnpm'
  - script: |
      echo $(TRANSFERT_PASSAGES_API_SPA) > apps/backend/nodejs/api-transfert-passages/.env
      echo $(TRANSFERT_PASSAGES_API_LOGS) >> apps/backend/nodejs/api-transfert-passages/.env
      echo "node-linker=hoisted" > .npmrc
      echo "symlink=false" >> .npmrc
      cat .npmrc
      cat apps/backend/nodejs/api-transfert-passages/.env
      pnpm install
      pnpx prisma generate --schema=apps/backend/nodejs/api-transfert-passages/prisma/schemas/cdv-sbdr021-SPA.prisma
      pnpx prisma generate --schema=apps/backend/nodejs/api-transfert-passages/prisma/schemas/cdv-sbdr015-LOGS.prisma
      pnpm run build --filter ${{ parameters.projectName }}
      mv node_modules apps/frontend/transfert-passages/
    displayName: 'Build Transfert Passages'
  - task: ArchiveFiles@2
    inputs:
      rootFolderOrFile: 'apps/frontend/transfert-passages'
      includeRootFolder: false
      archiveType: 'zip'
      archiveFile: '$(Build.ArtifactStagingDirectory)/${{ parameters.projectName }}.zip'
      replaceExistingArchive: true
    displayName: 'Archive Build Artifacts'
  - upload: $(Build.ArtifactStagingDirectory)/${{ parameters.projectName }}.zip
    artifact: ${{ parameters.projectName }}

For deployment I do it manually from the Releases menu

2

Answers


  1. Chosen as BEST ANSWER

    Ok So the way I managed to make it work in my pipeline :

    1. pnpm install
    2. pnpm run build --filter
    3. I create a tmp file and copy over the .next from the mono repo
    4. I create a simple package.json, containing the next as a dependency only, in the temp folder
    5. I cd into that folder
    6. run npm install
    7. Then I make an artifact of that folder.
    8. send it to the server
    steps:
      - checkout: self
        submodules: true
      - task: NodeTool@0
        inputs:
          versionSpec: '20.x'
        displayName: 'Install Node.js'
    
      - script: curl -L https://unpkg.com/@pnpm/self-installer | node
        displayName: 'Install pnpm'
    
      - script: |
          export NEXT_PUBLIC_API_USERNAME=$(NEXT_PUBLIC_API_USERNAME)
          export NEXT_PUBLIC_API_PASSWORD=$(NEXT_PUBLIC_API_PASSWORD)
          export NEXT_PUBLIC_APP_AAD_APP_API_URI=$(NEXT_PUBLIC_APP_AAD_APP_API_URI)
          export NEXT_PUBLIC_JWT_TOKEN=$(NEXT_PUBLIC_JWT_TOKEN)
        displayName: 'Set environment variables'
    
      - script: |
          echo $(apiSPAConnectionString) > $(apiBackendLocation)/.env
          echo $(apiLOGSConnectionString) >> $(apiBackendLocation)/.env
        displayName: 'Set environment variables for Prisma'
    
      - script: |
          pnpm install
          pnpm run prisma:generate:all --filter api-$(projectName)
          pnpm run build --filter $(projectName)
        displayName: 'Build Transfert Passages'
    
      - script: |
          mkdir -p $(tempFolder)
          mv $(packageJSONLocation)package.json $(tempFolder)
          mv $(appLocation)/.next $(tempFolder)
          cd $(tempFolder)
          npm install
        displayName: 'Building new dependencies'
      - task: ArchiveFiles@2
        inputs:
          rootFolderOrFile: $(tempFolder)
          includeRootFolder: false
          archiveType: 'zip'
          archiveFile: '$(Build.ArtifactStagingDirectory)/$(projectName).zip'
          replaceExistingArchive: true
        displayName: 'Archive Build Artifacts'
      - upload: $(Build.ArtifactStagingDirectory)/$(projectName).zip
        artifact: $(projectName)
    

    Hope it can help someone.


  2. In order to deploy Turbo repo successfully, Refer the steps below: –

    My Turbo-repo app runs locally with turbo run dev command:-

    Commands: –

    npm install turbo --global
    turbo build
    turbo run dev
    

    Output: –

    enter image description here

    My Azure DevOps pipeline code: –

    trigger:
    - main
    
    variables:
      environmentName: 'siliconwebapp655'
      vmImageName: 'ubuntu-latest'
    
    stages:
    - stage: Build
      displayName: Build stage
      jobs:
      - job: Build
        displayName: Build
        pool:
          vmImage: $(vmImageName)
    
        steps:
        - task: NodeTool@0
          inputs:
            versionSpec: '18.x'
          displayName: 'Install Node.js'
    
        - script: npm install turbo --global
          displayName: 'Install Turbo globally'
        - script: npm install
          displayName: 'Install all packages'
    
        - script: |
            turbo build
          displayName: 'Build application with Turbo'
    
        - task: ArchiveFiles@2
          displayName: 'Archive files'
          inputs:
            rootFolderOrFile: '$(System.DefaultWorkingDirectory)'
            includeRootFolder: false
            archiveType: zip
            archiveFile: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
            replaceExistingArchive: true
    
        - upload: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
          artifact: drop
    
    - stage: Deploy
      displayName: Deploy stage
      dependsOn: Build
      condition: succeeded()
      jobs:
      - deployment: Deploy
        displayName: Deploy
        environment: $(environmentName)
        pool:
          vmImage: $(vmImageName)
        strategy:
          runOnce:
            deploy:
              steps:
              - task: NodeTool@0
                inputs:
                  versionSpec: '18.x'
                displayName: 'Install Node.js for deployment'
    
              - script: npm install turbo --global
                displayName: 'Install Turbo globally'
    
              - task: AzureWebApp@1
                displayName: 'Azure Web App Deploy: $(webAppName)'
                inputs:
                  azureSubscription: 'SID subscription (0151c365-f598-44d6-b4fd-e2b6e97cb2a7)'
                  appType: 'webAppLinux'
                  appName: 'siliconwebapp542'
                  package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
                  runtimeStack: 'NODE|18.10'
                  startUpCommand: 'turbo run dev'
    

    Output:-

    enter image description here

    You can scale up your Web app to Standard Tier from Basic tier to increase the compute size and memory of your Web app: –

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search