How to deploy pgadmin4 docker image on azure web app? - azure

I am unable to run docker image dpage/pgadmin4 on azure web app (Linux) which is available on docker hub.
I have installed Docker in my Linux machine and was able to run that docker image locally. Then I created Web app in Azure with options as given below:
OS: Linux
Publish: Docker Image
App service plan: Linux app service
After creating web app, I added two env variables in App Settings section:
PGADMIN_DEFAULT_EMAIL : user#domain.com
PGADMIN_DEFAULT_PASSWORD : SuperSecret
Finally login screen is visible but when I enter above credentials, it doesn't work and keeps redirecting to login page.
Update: If login is working properly, screen appears as shown below.
!(pgadmin initial screen)

After several retries i once got an message (CSRF token invalid) displayed in the right-top corner of the login screen.
For CSRF to properly work there must be some serverside state? So I activated the "ARR affinity" in the "General Settings" on the azure "Configuration".
I also noticed in the explamples on documentation the two environment-variables PGADMIN_CONFIG_CONSOLE_LOG_LEVEL (which is in the example set to '10') and PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION (which is in the example set to 'True').
After enabling "ARR" and setting PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION to False the login started to work. I have no idea what PGADMIN_CONFIG_ENHANCED_COOKIE_PROTECTION is actually doing, so please take that with caution.
If thats not working for you, maybe setting PGADMIN_CONFIG_CONSOLE_LOG_LEVEL to 10 and enabling console debug logging can give you a clue whats happening.

For your issue, I do the test and find that it's really a strange thing. When I deploy the docker image dpage/pgadmin4 in Azure service Web App for Container through Azure CLI and set the app settings, there is no problem to log in with the user and password. But when I deploy it through the Azure portal, then I meet the same thing with you.
Not sure what is the reason, but the solution is that set the environment variables PGADMIN_DEFAULT_EMAIL and PGADMIN_DEFAULT_PASSWORD through the Azure CLI like below:
az webapp config appsettings set --resource-group <resource-group-name> --name <app-name> --settings PGADMIN_DEFAULT_EMAIL="user#domain.com" PGADMIN_DEFAULT_PASSWORD="SuperSecret"
If you really want to know the reason, then you can make feedback to Microsoft. Maybe it's a bug or some special settings.
Update
The screenshot of the test on my side here:

Related

Deployed Azure WebApp gives 403

My issue:
When I try access the main URL for my web app, Azure replies with a '403 - You do not have permission to view this directory or page'.
Context:
I have deployed a Python webapp to Azure using the Pipeline/Release on DevOps (Azure Web App Deploy task seems to run successfully with the artifact generated by the Pipeline). I have previously deployed Python Function Apps successfully with a similar pipeline (different app type of course, and sku).
The Kudu SCM page works e.g.,: myapp.scm.azurewebsites.net
All logs seem to indicate the webapp deployment was successful. If I use CMD or Powershell from the SCM, I can see my app.py (for Flask) is in the correct location. The deployment has my requirements under the site packages installed including Flask.
The app runs quite successfully on my local machine via 'flask run', after I activate the virtual environment.
Yet when I try connect to myapp.azurewebsites.net, I get a 403 on the plain route. Anything after it like /test or /myapi returns a 404.
Something I do not see in any of the logs I can access via Kudu is mention of 'gunicorn', which I believe is what Azure uses by default. I just want to see some kind of log output somewhere to show that flask or gunicorn or something has successfully loaded app.py and is listening for incoming connections.
Maybe you do not know why I would get 403's, but you might know where I should be seeing the aforementioned logs.
TIA for any suggestions.
EDIT:
Something to add is that if I enable logs, and connect to the logstream then I do see logs generated as I access Kudu. This suggests some Application & Web Server are running - at least for whatever container runs that side of things.
It even notes the failed connections from Postman for the actual myapp.azurewebsites.net, but has nothing other than a line indicating that there is a 403.
My app has been stripped down to the most bare app.py with no includes other than Flask and routes which simply return a string. Most includes in requirements.txt have also been stripped out.
Still same issue.
I do have an answer after a couple of days worth of pulling my hair out.
Turns out that the 403's were not actually a permissions issue.
az webapp list-runtimes --os windows
The list shows no runtimes available for Python/Flask Web App. This is why I could not find any gunicorn or Flask logs - neither are set up. Azure deployed the artifact's zip and called it a day.
To rectify this, the DevOps Pipeline/Release must run on Linux. The Azure Web App Deploy task, when set to "Web App on Linux", will have Python runtime stacks available. Once selected, these will allow for a startup command to be specified. (Such as flask run --host=0.0.0.0 --port=8000)
Furthermore in azuredeploy.json the "Microsoft.Web/serverfarms" must have a "kind" specified to include "linux". It also requires:
"properties": {"reserved" : true}
Once deployed, logs indicate that docker is being set to an internal port of 8000 while the default 'flask run' which is executed would use 5000.
Ideally: use gunicorn with port mapping but, to get things going, tell flask to use port 8000.

Can I deploy code from DevOps to Azure Web running on Linux Container?

I have a Web app running on Linux which is deployed from Docker Container.
Container comes from Azure container registry and was defined when I created the web app.
When I try to set my release pipeline to deploy to this web app, it doesnt offer me this choice.
When I set my subscription and Web app on Linux, I only see web apps that are deployed from code. My web app from docker container is not in the list in the App Name select:
I tried to do this manually using Azure PowerShell. I have set up local connection and trying to test the deploy but it doesnt work.
I have downloaded the repository locally as a zip file and I am trying to deploy it from this local zip file to the Web app on Azure. I try to deploy it from Powershell:
$webapp = Get-AzWebApp -ResourceGroupName "MyResourceGroup" -Name "my-container-app"
$path = 'C:\temp\repository.zip'
Publish-AzWebApp -WebApp $webapp -ArchivePath $path -Force
I am using Publish-AzWebApp command.
This command goes without an error, I also tried without -Force parameter, and with -AsJob parameter.
Everytime the command is executed successfully, but when I check my web app there is nothing deployed there. If I try this exact procedure with web app that is not from container, but from code than it works. By code/container I mean this setting that you choose when creating web app:
Currently I am using docker image that is also used by Azure as default so it should be the same Debian. I need to use it because I want to set some things differently in my web app, so I want to have my own system on web app, but deploy code from Devops to it.
However it seems that this type of web app is not supperted for deploy - nether from Devops gui, nor from Azure CLI. Can I somehow deploy my code on a web app that is running on my custom docker image?
PS: One option is to use the agent in Devops pipeline, compile a docker image from it and publish it with my code to the Azure container repository, from which it can be used form my web app. Problem is that you can only choose from 2 Ubuntu versions as an agent for build pipeline and I dont want that.
Any help is appreciated, thanks
For your requirements, first of all, you need to know the Web App on Linux and Web App for Container are two different resources, so it does not list your app deployed from the docker image. And second, when you use the docker image, it means you need to create a new image when your code change. So it does not support that create the Web App from the docker image and then publish the code from the DevOps.
The option that you think is right. Don't worry about the OS, you can use the Azure CLI command to create the docker image and push it to the Azure Container Registry directly:
az acr build -t image_name:tag -r acr_name source_code_path
And then deploy the image from the ACR to the Web App. In this way, the DevOps agent just use to run the task, not for the creation of the docker image.

Docker fails to pull the image from within Azure App Service

The Container Setting on the App Service it self look solid:
But the log pane shows errors:
2020-02-11 06:31:40.621 ERROR - Image pull failed: Verify docker image configuration and credentials (if using private repository)
2020-02-11 06:31:41.240 INFO - Stoping site app505-dfpg-qa2-web-eastus2-gateway-apsvc because it failed during startup.
2020-02-11 06:36:05.546 INFO - Starting container for site
2020-02-11 06:36:05.551 INFO - docker run -d -p 9621:8081 --name app505-dfpg-qa2-web-eastus2-gateway-apsvc_0_a9c8277e_msiProxy -e WEBSITE_SITE_NAME=app505-dfpg-qa2-web-eastus2-gateway-apsvc -e WEBSITE_AUTH_ENABLED=False -e WEBSITE_ROLE_INSTANCE_ID=0 -e WEBSITE_HOSTNAME=app505-dfpg-qa2-web-eastus2-gateway-apsvc.azurewebsites.net -e WEBSITE_INSTANCE_ID=7d18d5957d129d3dc3a25d7a2c85147ef57f1a6b93910c50eb850417ab59dc56 appsvc/msitokenservice:1904260237
2020-02-11 06:36:05.552 INFO - Logging is not enabled for this container.
Please use https://aka.ms/linux-diagnostics to enable logging to see container logs here.
2020-02-11 06:36:17.766 INFO - Pulling image: a...cr/gateway:1.0.20042.2
2020-02-11 06:36:17.922 ERROR - DockerApiException: Docker API responded with status code=NotFound, response={"message":"pull access denied for a...cr/gateway, repository does not exist or may require 'docker login': denied: requested access to the resource is denied"}
2020-02-11 06:36:17.923 ERROR - Pulling docker image a...cr/gateway:1.0.20042.2 failed:
2020-02-11 06:36:17.923 INFO - Pulling image from Docker hub: a...cr/gateway:1.0.20042.2
2020-02-11 06:36:18.092 ERROR - DockerApiException: Docker API responded with status code=NotFound, response={"message":"pull access denied for a...cr/gateway, repository does not exist or may require 'docker login': denied: requested access to the resource is denied"}
2020-02-11 06:36:18.094 ERROR - Image pull failed: Verify docker image configuration and credentials (if using private repository)
2020-02-11 06:36:19.062 INFO - Stoping site app505-dfpg-qa2-web-eastus2-gateway-apsvc because it failed during startup.
The Service Principal used to deploy the App Service has AcrPush access to the parent resource group of the container registry:
The setting are present:
I did az login with that service principal and then tried az acr login to the registry. It works fine. So what am I missing here?
EDIT 1
I know the credentials are correct, because I tested them like this:
Where I just copied the values from the app service configuration and pasted on the console. docker has no problem logging in.
It must be something else.
EDIT 2
However, I also get this:
C:\Dayforce\fintech [shelve/terraform ≡]> docker pull a...r/gateway
Using default tag: latest
Error response from daemon: pull access denied for a...r/gateway, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
So, I can login, but not pull. Very strange, because the account is configured to have AcrPush access to the container, which includes AcrPull:
EDIT 3
I was able to pull successfully when using the FQDN for the registry:
I updated the pipeline, but I still get the same errors:
2020-02-11 16:03:50.227 ERROR - Pulling docker image a...r.azurecr.io/gateway:1.0.20042.2 failed:
2020-02-11 16:03:50.228 INFO - Pulling image from Docker hub: a...r.azurecr.io/gateway:1.0.20042.2
2020-02-11 16:03:50.266 ERROR - DockerApiException: Docker API responded with status code=InternalServerError, response={"message":"Get https://a...r.azurecr.io/v2/gateway/manifests/1.0.20042.2: unauthorized: authentication required"}
2020-02-11 16:03:50.269 ERROR - Image pull failed: Verify docker image configuration and credentials (if using private repository)
2020-02-11 16:03:50.853 INFO - Stoping site app505-dfpg-qa2-web-eastus2-gateway-apsvc because it failed during startup.
EDIT 4
The only way that I found working was to enable the Admin User on the ACR and pass its credentials in the DOCKER_... variables instead of credentials of the Service Principal.
This is frustrating, I know the Service Principal can login and pull when ran locally, it is a mystery why it does not work for docker running on an App Service Host. We have another team here which faced the same issue and they have not found any solution, but enable the Admin User.
EDIT 5
The entire process runs as part of the Azure DevOps on-prem release pipeline using a dedicated Service Principal. Let me call it Pod Deploy Service Principal or just SP for short.
Let DOCKER_xyz denote the three app settings controlling the docker running on the App Service host:
DOCKER_REGISTRY_SERVER_URL
DOCKER_REGISTRY_SERVER_USERNAME
DOCKER_REGISTRY_SERVER_PASSWORD
I think we need to distinguish two parts here:
App Service needs to talk to the ACR in order to pull from it the details about the image and present them in this GUI - For that to work, the SP must have the AcrPull role in the ACR. Failure to do so results in the GUI presenting a spinning icon for the Image and Tag rows. I stumbled on it before - How to configure an Azure app service to pull images from an ACR with terraform? Now the answer to that question suggests that I have to assign the AcrPull role and set the DOCKER_xyz app settings. I think that the DOCKER_xyz app settings are not for that, but for the second part.
It seems to me that when an App Service is started, the host uses docker to actually pull the right image from the ACR. This part seems to be detached from (1). For it to work, the app settings must have the DOCKER_xyz app settings.
My problem is that part (1) works great, but part (2) does not even if DOCKER_xyz app settings specify the credentials of the SP from part (1). The only way I could make it work if I point DOCKER_xyz at the Admin User of the ACR.
But that why on Earth the DOCKER_xyz app settings cannot point to the pipeline SP, which was good enough for the part (1)?
EDIT 6
The current state of affairs is this. Azure App Service is unable to communicate with an ACR except using ACR admin user and password. So, even if the docker runtime running on the App Service host machine may know how to login using any service principal, the App Service would not use any identity or Service Principal to read metadata from the ACR - only admin user and password. The relevant references are:
https://feedback.azure.com/forums/169385-web-apps/suggestions/36145444-web-app-for-containers-acr-access-requires-admin#%7btoggle_previous_statuses%7d
https://github.com/MicrosoftDocs/azure-docs/issues/49186
On a personal note I find it amazing that Microsoft recommends not to use ACR admin user, yet a very core piece of their offering, namely Azure App Service, depends on it being enable. Makes me wonder whether different teams in Microsoft are aware of what others are doing or not doing...
App service started pulling after doing these steps for me. :D
Enable Admin Access in Azure Container Registry
In the App service configuration, provide container registry admin credentials
DOCKER_REGISTRY_SERVER_PASSWORD(admin enabled password),
DOCKER_REGISTRY_SERVER_USERNAME(crxxxxxx),
DOCKER_REGISTRY_SERVER_URL (https://crxxxxxx.azurecr.io)
Go to your app service and select identity section on the left, and click on system assigned - change status to On.
Now go to IAM Control container registry, add ACR pull role to App Service system assigned identity enabled on step 3.
Restart your App Service and wait .Changes will take few minutes to reflect so refresh your logs. (10 minutes or more)
Good luck :)
After a lot of research I figured out a way to resolve this without enabling Admin user
Create an app registration using Azure Active Directory and store the secret somewhere.
Go to the Azure container registry and add role assignment to this newly created app with permissions of AcrPush (which also contains AcrPull).
In the App service configuration, replace the variables .
DOCKER_REGISTRY_SERVER_PASSWORD with Client Secret of app registration which was saved in the first step
DOCKER_REGISTRY_SERVER_USERNAME with client Id of App registration
This should solve the Docker Api exception.
It's baffling that this is not mentioned in any Azure Container Registry documentation. Although I think it is mentioned somewhere in AAD documentation indirectly 😐.
From the message I got of the talk, let me solve your puzzle about the error.
I guess you deploy the image in ACR to the Web App through the Azure portal. When you use the Azure portal to deploy the Web App from the ACR, it only lets you select the ACR and image and tag, but do not let you set the credential. In this way, Azure will set it itself with the admin user and password if you enable the admin user. If you do not enable it, the error you got happens.
And if you want to use the service principal, I recommend you use the other tools, such as Azure CLI. Then you can set the docker registry credential yourself with the command az webapp config container set.
Here is the example and it works fine on my side:
With the Azure CLI, you can follow the steps here.
Update:
Here are the screenshots of the test on my side:
Found the answer by setting "acrUseManagedIdentityCreds" to True. The second command in this comment: https://stackoverflow.com/a/69120462/17430834
Edit 1: Adding the command
Here is the command that you will need to run to make this change.
az resource update --ids /subscriptions/<subscription-id>/resourceGroups/myResourceGroup/providers/Microsoft.Web/sites/<app-name>/config/web --set properties.acrUseManagedIdentityCreds=True
I was trying to do the same from Azure DevOps pipelines and got the same problem.
I didn't find out how to make it work using the ACR name, but it works if you use your_acr_name.azurecr.io instead.
If you go to the Access Keys page of your ACR you will find two values
Registry name: MyCoolRegistry (doesn't work if you use this one)
Login server: mycoolregistry.azurecr.io
The login server is working - just put it as the containerRegistry in your Pipeline without creating a service connection.
Just in case someone is struggling with that one.
Just to add to mark's amazing job of working it all through and for the fast readers: for everything to work, one of course also has to enable the admin user (who by default is disabled). For example by issuing:
az acr update -n <your-azureregistry-name> --admin-enabled true
on the console.
I experienced this same issue when trying to deploy an Docker application to Azure Web Apps for containers.
When I deployed the application I will get the error:
DockerApiException: Docker API responded with status code=NotFound, response={"message":"pull access denied for a..my-repo/image, repository does not exist or may require 'docker login': denied: requested access to the resource is denied"}.
Here's how I solved it:
The issue was that I was not specifying the full path to the image. I was supposed to include my-registry-url in the docker image-name. That is instead of just image-name I was supposed to use my-registry-url/image-name, since I am trying to pull from a private repository.
So say these are variables:
docker image name is promiseapp
docker-registry_url is promisecicdregistry.azurecr.io
resource-group is dockerprojects
app-service-plan is dockerlinuxprojects
azure-web-app name is promiseapptest
docker-registry-user is test-user
docker-registry-password is 12345678
Then my command will be:
az webapp create --resource-group dockerprojects --plan dockerlinuxprojects --name promiseapptest --deployment-container-image-name promisecicdregistry.azurecr.io/promiseapp
az webapp config container set --resource-group dockerprojects --name promiseapptest --docker-custom-image-name promisecicdregistry.azurecr.io/promiseapp --docker-registry-server-url https://promisecicdregistry.azurecr.io --docker-registry-server-user test-user --docker-registry-server-password 12345678
In my case, I fixed the error by using the fully qualified Azure Container Registery name like this:
xwezi.azurecr.io
The previous value was
xwezi
When I deploy manually to App Services, I wouldn't get that error.
But, when I used Azure App Service deploy task to deploy the container to the App Service, the service won't work correctly.
And, the log stream will show the above errors.
Unfortunately, the error messages weren't helpful for me to find this out. But I hope this will save your time :)

Azure Container Registry in Azure Web App for Containers across subscriptions

I'm currently trying to set up an Azure Web App for Containers, linking it to a Azure Container Registry that lives inside a different subscription. That's why my initial thought was to use the Private Registrytab inside the Web apps Container Settings to enter the credentials of said Registry.
However when I save and reload the page the settings of the Azure Container Registry tab are now populated and the Private Registry tab is empty. The issue is, that I get now get following error:
2020-01-21 21:51:12.951 ERROR - DockerApiException: Docker API responded with status code=NotFound, response={"message":"pull access denied for cliswebapi, repository does not exist or may require 'docker login': denied: requested access to the resource is denied"}
I assume because no password was stored. How do I configure this properly?
While you use the private registry, the Azure Container Registry is also a private registry, and deploy to Web App for Containers, you need to set the environment variables here:
DOCKER_REGISTRY_SERVER_USERNAME - The username for the ACR server.
DOCKER_REGISTRY_SERVER_URL - The full URL to the ACR server. (For example, https://my-server.azurecr.io.)
DOCKER_REGISTRY_SERVER_PASSWORD - The password for the ACR server.
See more details in If you're using Azure Container Registry, you need to set some app settings.
And if you create multiple containers, all the images must be in the same registry. All in Docker Hub or Azure Container Registry. See more details in All images must use the same registry.
Update:
With the message that you deploy the Web App using the image in the ACR in a different subscription. It seems it's a bug in Web App and you can see the issue in the Github. And the suggestion is that maybe you can use the service principal for the ACR to authenticate and the steps here.
I have spend some time on this issue and figured it out. Here is my solution:
Assuming we are having two subscriptions, let's call them SUB-A and SUB-B, where we are having an Azure Container Registry in SUB-A (called azurebluedev in my example).
Now we'd like to create an App Service in SUB-B that pulls its image of our container registry by using the admin username.
It's critical that you use the correct format under Image and tag in the docker blade when creating the app service. It must follow the format url/image:tag (without https) otherwise you will run into the described problem. I was using image:tag format beforehand which didn't work.
This worked for me!

Azure WebApp container restart issue

I've created an web app running the grafana docker image as this
az group create --name grp-test-container-1
--location "West Europe"
az appservice plan create --name asp-test-container-1
--resource-group grp-test-container-1
--sku B1
--is-linux
az webapp create --resource-group grp-test-container-1
--plan asp-test-container-1
--name app-test-container-1
--deployment-container-image-name grafana/grafana:latest
Then I updated the appsettings in order to pass env variables to the docker run command
az webapp config appsettings set --name app-test-container-1
--settings GF_INSTALL_PLUGINS='grafana-azure-monitor-datasource'
--resource-group grp-test-container-1
Then I need to restart the container in order to get the added env variable in the docker run command.
I tried to restart the web app, stop/start it, change the docker image name and save under the Container Settings.. nothing works
Any suggestions?
Solution/Bug
As Charles Xu said in his answer, to reload the container you need to change the docker image and save in order to make the web app fetch the image again and apply the added env variables.
In my case, I did that change and then looked at the log output but the log never got updated. I waited 5-10 minutes and still no logs were added..
But when I visit the site and browsed to the extension, which were installed by the env varibles, I could se that it all had gone through.
So, to summarize: The log in the Container Settings are not to be trusted, when doing a change those changes might not show up in the log.
I just got off the phone with a support engineer from the Azure web apps/app services team, after having pulled my hair out for several days. Literally.
So in case anyone else having trouble with their app service not responding to restarts, configuration changes, docker image changes, etc, you can try this:
In the Azure Portal navigate to your app service and then "Configuration"->"General settings" and set the "Always on" setting to "On". This setting is by default set to "Off" and will make the app service enter an "idle state" after some time of not receiving any requests.
The only way to trigger the app service out of this idle state is to perform a request towards it. Restarts, config changes, docker image changes, etc., will have no effect until that first request is done. Setting the "Always on" setting to "On" will prevent the app service from entering this idle state, and so it will always be responsive.
In terms of cost this setting change shall have no impact. That is unless you are trying to force as many applications into a single app service plan as possible, where many of them are seldomly in use and hence in an idle state will not use any resources of your app service plan total.
What you need to do is change the image from grafana/grafana:latest into grafana/grafana, just delete the version latest and click the save button below. Then it will work.

Resources