microsoft / azure-container-apps

Roadmap and issues for Azure Container Apps
MIT License
358 stars 28 forks source link

Feature Request: Support mount options in volume mount #520

Open harrysummer opened 1 year ago

harrysummer commented 1 year ago

Is your feature request related to a problem? Please describe.
I am trying to setup a PostgreSQL container app with persistent data mounted from Azure Files. However, PG-SQL only allows that the data folder is owned by a non-root user. Moreover, the doc of PGSQL specifically recommends hard in the mounting option. So, it would be very helpful if user can manually specify the mounting option of volume mounts.

Describe the solution you'd like.
Add a field to the volumeMounts structure in yaml config. The snippet should look like

      volumeMounts:
      - volumeName: postgresql-volume
        mountPath: /var/lib/postgresql/data
        mountOptions: [ "uid=999", "gid=999", "hard" ]

The specified mounting options can be passed to k8s config transparently, or manually appended to the existing mounting options, depending on the implementation.

flytzen commented 1 year ago

Another mountOptions that is required is nobrl.

Microsoft recommends that you set nobrl when mounting Azure Files volumes into containers. Without this setting, SQLite fails with database is locked.

The attached Bicep file tries to deploy Mealie, which use SQLite in the API container. If you deploy it, you will see that the API fails to start because SQLite throws "database is locked" - as is expected when nobrl is not set. meailedeploy.zip

vincentspaa commented 1 year ago

Seeing as this feature request might really help us out with resolving issue #534 , are there any concrete plans on including this request in the Container Apps roadmap @anthonychu ?

anthonychu commented 1 year ago

This feature is being tracked at #765.

It's not available in the portal yet, but you can use ARM or Bicep to add a mountOptions property to the volume.

We'll announce this feature in public preview once portal supports it.

@flytzen I've tested out your Mealie example and it looks like it's working now (shows the login screen, at least). Had to make a couple of other adjustments to the Bicep:

param location string = resourceGroup().location

param deploymentName string = 'flytzen-mealie'

// TODO: https://stackoverflow.com/questions/53226642/sqlite3-database-is-locked-in-azure
// https://github.com/MicrosoftDocs/azure-docs/issues/82464
// https://learn.microsoft.com/en-us/troubleshoot/azure/azure-kubernetes/mountoptions-settings-azure-files

resource storageAccount 'Microsoft.Storage/storageAccounts@2022-05-01' = {
  name: '${replace(deploymentName, '-','')}sa'
  location: location
  sku: {
    name: 'Standard_GRS'
  }
  kind: 'StorageV2'

  resource fileShareService 'fileServices' = {
    name: 'default'
    resource fileShare 'shares' = {
      name: '${deploymentName}-fs'
    }
  }
}

resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-06-01' = {
  name: '${deploymentName}-la'
  location: location
  properties: {
    sku: {
      name: 'PerGB2018'
    }
  }
}

resource acaenvironment 'Microsoft.App/managedEnvironments@2022-06-01-preview' = {
  name: '${deploymentName}-cae'
  location: location
  sku:{
    name: 'Consumption'
  }
  properties: {
    appLogsConfiguration: {
      destination: 'log-analytics'
      logAnalyticsConfiguration: {
        customerId: logAnalytics.properties.customerId
        sharedKey: logAnalytics.listKeys().primarySharedKey
      }

    }
  }
  resource sharedFiles 'storages@2022-06-01-preview' = {
    name: '${deploymentName}mount'
    properties: {
      azureFile: {
        accountName: storageAccount.name
        accountKey: storageAccount.listKeys().keys[0].value
        accessMode: 'ReadWrite'
        shareName: storageAccount::fileShareService::fileShare.name
      }
    }
  }
}

resource apicontainer 'Microsoft.App/containerApps@2023-04-01-preview' = {
  location: location
  name: '${deploymentName}-api-aca'
  properties: {
    managedEnvironmentId: acaenvironment.id
    configuration: {
      ingress: {
        external: false
        targetPort: 9000
        allowInsecure: true
        traffic: [
          {
            latestRevision: true
            weight: 100
          }
        ]
      }
    }
    template: {
      // revisionSuffix: 'firstrevision'
      containers: [
        {
           name: 'mealie-api'
           image: 'hkotel/mealie:api-v1.0.0beta-5'
           volumeMounts: [
            {
              mountPath:'/app/data'
              volumeName: 'api-volume'
            }
          ]
          resources:{
            memory: '1Gi'
            cpu: json('0.5')
          }
          env: [
            {
              name: 'ALLOW_SIGNUP'
              value: 'true'
            }
            {
              name: 'PUID'
              value: '1000'
            }
            {
              name:'PGID'
              value:'1000'
            }
            {
              name:'TZ'
              value: 'Europe/London'
            }
            {
              name:'MAX_WORKERS'
              value:'1'
            }
            {
              name:'WEB_CONCURRENCY'
              value:'1'
            }
            {
              name:'BASE_URL'
              value: 'https://${deploymentName}-aca.${acaenvironment.properties.defaultDomain}'
            }
          ]
        }
      ]
      volumes:[
        {
          name:'api-volume'
          storageType:'AzureFile'
          storageName:acaenvironment::sharedFiles.name
          mountOptions: 'uid=1000,gid=1000,nobrl,mfsymlinks,cache=none'
        }
      ]
      scale: {
        minReplicas: 0
        maxReplicas: 1
        rules: [
          {
            name: 'http-requests'
            http: {
              metadata: {
                concurrentRequests: '10'
              }
            }
          }
        ]
      }
    }

  }
} 

resource frontendcontainer 'Microsoft.App/containerApps@2022-06-01-preview' = {
  location: location
  name: '${deploymentName}-frontend-aca'
  properties: {
    managedEnvironmentId: acaenvironment.id
    configuration: {
      ingress: {
        external: true
        targetPort: 3001
        allowInsecure: false
        traffic: [
          {
            latestRevision: true
            weight: 100
          }
        ]
      }
    }
    template: {
      // revisionSuffix: 'firstrevision'
      containers: [
        {
          name: 'mealie-frontend'
          image: 'hkotel/mealie:frontend-v1.0.0beta-5'
          env: [
            {
              name: 'API_URL'
              value: 'https://${deploymentName}-api-aca.internal.${acaenvironment.properties.defaultDomain}'
            }
          ]
          volumeMounts: [
            {
              mountPath:'/app/data'
              volumeName: 'frontend-volume'
            }
          ]
        }
      ]
      volumes:[
        {
          name:'frontend-volume'
          storageType:'AzureFile'
          storageName:acaenvironment::sharedFiles.name
        }
      ]
      scale: {
        minReplicas: 0
        maxReplicas: 1
        rules: [
          {
            name: 'http-requests'
            http: {
              metadata: {
                concurrentRequests: '10'
              }
            }
          }
        ]
      }
    }
  }
}
flytzen commented 1 year ago

This feature is being tracked at #765.

It's not available in the portal yet, but you can use ARM or Bicep to add a mountOptions property to the volume.

We'll announce this feature in public preview once portal supports it.

@flytzen I've tested out your Mealie example and it looks like it's working now (shows the login screen, at least). Had to make a couple of other adjustments to the Bicep:

Awesome, that's going far above and beyond. Thank you!

cwe1ss commented 3 months ago

@anthonychu can we still play around with the documented „mountOptions“ field via ARM/Bicep? may I ask if this will be in private preview or public preview soon?

cgraf-spiria commented 3 months ago

When editing a container app's volumes, there is a mount options field. So I guess it's available now ?

avalanche-tm commented 2 months ago

Can this be done in Azure Container Instances?