Things You Should Know: Web Apps and Linux


Azure App Service on Linux and Web App for Containers allow you to run your Web App on Linux and Apache. Azure App Service on Linux provides a collection of Microsoft-provided runtime stacks that you can use for your Web App. Web App for Containers makes it possible to use your own Docker container in Azure Container Registry, Docker Hub, or a private registry.

In this post, I will cover both of these offerings. Each topic will indicate which offering(s) it applies to using the following icons.

Applies to Azure App Service on Linux  Applies to Azure App Service on Linux

Applies to Web App for Containers  Applies to Web App for Containers

If a topic applies to both, that will be indicated by the presence of both icons.


In this post:
If you need info, check the FAQ.
If your site doesn't start, check the Docker log.
You can discover and download the latest Docker logs using Kudu.
You shouldn't install components using SSH because they won't persist.
If your container takes a long time to start, increase the start time limit.
Check the return code from "docker run" if your site doesn't start.
The Bash console in Advanced Tools is a different Docker container.
If you're persisting files, only the /home directory is persisted.
If you're persisting files, don't copy data to /home during build.
You can enable and disable storage persistence with an app setting.
Use the X-ARR-SSL header if you need to force SSL for your site.
You don't need (and should not have) SSL support in your app.
To use SSH, your Docker image needs special sauce.
You can only expose one port to the outside world.
If a feature is missing in the portal, it's not available on Linux.
Don't use df to find your disk space usage.
To prevent down-time when you update your code, use Continuous Deployment.
If you don't see a feature you want, you can request the feature.
If you're deploying using Web Deploy, set WEBSITE_WEBDEPLOY_USE_SCM to false.

If you need info, check the FAQ.
Applies to Azure App Service on Linux Applies to Web App for Containers

The FAQ for Azure App Service on Linux and Web App for Containers is a great resource to get your questions answered. Our product team (the folks who build our services) regularly updates the FAQ as new features are added or as they encounter customer questions.

A few of the items in this post are included in the FAQ. In those situations, we will provide information here and also point you to the FAQ.

Back to Top

If your site doesn't start, check the Docker log.
Applies to Web App for Containers

We log useful information into the Docker log that can help you troubleshoot your site when it doesn't start or if it's restarting. We log a lot more than you might be used to seeing in a Docker log, and we will continue to work on making this logging more useful.

You can find the Docker log in the /LogFiles directory. You can access this via the Kudu (Advanced Tools) Bash console, by using an FTP client to access it, or by using our API to download the current logs. (See "You can discover and download the latest Docker logs using Kudu" in this post for info on that.) The naming convention for the Docker log is YYYY_MM_DD_RDxxxxxxxxxxxx_docker.log.

Note that if you try and download the Docker log that is currently in use using an FTP client, you may get an error because of a file lock. In that case, you can download it using our API (see "You can discover and download the latest Docker logs using Kudu" in this post) or you can use "tail" in the console to view it. (Our API gets you the current Docker log, so if you want to review a past log, use the "tail" option.)

To view the Docker log using tail, access the console, switch into the LogFiles directory, and run this command:

tail 2017_09_05_RD*0FA_docker.log

In this example, I'm viewing the Docker log for September 5. Note that I'm also using a wildcard replacement for the machine ID (the RD number) so that I don't have to type all the characters.

Tip: You can pipe the output of tail to a new file in case you want to download it. Simply append "> filename.txt" to the command above.

Back to Top

You can discover and download the latest Docker logs using Kudu.
Applies to Web App for Containers

We have an API that allows you to easily see the current Docker log details (such as the filename, etc.) and also download the current Docker logs in Zip format.

To see details on the current Docker logs in JSON format, you can use this URL:

https://[sitename].scm.azurewebsites.net/api/logs/docker

You can get to this easily by going to Advanced Tools (Kudu) and then appending "/api/logs/docker" to the URL. The output of this will be a JSON response with the most relevant and current Docker logs.

If you want to download the logs shown in the above API in Zip format, append "zip" to the URL. For example:

https://[sitename].scm.azurewebsites.net/api/logs/docker/zip

We will be adding a link to download the logs to the Kudu home page soon so that you don't have to manually browse to the API.

Back to Top

You shouldn't install components using SSH because they won't persist.
Applies to Web App for Containers

You can SSH into your app container and install components. However, when your site is restarted, anything that you install will be gone. Why is that? That's the way Docker works. When your site starts, we run your Docker image and create a Docker container. Your app runs inside of that container, and the file system contains only what is in the Docker image. If your Docker image doesn't install a particular component, it won't be there when your container starts.

If you want to install a particular component, make sure that you do it in a Dockerfile so that the component is included in your Docker image. See this documentation for full information on how to do that.

Back to Top

If your container takes a long time to start, increase the start time limit.
Applies to Web App for Containers

When we start your container, we'll wait a while for it to start and initialize. We consider the startup to be successful once the container is running and once we get a response to a ping so that we know it's ready to respond to HTTP traffic. We'll wait 230 seconds for that to happen. If we don't have a successful start within 230 seconds, we'll assume there's a problem and we'll stop the container.

We realize that some containers might need more time than that to start, so we allow you to increase that 230 second wait time up to a limit of 600 seconds. To configure that, add an app setting called WEBSITES_CONTAINER_START_TIME_LIMIT and set it to the number of seconds you would like for us to wait for your container to start (up to a maximum of 600) as shown in the image below.

 

Configuring Container Start Time Limit

Back to Top

Check the return code from "docker run" if your site doesn't start.
Applies to Web App for Containers

If your site doesn't start, checking the return code from the "docker run" command is a good first step. As stated above, we don't consider your container to be "started" until it is ready to respond to HTTP requests. That means that there are situations where your container actually does start successfully, but it doesn't respond to an HTTP request and is considered not ready.

Here's a snippet from a Docker log that illustrates an interesting problem.

2017-09-14 19:26:22.494 INFO  - Starting container for site
2017-09-14 19:26:22.496 INFO  - docker run -d -p 52879:80 --name customer-webapp . . .
2017-09-14 19:26:24.271 INFO  - docker run returned: STDOUT>> c73ac7c0d7d2c1726d7a95929e591703d7c39eb7e7f314210ad5b4064f433762
. . .
2017-09-14T19:26:34.628607412Z { engine: 'joenode', port: '3000', pid: 5 }
2017-09-14 19:30:14.428 ERROR - Container customer-webapp_0 for site customer-webapp did not start within expected time limit. Elapsed time = 230.0443067 sec>

I have truncated much of this output, but what you can see here is that the "docker run" command was run and two seconds later, you see a long, hexadecimal string as the return code. (This is on the third line of the log.) That hexadecimal string is the container's unique identifier, and the fact that we have a unique identifier for the container means that the container actually did start. However, at the end of the log, we see a message that the container did not start within the expected time limit.

Since we know that the container started and we also know that Web App for Containers doesn't consider the container to be started unless it's ready to respond to HTTP requests, we can conclude that the issue here is that the container is not responding to requests on port 3000. (Notice that the Node process is listening on port 3000 as shown in the next to the last line.) There are two solutions to this issue:

  1. Use the EXPOSE instruction in your Dockerfile to expose port 3000.
  2. Use the WEBSITES_PORT app setting with a value of "3000" to expose that port.

Back to Top

The Bash console in Advanced Tools is a different Docker container.
Applies to Azure App Service on Linux Applies to Web App for Containers

We offer a Bash console in Advanced Tools (also called "Kudu") that you can use to browse directory structure, etc. It's important to realize that this console is running inside of the Kudu Docker container. This is not the same container that your app is running in, so if you look at files and directories here, they won't reflect your app. The only exception to that is the /home directory. That directory is, by default, mounted from Azure Storage, and it's the same location in both the Kudu container and your app's container.

Back to Top

If you're persisting files, only the /home directory is persisted.
Applies to Web App for Containers

By default, we don't persist files in your site. However, if you need to persist files, you can enable App Service Storage (see "You can enable and disable storage persistence with an app setting"). If you enable this, we mount the /home directory to Azure Storage. If your app is restarted, any files saved within the /home directory and sub-directories will persist. However, any files or directories outside of the /home directory will not be persisted between site recycles. This can impact you in a couple of different ways.

  • If you use npm, apt, or similar to install something from the console after your app starts, once the app restarts, whatever you installed will be gone.
  • If you save files outside of the /home directory, if your app restarts, those files will be gone.

If you need an extension or other component for your app to run, make sure that you install it via your Dockerfile. That way, it will be available always. If you need to persist files that your app is creating, make sure that you write them into the /home directory structure.

For more information on creating your own container for use with Web App for Containers, see our documentation.

Back to Top

If you're persisting files, don't copy data to /home during build.
Applies to Web App for Containers

As is detailed in the previous and next topics, you can persist the /home directory using an app setting and we'll mount /home to Azure Storage. It's important to understand that when we do that, we will overwrite anything that's in the /home directory with the content from the Azure Storage location. (For a brand new app, we will remove what's currently in /home and the /home directory will then be empty.)

If you copy data to the /home directory in the build phase of your Docker image, that data will be removed when the Docker container is started. Therefore, you should make sure that any data you write to the file system in your build phase is written outside of the /home directory structure. (Again, this only applies if you are persisting files.)

Back to Top

You can enable and disable storage persistence with an app setting.
Applies to Web App for Containers

You can use an app setting called WEBSITES_ENABLE_APP_SERVICE_STORAGE to control whether or not the /home directory of your app is mapped to Azure Storage. If you need files to be persisted in scale operations or across restarts, you should add this app setting and set it to "true". If you don't require file persistence, you can set this app setting to false.

The absence of this app setting will result in the setting being "true". In other words, if this app setting does not exist in your app, you will see the /home directory mapped to Azure Storage. The app setting will be missing if you created your app while Web App for Containers was in public preview or if someone has deleted the app setting.

Keep in mind that if you enable App Service Storage, when an Azure Storage changeover occurs (which does happen periodically), your site will restart when the storage volume changes.

Note: If App Service Storage is not enabled, any files written into the /home folder will not be persisted across instances (in the case of a scale out) or across restarts.

Even if storage persistence is disabled, the /home directory will be mapped to Azure Storage in the Kudu (Advanced Tools) container. That way, the /home/LogFiles directory will persist between restarts and scale out operations in the Kudu container. Therefore, if you need to get Docker logs or other logs, always use the Kudu Bash console instead of using SSH to access your app's container. (See this for more information on how to get the latest Docker logs from Kudu.)

Note: If you set this app setting on an Azure App Service on Linux app using a built-in image, it will have no impact.

Back to Top

Use the X-ARR-SSL header if you need to force SSL for your site.
Applies to Azure App Service on Linux Applies to Web App for Containers

You can use a .htaccess file to enforce SSL on your site. Many developers already know how to do this, and most techniques rely on checking for an HTTPS request and redirecting the request to HTTPS if it isn't an SSL request. This won't work for Azure App Service on Linux or Web App for Containers because we terminate SSL at the front-end. That means that all of the requests that get to your app container are going to be HTTP (not HTTPS) from our front-end to your app. (Don't worry. Any network traffic that can be intercepted is going to be encrypted if you use SSL.)

The correct way to check for an SSL request is to check the X-ARR-SSL header. We set this if the request comes into our front-end as an SSL request. For details on how to do that, see this blog post.

Back to Top

You don't need (and should not have) SSL support in your app.
Applies to Azure App Service on Linux Applies to Web App for Containers

As pointed out above, we terminate SSL at the front-ends. That means that SSL requests never get to your Web App. That's good news for you because it means that you don't need to (and should not) implement any support for SSL into your app. Also as stated above, it's important to understand that the front-ends where SSL is terminated are inside of our Azure data centers. If you use SSL with your site, your traffic across the Internet will always be safely encrypted.

Back to Top

To use SSH, your Docker image needs special sauce.
Applies to Web App for Containers

We provide the ability to SSH into your app, but if you're using a custom container, you need to take additional steps in order to add this ability to your app. We've provided all the steps necessary here.

Back to Top

You can only expose one port to the outside world.
Applies to Web App for Containers

Web App for Containers currently allows you to expose only one port to the outside world. That means that your container can only listen for HTTP requests on a single port. Some apps need multiple ports. For example, you might have one port that is used for requests into the app and a separate port that is used for a dashboard or admin portal. As of today, that configuration isn't possible in Web App for Containers.

We will attempt to detect which port to bind to your container, but you can also use the WEBSITES_PORT app setting and configure it with a value for the port you want to bind to your container.

Back to Top

If a feature is missing in the portal, it's not available on Linux.
Applies to Azure App Service on Linux Applies to Web App for Containers

Azure App Service has a rich feature-set, but not all of those features are currently available for Linux apps. We're working on adding new features all the time, and once new features are added, they'll appear on the menu in the Azure portal. If you see that a particular feature is missing from the menu for your Linux apps, it's simply because we haven't added that feature yet.

Back to Top

Don't use df to find your disk space usage.
Applies to Azure App Service on Linux Applies to Web App for Containers

You're probably used to using "df" to find out disk space in your volumes. You can certainly do that in Azure App Service on Linux and Web App for Containers, but what you'll see isn't really going to be as helpful as you might think.

Assuming you are persisting files in the /home directory (which is currently the default), you will have a quota based on your pricing tier. However, if you use "df", the disk space you see won't reflect that quota. If you want to find out your disk usage, use Quotas in your Web App's menu, File System Storage in the App Service Plan's menu, or use the REST API to find your usage.

Back to Top

To prevent down-time when you update your code, use Continuous Deployment.
Applies to Web App for Containers

If you update your code, push a new Docker image, and then restart your site manually to pick up that change, you're going to experience some down-time while we pull the new image and start your container. You can avoid that by using the Continuous Deployment feature.

When you use Continuous Deployment, any time you push a new Docker image to your registry, Web App for Containers will pick up that change automatically. We'll pull the image and start the container, and we'll wait until that new container is running and ready for HTTP requests before we switch over to it. During that time, your old image will continue to serve requests into your app.

For more information on Continuous Deployment, see our documentation on it.

Back to Top

If you don't see a feature you want, you can request the feature.
Applies to Azure App Service on Linux Applies to Web App for Containers

If you want a feature that isn't currently available, please feel free to request the feature in our Web Apps Feedback forum. Please make sure to put "[Linux]" in the title so that we'll know it applies to App Service on Linux and Web App for Containers.

Back to Top

If you're deploying using Web Deploy, set WEBSITE_WEBDEPLOY_USE_SCM to false.
Applies to Azure App Service on Linux Applies to Web App for Containers

You can use Visual Studio to deploy to App Service on Linux and Web App for Containers using Web Deploy. However, when you do, you want to make sure that the endpoint for deployment isn't the Kudu container. To configure that, add an app setting to your app with a name of WEBSITE_WEBDEPLOY_USE_SCM and set the value to false.

Back to Top


Comments (0)

Skip to main content