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"