laravel - In Azure WebApp (Linux) cannot run .sh file remotely via Azure DevOps Pipelines - Stack Overflow

I am deploying a PHPLaraval project in Azure WebApp (Linux PHP 8.3) via a Yaml pipeline.I am running

I am deploying a PHP/Laraval project in Azure WebApp (Linux PHP 8.3) via a Yaml pipeline. I am running into an issue, but also have a couple of theoretical questions:

  1. ISSUE: After a complete the CD (Deployment) and create all the infra and deploy the files to Azure Web App. I need to run a custom .sh file, to create the directories Laraval needs to store things like compiled views, chache, sessions, logs etc, and set the write permissions. It seems the reccomended way to do this is via Kudu Api. But this does not seems to work.
  2. QUESTION: It seems Laravel and Boostrap needs to have write access to certain folders to store things, like precompiled views and cache, etc. But in bothe Microsoft Agent in Azure DevOps and Azure WebApp, everything is read only. How do you solve this issue, without needing in this case to try to run a .sh script to set these up post-deployment?
  3. QUESTION: The same for Laravel migrations. This needs to run at the end of the CD, after the infrastructire is compllete and deployed. I cannot run this at the start of the CI, when building the code, as infra may not be available or may not complete successfully and leave the app in an unstable state. How can this run at the end of CD? How someone can solve this without creating a custom .sh file as I did?

Here is the custom .sh file I need to run in the server psot-deplyment:

#!/bin/bash
set -e

# Ensure necessary directories exist
chmod +x /home/site/wwwroot/run.sh

mkdir -p /home/site/storage/framework/views
mkdir -p /home/site/storage/framework/cache
mkdir -p /home/site/storage/framework/cache/data
mkdir -p /home/site/storage/framework/sessions
mkdir -p /home/site/storage/bootstrap/cache
mkdir -p /home/site/storage/logs

chown -R www-data:www-data /home/site/storage

chmod -R 775 /home/site/storage
chmod -R 775 /home/site/storage/framework/views
chmod -R 775 /home/site/storage/framework/cache
chmod -R 775 /home/site/storage/framework/cache/data
chmod -R 775 /home/site/storage/framework/sessions
chmod -R 775 /home/site/storage/bootstrap/cache



# Run Laravel commands
# cd /home/site/wwwroot
php artisan config:clear
php artisan cache:clear
php artisan view:clear
php artisan view:cache
php artisan migrate --force

and here is the yaml pipeline:

parameters:
- name: env
  displayName: Deploy To Env
  type: string
  default: dev
  values:
  - dev
  - qa
  - prod

trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

variables:
  environment: ${{ parameters.env }}
  projectname: 'siteweb'
  appservicename: 'siteweb'
  mysqlservername: 'siteweb'
  mysqladminusername: $(mysql_adminusername)
  mysqladminpassword: $(mysql_adminpassword) 
  mysqlserverversion: '8.4'
  phpversion: '8.3'
  azurestoragecontainername: 'dbarchive'
  resourcegroup: 'siteweb'
  multiplerepocheckedin: false


resources:
  repositories:
    - repository: infra
      type: git
      name: S/-infrastructure
      ref: main
  
stages:
  - stage: Build
    displayName: 'Build'
    jobs:
      - job: BuildJob
        displayName: '${{ variables.projectname }} - Build'
        steps:
        - checkout: self

        # -This section is removed for simplicitity. It installs PHP8.3 and Composer. Install dependencies run unit tests etc. No issues here
       
        - task: ArchiveFiles@2
          inputs:
            rootFolderOrFile: '$(Build.SourcesDirectory)'
            includeRootFolder: false
            archiveType: 'zip'
            archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
            replaceExistingArchive: true

        - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
          artifact: drop
          displayName: 'Publish ZIP package'

  - stage: Deploy
    displayName: 'Deployment'
    jobs:
      - job: Deploy
        displayName: '${{ variables.projectname }} - Deploy to ${{ upper(parameters.env) }}'
        steps:
          - checkout: infra

          - download: current
            artifact: drop
            displayName: 'Download ZIP package'

          # This section is removed for simplicty. It cretes a MySql server, a mysql database, an App Service, and a web app (linux, PHP8.3)

          # Here I am just seeting the app settings, using az cli. This works well
          - template: yaml/templates/common/task-create-azure-phpwebapp.yml@infra
            parameters:
              environment: ${{ variables.environment }}
              projectname: ${{ variables.projectname }}
              appservicename: ${{ variables.appservicename }}
              resourcegroup: ${{ variables.environment }}-${{ variables.resourcegroup }}-rg
              phpversion: ${{ variables.phpversion }}
              settings: |
                    APP_KEY=base64:somekey
                    MYSQL_ATTR_SSL_CA=/home/site/wwwroot/ssl/DigiCertGlobalRootCA.crt.pem
                    DB_CONNECTION=mysql
                    DB_HOST=mysqlserver-siteweb-dev.mysql.database.azure
                    DB_PORT=3306
                    DB_DATABASE=mysqlsitewebdev
                    DB_USERNAME=someusername
                    DB_PASSWORD=somepass
                    LOG_CHANNEL=daily
                    CACHE_DRIVER=file
                    SESSION_DRIVER=file
                    STORAGE_PATH=/home/site/storage

          # Here I am just deploying the zipped app to the server. This works well
          - task: AzureRmWebAppDeployment@4
            inputs:
              ConnectionType: 'AzureRM'
              azureSubscription: 'dev-serviceconnection'
              appType: 'webApp'
              WebAppName: 'app-siteweb-dev'
              package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
            displayName: "Deploy App Files"
          
          # Here I am setting the command startup for the web app and reloading ngix
          - task: AzureCLI@2
            inputs:
              azureSubscription: 'dev-serviceconnection'
              scriptType: 'bash'
              scriptLocation: 'inlineScript'
              inlineScript: |
                az webapp config set \
                --resource-group ${{ variables.environment }}-${{ variables.resourcegroup }}-rg \
                --name app-siteweb-dev \
                --startup-file "cp /home/site/wwwroot/default /etc/nginx/sites-available/default && service nginx reload"
            displayName: "Set Command Startup"
            
          #HERE IS WHERE MY PROBLEM IS. IT DOES NOT SEEM TO DO ANYTHING. IT CANNOT RUN THE FILE. I HAD A VERSION WHERE I ALSO DO THE DEPLOYMENT, AND THAT DOESN'T WORK EITHR
          - task: AzureCLI@2
            inputs:
              azureSubscription: 'dev-serviceconnection'
              scriptType: bash
              scriptLocation: inlineScript
              inlineScript: |
                export WEBAPP_USERNAME=$(az webapp deployment list-publishing-profiles \
                    --name app-siteweb-dev \
                    --resource-group ${{ variables.environment }}-${{ variables.resourcegroup }}-rg \
                    --query "[?publishMethod=='ZipDeploy'].publishingUserName" -o tsv)

                export WEBAPP_PASSWORD=$(az webapp deployment list-publishing-profiles \
                    --name app-siteweb-dev \
                    --resource-group ${{ variables.environment }}-${{ variables.resourcegroup }}-rg \
                    --query "[?publishMethod=='ZipDeploy'].publishingPassword" -o tsv)

                curl -u $WEBAPP_USERNAME:$WEBAPP_PASSWORD \
                    -X POST  \
                    -H "Content-Type: application/json" \
                    -d '{ "command": "bash /home/site/wwwroot/run.sh" }'
            displayName: "Execute .sh File on Azure Web App"

I am deploying a PHP/Laraval project in Azure WebApp (Linux PHP 8.3) via a Yaml pipeline. I am running into an issue, but also have a couple of theoretical questions:

  1. ISSUE: After a complete the CD (Deployment) and create all the infra and deploy the files to Azure Web App. I need to run a custom .sh file, to create the directories Laraval needs to store things like compiled views, chache, sessions, logs etc, and set the write permissions. It seems the reccomended way to do this is via Kudu Api. But this does not seems to work.
  2. QUESTION: It seems Laravel and Boostrap needs to have write access to certain folders to store things, like precompiled views and cache, etc. But in bothe Microsoft Agent in Azure DevOps and Azure WebApp, everything is read only. How do you solve this issue, without needing in this case to try to run a .sh script to set these up post-deployment?
  3. QUESTION: The same for Laravel migrations. This needs to run at the end of the CD, after the infrastructire is compllete and deployed. I cannot run this at the start of the CI, when building the code, as infra may not be available or may not complete successfully and leave the app in an unstable state. How can this run at the end of CD? How someone can solve this without creating a custom .sh file as I did?

Here is the custom .sh file I need to run in the server psot-deplyment:

#!/bin/bash
set -e

# Ensure necessary directories exist
chmod +x /home/site/wwwroot/run.sh

mkdir -p /home/site/storage/framework/views
mkdir -p /home/site/storage/framework/cache
mkdir -p /home/site/storage/framework/cache/data
mkdir -p /home/site/storage/framework/sessions
mkdir -p /home/site/storage/bootstrap/cache
mkdir -p /home/site/storage/logs

chown -R www-data:www-data /home/site/storage

chmod -R 775 /home/site/storage
chmod -R 775 /home/site/storage/framework/views
chmod -R 775 /home/site/storage/framework/cache
chmod -R 775 /home/site/storage/framework/cache/data
chmod -R 775 /home/site/storage/framework/sessions
chmod -R 775 /home/site/storage/bootstrap/cache



# Run Laravel commands
# cd /home/site/wwwroot
php artisan config:clear
php artisan cache:clear
php artisan view:clear
php artisan view:cache
php artisan migrate --force

and here is the yaml pipeline:

parameters:
- name: env
  displayName: Deploy To Env
  type: string
  default: dev
  values:
  - dev
  - qa
  - prod

trigger:
  - main

pool:
  vmImage: 'ubuntu-latest'

variables:
  environment: ${{ parameters.env }}
  projectname: 'siteweb'
  appservicename: 'siteweb'
  mysqlservername: 'siteweb'
  mysqladminusername: $(mysql_adminusername)
  mysqladminpassword: $(mysql_adminpassword) 
  mysqlserverversion: '8.4'
  phpversion: '8.3'
  azurestoragecontainername: 'dbarchive'
  resourcegroup: 'siteweb'
  multiplerepocheckedin: false


resources:
  repositories:
    - repository: infra
      type: git
      name: S/-infrastructure
      ref: main
  
stages:
  - stage: Build
    displayName: 'Build'
    jobs:
      - job: BuildJob
        displayName: '${{ variables.projectname }} - Build'
        steps:
        - checkout: self

        # -This section is removed for simplicitity. It installs PHP8.3 and Composer. Install dependencies run unit tests etc. No issues here
       
        - task: ArchiveFiles@2
          inputs:
            rootFolderOrFile: '$(Build.SourcesDirectory)'
            includeRootFolder: false
            archiveType: 'zip'
            archiveFile: '$(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip'
            replaceExistingArchive: true

        - publish: $(Build.ArtifactStagingDirectory)/$(Build.BuildId).zip
          artifact: drop
          displayName: 'Publish ZIP package'

  - stage: Deploy
    displayName: 'Deployment'
    jobs:
      - job: Deploy
        displayName: '${{ variables.projectname }} - Deploy to ${{ upper(parameters.env) }}'
        steps:
          - checkout: infra

          - download: current
            artifact: drop
            displayName: 'Download ZIP package'

          # This section is removed for simplicty. It cretes a MySql server, a mysql database, an App Service, and a web app (linux, PHP8.3)

          # Here I am just seeting the app settings, using az cli. This works well
          - template: yaml/templates/common/task-create-azure-phpwebapp.yml@infra
            parameters:
              environment: ${{ variables.environment }}
              projectname: ${{ variables.projectname }}
              appservicename: ${{ variables.appservicename }}
              resourcegroup: ${{ variables.environment }}-${{ variables.resourcegroup }}-rg
              phpversion: ${{ variables.phpversion }}
              settings: |
                    APP_KEY=base64:somekey
                    MYSQL_ATTR_SSL_CA=/home/site/wwwroot/ssl/DigiCertGlobalRootCA.crt.pem
                    DB_CONNECTION=mysql
                    DB_HOST=mysqlserver-siteweb-dev.mysql.database.azure
                    DB_PORT=3306
                    DB_DATABASE=mysqlsitewebdev
                    DB_USERNAME=someusername
                    DB_PASSWORD=somepass
                    LOG_CHANNEL=daily
                    CACHE_DRIVER=file
                    SESSION_DRIVER=file
                    STORAGE_PATH=/home/site/storage

          # Here I am just deploying the zipped app to the server. This works well
          - task: AzureRmWebAppDeployment@4
            inputs:
              ConnectionType: 'AzureRM'
              azureSubscription: 'dev-serviceconnection'
              appType: 'webApp'
              WebAppName: 'app-siteweb-dev'
              package: '$(Pipeline.Workspace)/drop/$(Build.BuildId).zip'
            displayName: "Deploy App Files"
          
          # Here I am setting the command startup for the web app and reloading ngix
          - task: AzureCLI@2
            inputs:
              azureSubscription: 'dev-serviceconnection'
              scriptType: 'bash'
              scriptLocation: 'inlineScript'
              inlineScript: |
                az webapp config set \
                --resource-group ${{ variables.environment }}-${{ variables.resourcegroup }}-rg \
                --name app-siteweb-dev \
                --startup-file "cp /home/site/wwwroot/default /etc/nginx/sites-available/default && service nginx reload"
            displayName: "Set Command Startup"
            
          #HERE IS WHERE MY PROBLEM IS. IT DOES NOT SEEM TO DO ANYTHING. IT CANNOT RUN THE FILE. I HAD A VERSION WHERE I ALSO DO THE DEPLOYMENT, AND THAT DOESN'T WORK EITHR
          - task: AzureCLI@2
            inputs:
              azureSubscription: 'dev-serviceconnection'
              scriptType: bash
              scriptLocation: inlineScript
              inlineScript: |
                export WEBAPP_USERNAME=$(az webapp deployment list-publishing-profiles \
                    --name app-siteweb-dev \
                    --resource-group ${{ variables.environment }}-${{ variables.resourcegroup }}-rg \
                    --query "[?publishMethod=='ZipDeploy'].publishingUserName" -o tsv)

                export WEBAPP_PASSWORD=$(az webapp deployment list-publishing-profiles \
                    --name app-siteweb-dev \
                    --resource-group ${{ variables.environment }}-${{ variables.resourcegroup }}-rg \
                    --query "[?publishMethod=='ZipDeploy'].publishingPassword" -o tsv)

                curl -u $WEBAPP_USERNAME:$WEBAPP_PASSWORD \
                    -X POST https://app-siteweb-dev.scm.azurewebsites/api/command \
                    -H "Content-Type: application/json" \
                    -d '{ "command": "bash /home/site/wwwroot/run.sh" }'
            displayName: "Execute .sh File on Azure Web App"
Share Improve this question asked Mar 23 at 12:46 Herald GjuraHerald Gjura 839 bronze badges 1
  • Please don't ask multiple questions in one. Also, for a start, extract a minimal reproducible example. – Ulrich Eckhardt Commented Mar 23 at 15:07
Add a comment  | 

1 Answer 1

Reset to default 0

According to Customize build automation,

If you deploy your app using Git, or using zip packages with build automation enabled, the App Service build automation steps through the following sequence:

  1. Run custom script if specified by PRE_BUILD_SCRIPT_PATH.

  2. Run php composer.phar install.

  3. Run custom script if specified by POST_BUILD_SCRIPT_PATH.

PRE_BUILD_COMMAND and POST_BUILD_COMMAND are environment variables that are empty by default. To run pre-build commands, define PRE_BUILD_COMMAND. To run post-build commands, define POST_BUILD_COMMAND.

You can run your .sh file as post build commands.

  1. Add two app settings in your web app.

    • SCM_DO_BUILD_DURING_DEPLOYMENT: true

    • POST_BUILD_SCRIPT_PATH: {path to your .sh file}

  2. Deploy your web app using AzureWebApp@1 task or AzureRmWebAppDeployment@4 task. (There is no need to adjust your AzureRmWebAppDeployment@4 task.) Then you will see your .sh file is built by Oryx build in the task log.

  3. Result

    Checking in the Kudu Bash, the directories will be created successfully.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744286218a4566810.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信