A method to run multiple applications in single App Service
Published Jan 10 2023 11:20 PM 4,085 Views
Microsoft

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.

 

 

 

 

 

Co-Authors
Version history
Last update:
‎Jan 04 2023 05:40 PM
Updated by: