Shared across multiple sites using a single-container nginx and a single-container php (one version)
This article was last updated 149 days ago. The information in it may have developed or changed. If it is invalid, please leave a message in the comment section.

Preface

Why did I write this article? As you know, many application deployments require an LNMP environment. Setting up this environment is neither simple nor difficult. Moreover, there are now various Linux panels that can conveniently provide one-click, one-stop installation. I initially used the Baota Linux panel, and later I also tried the 1Panel panel, both of which are quite good.

Later, mainly because I frequently tinkered with various data transfers, Docker's advantages became apparent when data migration was involved. For example, I suddenly wanted to reuse my old, unused first-generation M1 version of Mac Mini and containerize all my applications for it. At this point, migrating applications that were originally deployed from source code within the BT Panel became very troublesome. Of course, there's another way: directly installing the BT Panel using Docker. However, I personally don't like this approach. I believe in either bare-metal deployment (Linux panels are designed for bare-metal environments) or full containerization, which is why this article came about.

One advantage of the panel is its flexible support for multiple sites, multiple PHP versions, and multiple databases, as shown in the image below:

image.png

Switching databases is straightforward; you just need to change the pointer in the configuration file. Switching PHP versions is indeed very convenient in this regard. Ideally, if I were to use a containerized environment instead, it should achieve the following:
1. Reuse
Just like with a panel, creating a new site only requires adding the corresponding directory (and a site's corresponding conf configuration file).
2. Flexible switching
If you need to change the PHP version, it should be simple and convenient (in seconds).

In summary, you only need to set up one nginx container and one PHP container (one refers to one version, such as PHP 7.4, which will be used below) to use multiple sites simultaneously.

Note: Here's a brief explanation of my philosophy: I rarely use Docker Compose with Docker because my philosophy is reusability. I don't want to create a bunch of containers every time. For example, if I have a MariaDB container, all my applications that need a database and can use MariaDB will use this container, which also makes backups easier. Of course, this only applies to my environment and habits; other environments with application isolation requirements are a different story.

Deploying nginx and php7.4 fpm containers

Now let's get down to business. Next, we'll do some hands-on practice, creating a bridge, an nginx container, and a PHP 7.4 fpm container:

Creating a bridge

Because a bridge named public-net is used below, it needs to be created in advance:

docker network create public-net

Deploying an Nginx container:

docker run --name=nginx -d --restart=always --net=public-net \ -p 9000:80 \ -v /docker/nginx/html:/usr/share/nginx/html \ -v /docker/nginx/conf/conf.d:/etc/nginx/conf.d \ -v /docker/nginx/log:/var/log/nginx \ nginx:latest

Note: Nginx has default files. You cannot directly mount empty folders using the `-v` option. You need to first create a container without the `-v` parameter, copy the files out using a command, delete them, and then recreate the volume using `-v`. Copying files looks like this:

docker cp nginx:/usr/share/nginx/html /docker/nginx/ docker cp nginx:/etc/nginx/conf.d /docker/nginx/conf/

Deploying a container for PHP 7.4 FPM:

docker run --name=php_74 -d --restart=always --net=public-net \ --privileged=true \ -v /docker/nginx/html:/var/www \ php:7.4-fpm

Shared across multiple sites using a single Nginx container and a single PHP 7.4 FPM server.

That basically completes the task. But how do we achieve the reuse and flexible switching we mentioned above?

Key points:
1. Directory Structure:
The directory structure is actually very simple, for example:
The root folder of the site in the nginx container (/usr/share/nginx/html) is mounted in the host machine as /docker/nginx/html. Therefore, the root folder of the PHP container (/var/www) must also be mounted in the host machine as this. The advantage of this is that the file paths of the nginx and PHP containers are consistent, and when nginx creates a new site in the future, it only needs to create the site folder in this mounted directory (/docker/nginx/html), thus achieving the reuse we mentioned earlier.
2. The default.conf file doesn't need to be modified. Each time a new site is created, only a corresponding .conf file needs to be created. Here, we'll use wow.conf as an example, which we'll discuss in another article when setting up a World of Warcraft registration website.

Create a new file named wow.conf in the /docker/nginx/conf/conf.d folder. The configuration script for FastCGI should contain the following:

location ~/ .php { root /var/www; fastcgi_pass php7_4:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME   document_root$fastcgi_script_name;; include fastcgi_params; }

The key to flexible switching lies in this part. Why do we use php:7.4-fpm for our PHP container image? FPM stands for FastCGI Process Manager, meaning this image's PHP supports FastCGI. Because nginx cannot understand the PHP language, when interpretation is needed, it uses FastCGI, based on the network address and port (php7_4:9000) provided by the `fastcgi_pass` parameter to find the PHP container for interpretation. (Why can `php7_4` represent the PHP container's network address? Simply add the `--net=public-net` parameter to both nginx and the PHP container during creation; the specific reasons won't be elaborated here, as that would be too lengthy). `fastcgi_index` specifies the filename to be interpreted, `index.php`. So where is this file located? It's determined by the variable specified by `fastcgi_param`.document_root is used to determine, and The content of the `document_root` variable is determined by the `root /var/www` above (the default value of this is `root html`. This works fine for a standard bare-metal installation via a control panel, but it's no longer suitable for containerized deployments). In fact, for multi-site PHP deployments, this `conf` file is inherently site-specific. Therefore, you don't need to use the `$ document_root` approach; you can directly use the root path name, such as `/var/www/wow`. The `root` line can even be omitted, as follows:

location ~/ .php { fastcgi_pass php7_4:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/wow/fastcgi_script_name;; include fastcgi_params; }

Mission accomplished!

To summarize the key points: Nginx finds PHP at the specified address and port, and then instructs PHP to find and interpret index.php at the specified path. Why can PHP find index.php at the specified path? Isn't this site folder on the Nginx container? Ah, because PHP also mounts that Nginx directory, so it can also find the corresponding site folder.

Also: It is recommended to install all the necessary extensions in the container for your PHP version. I will discuss this in another article.

📌 Content Structure Hints:
This content belongs to "Blog Knowledge MapThis is part of the document; you can view the full content path here: Blog Knowledge Map .
Share this article
All blog content is original; please indicate the source when reprinting! The blog's RSS address is:https://blog.tangwudi.com/feed, welcome to subscribe; if necessary, you can joinTelegram GroupDiscuss the problem together.
No Comments

Send Comment Edit Comment


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠(ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ°Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
Emoticons
Emoji
Little Dinosaur
flower!
Previous
Next