Deploying a Containerized Nginx and PHP-FPM Stack on CentOS 7

Host System Requirements

Target Operating System: CentOS 7.x
Minimum Resources: 4GB RAM

Installing the Docker Engine

First, update the system repositories and remove any obsolete Docker versions:

sudo yum update -y

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

Install necessary dependencies and add the official Docker repository:

sudo yum install -y yum-utils device-mapper-persistent-data lvm2

sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

Install Docker Community Edition and start the daemon:

sudo yum makecache fast
sudo yum install -y docker-ce
sudo systemctl start docker
sudo systemctl enable docker

Building a Custom Nginx Image

Create a project directory structure for the web server configuration:

mkdir -p /opt/web-stack/nginx
mkdir -p /opt/web-stack/nginx/{conf,logs,html}
cd /opt/web-stack/nginx

Create a Dockerfile to compile Nginx from source. This approach allows for custom modules and specific configurations:

cat <<'EOF' > Dockerfile
FROM centos:7

MAINTAINER devops@example.com

RUN yum install -y wget gcc gcc-c++ make pcre-devel zlib-devel openssl-devel

WORKDIR /usr/local/src

ENV NGINX_VER=1.18.0

ADD http://nginx.org/download/nginx-${NGINX_VER}.tar.gz .

RUN tar -xzf nginx-${NGINX_VER}.tar.gz \
    && cd nginx-${NGINX_VER} \
    && ./configure \
        --prefix=/etc/nginx \
        --sbin-path=/usr/sbin/nginx \
        --conf-path=/etc/nginx/nginx.conf \
        --error-log-path=/var/log/nginx/error.log \
        --http-log-path=/var/log/nginx/access.log \
        --pid-path=/var/run/nginx.pid \
        --lock-path=/var/run/nginx.lock \
        --with-http_ssl_module \
        --with-http_v2_module \
        --with-http_gzip_static_module \
    && make && make install

RUN useradd -M -s /sbin/nologin nginx

RUN mkdir -p /var/log/nginx /etc/nginx/conf.d

EXPOSE 80 443

CMD ["nginx", "-g", "daemon off;"]
EOF

Build the Nginx image:

docker build -t custom-nginx:latest .

Building a Custom PHP-FPM Image

Navigate back to the project root and create the PHP environment directory:

cd /opt/web-stack
mkdir php
cd php

Create the PHP Dockerfile using the official Alpine-based image for a smaller footprint. We will install common extensions like PDO, MySQL, and GD:

cat <<'EOF' > Dockerfile
FROM php:8.1-fpm-alpine

MAINTAINER devops@example.com

RUN apk add --no-cache \
    libzip-dev \
    libpng-dev \
    libjpeg-turbo-dev \
    freetype-dev \
    libxml2-dev

RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) \
    gd \
    pdo \
    pdo_mysql \
    mysqli \
    zip \
    bcmath

RUN apk add --no-cache $PHPIZE_DEPS \
    && pecl install redis-5.3.7 \
    && docker-php-ext-enable redis

WORKDIR /var/www/html

Build the PHP image:

docker build -t custom-php:latest .

Orchestration with Docker Compose

Install Docker Compose to manage the multi-container setup:

sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Create a docker-compose.yml file in the /opt/web-stack directory to define the services:

version: '3.8'

services:
  web:
    image: custom-nginx:latest
    container_name: web_server
    ports:
      - "8080:80"
    volumes:
      - ./nginx/conf/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/conf.d:/etc/nginx/conf.d:ro
      - ./www:/var/www/html
      - ./nginx/logs:/var/log/nginx
    depends_on:
      - app
    networks:
      - app_net

  app:
    image: custom-php:latest
    container_name: php_backend
    volumes:
      - ./www:/var/www/html
    networks:
      - app_net

networks:
  app_net:
    driver: bridge

Configuring Nginx for PHP Processing

Create the necessary configuration files. First, the main Nginx configuration should include the site configs:

mkdir -p /opt/web-stack/nginx/conf.d
cat <<'EOF' > /opt/web-stack/nginx/conf/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/nginx/access.log main;
    sendfile on;
    keepalive_timeout 65;
    include /etc/nginx/conf.d/*.conf;
}
EOF

Next, create a server block configuration file to handle PHP requests via FastCGI:

cat <<'EOF' > /opt/web-stack/nginx/conf.d/default.conf
server {
    listen 80;
    server_name localhost;
    root /var/www/html;
    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass app:9000;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }
}
EOF

Deployment and Verification

Create a test PHP file to verify the environment:

mkdir -p /opt/web-stack/www
echo "<?php phpinfo(); ?>" > /opt/web-stack/www/index.php

Launch the stack using Docker Compose:

cd /opt/web-stack
docker-compose up -d

To apply configuration changes to Nginx, recreate the container:

docker-compose up -d --force-recreate web

Access the server via browser at http://<YOUR_IP>:8080. If the PHP info page loads, the deployment is successful.

Automated Setup Script

The entire process can be automated using a shell script. Below is an abstract representation of such a script to handle the bootstrapping:

#!/bin/bash

# Check for root privileges
if [ "$EUID" -ne 0 ]; then echo "Please run as root"; exit; fi

# Install Docker if missing
if ! command -v docker &> /dev/null; then
    yum install -y yum-utils
    yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
    yum install -y docker-ce docker-compose
    systemctl start docker
fi

# Setup directories
mkdir -p /opt/web-stack/{www,nginx/{conf,conf.d,logs},php}

# Write files (Dockerfiles, configs, etc.)
# ... (File writing logic as described above) ...

# Build and Start
cd /opt/web-stack
docker-compose build
docker-compose up -d

echo "Deployment complete. Visit http://$(hostname -I | awk '{print $1}'):8080"

Tags: docker nginx PHP devops centos

Posted on Wed, 20 May 2026 16:24:58 +0000 by jrobles