A method to run multiple applications in single App Service

This post has been republished via RSS; it originally appeared at: New blog articles in Microsoft Community Hub.

Sometimes we want to have applications developed in various languages in one App Service. There is a solution - Docker Compose. However, it is still in Preview status, so it is not recommended to use it in Production environment. There are also some limitations. In this article, I would like to use a sample app service to introduce a method to do the same thing by using nginx and custom docker container.

 

Note

The current method does not obey the recommendation of Docker that a docker container should host only one service, and we actually recommend customers use Azure Container App for hosting multiple applications.

 

Design

We will create a Docker container to have nginx installed and use it as a reverse proxy to redirect the request from external to different applications.

yorkzhang_0-1672880034568.png

 

The above picture shows that the request comes from outside firstly arrived at the nginx service at port 8082 in the container. If the request url is ending with /php/, the request will be direct to the Apache server listening 80 port. Otherwise, the request will be processed in node express server.

 

Implementation

Firstly, we need to create a Docker image. I use below Dockerfile for creating the image:

 

 

FROM oberd/php-8.0-apache RUN apt-get update && apt-get install -y nodejs npm RUN apt-get -y install nginx RUN echo "ServerName localhost:80" >> /etc/apache2/apache2.conf COPY nginx.conf /etc/nginx/nginx.conf COPY default /etc/nginx/sites-enabled/default #WORKDIR is /var/www/html COPY . /var/www/html/ EXPOSE 8082 RUN chmod 777 /var/www/html/start.sh RUN npm install ENTRYPOINT ["/var/www/html/start.sh"]

 

 

Explanation:
- Use an Apache image container so I do not need to install Apache 8.0.
- Then install node.js, npm and nginx.
- "RUN echo "ServerName localhost:80" >> /etc/apache2/apache2.conf" will configure Apache server to use port 80 to recieve the request.
- Copy modified nginx.conf, defaut files to configure the nginx to use reverse proxy and expected port to receive request.
- Change the start.sh file permission to make sure it can run properly.
- At the end of the Dockerfile, it will launch start.sh file.
Below is the modified part of the nginx.conf:

 

 

server{ listen 8082; server_name _; ### if request is end with /php/..., the request will be directed to 80 port in 127.0.0.1. ### location /php{ proxy_pass http://127.0.0.1:80/; } ### if request is end with /..., the request will be directed to 3000 port in 127.0.0.1. ### location /{ proxy_pass http://127.0.0.1:3000/; } }

 


Below is the modified default file which change the nginx default port to 8081 to avoid port conflicts with Apache which uses port 80.

 

 

## # You should look at the following URL's in order to grasp a solid understanding # of Nginx configuration files in order to fully unleash the power of Nginx. # http://wiki.nginx.org/Pitfalls # http://wiki.nginx.org/QuickStart # http://wiki.nginx.org/Configuration # # Generally, you will want to move this file somewhere, and start with a clean # file but keep this around for reference. Or just disable in sites-enabled. # # Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples. ## # Default server configuration # server { listen 8081 default_server; listen [::]:8081 default_server; ...........

 

 

Below is the start.sh file which is created to start the related application and service. Explanations are in comments.

 

#!/bin/bash #restrat nginx to ensure it will use the replaced & modified configuration files service nginx restart #restrat Apache service to ensure it will use the modified configuraton file service apache2 restart #start the express web server node express_demo.js

 


In the example, I simply use php.info file as a PHP application and express_demo.js as a node application. Please refer to below public GitHub repository for the whole project:

yorkzhang/dockernodephp (github.com)


After you create the docker image and use app service to pull it from your docker repository. You need to make sure that a application setting WEBSITES_PORT is set to 8082 as your nginx is listening to 8082.

 

This example is just for your reference. Actually, to host a PHP application, you do not need to have a separated Apache service but just need to use the existing nginx web server. You may refer to below document for setting this:
PHP FastCGI Example | NGINX

 

However, purely using Nginx as a reverse proxy is totally OK as you can have flexibility to choose other applications' web servers.

 

 

 

 

 

Leave a Reply

Your email address will not be published. Required fields are marked *

*

This site uses Akismet to reduce spam. Learn how your comment data is processed.