宿主机Red Hat系
更新系统并安装自动补齐增强包:
dnf update && dnf install -y bash-completion kernel-modules-extra iptables-nft
立即刷新当前终端环境使其生效
source /etc/profile.d/bash_completion.sh
重启系统
reboot
添加docker源
dnf install -y dnf-plugins-core
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
安装并启动基础服务
dnf install -y firewalld docker-ce docker-ce-cli containerd.io
限制 Docker 日志大小(防止撑爆硬盘)
mkdir -p /etc/docker && cat> /etc/docker/daemon.json <<EOF
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
EOF
# 重新启动daemon:
systemctl daemon-reload
启动并启用防火墙…
systemctl start firewalld #开启
systemctl status firewalld # 开启状态
systemctl enable firewalld # 设置开机自启
宿主机对外端口与 NAT 网络配置
# 开启常用端口
firewall-cmd --permanent --zone=public --add-port=80/tcp
firewall-cmd --permanent --zone=public --add-port=443/tcp
# HTTP/3 / QUIC
firewall-cmd --permanent --zone=public --add-port=443/udp
firewall-cmd --permanent --zone=public --add-port=22/tcp
# 核心:允许公共区域的 IP 伪装(NAT转换),同时支持 IPv4 和 IPv6 容器访问外网
firewall-cmd --permanent --zone=public --add-masquerade
# 重载防火墙使规则生效..."
firewall-cmd --reload
开启内核 IP 转发(IPv4 + IPv6 双栈)
cat > /etc/sysctl.conf <<EOF
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv6.conf.default.forwarding = 1
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
EOF
sysctl -p && lsmod | grep bbr
启动 Docker。
systemctl start docker
# 查看运行状态
systemctl status docker
# 启动并设置开机自启
systemctl enable docker
下载 alpine 镜像
docker pull alpine:3.24
列出本地主机上的镜像
docker images
镜像名:标签 删除
docker rmi -f alpine:3.24
删除 容器
docker rm -f alpine
启动容器
docker run -itd \
-p 80:80 \
-p 443:443/tcp \
-p 443:443/udp \
-e TZ=Asia/Shanghai \
--restart=always \
--name alpine \
alpine:3.24 /bin/sh
查看运行的容器
docker ps
进入容器
docker exec -it alpine /bin/sh
容器内安装依赖:
apk update && apk upgrade
apk add --no-cache \
build-base linux-headers perl autoconf automake libtool \
curl pcre-dev zlib-dev git wget mariadb mariadb-client \
php83 php83-fpm php83-mysqli php83-pdo_mysql php83-mbstring php83-json
验证时间
date
如果时间非CST作如下修改
#--------------------修复时间--------------------------------------
apk add --no-cache tzdata
# 1. 创建上海时区的软链接覆盖默认时区
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# 2. 刷新容器内的时区变量
echo "Asia/Shanghai" > /etc/timezone
# 4. 验证时间是否修改成功
date
#-----------------------------------------------------------------
下载geoip2数据库
cd /root && git clone https://github.com/leev/ngx_http_geoip2_module.git
下载libmaxminddb
wget -nc https://github.com/maxmind/libmaxminddb/releases/download/1.13.3/libmaxminddb-1.13.3.tar.gz && tar -zxvf libmaxminddb-1.13.3.tar.gz && cd libmaxminddb-1.13.3
编译libmaxminddb
./configure && make -j$(nproc) && make install && ldconfig
下载/安装/解压 openssl删除已使用文件
cd .. && wget -nc https://github.com/openssl/openssl/releases/download/openssl-4.0.1/openssl-4.0.1.tar.gz && tar -zxvf openssl-4.0.1.tar.gz && rm -rf libmaxminddb-1.13.3.tar.gz openssl-4.0.1.tar.gz
下载/解压 nginx:
wget -nc https://nginx.org/download/nginx-1.30.3.tar.gz && tar -zxvf nginx-1.30.3.tar.gz && cd nginx-1.30.3
添加编译插件:
./configure \
--prefix=/usr/local/nginx \
--conf-path=/etc/nginx/nginx.conf \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-threads \
--with-file-aio \
--with-http_ssl_module \
--with-http_v2_module \
--with-http_v3_module \
--with-http_realip_module \
--with-http_sub_module \
--with-http_gzip_static_module \
--with-http_auth_request_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-stream \
--with-stream_ssl_module \
--with-stream_realip_module \
--with-stream_ssl_preread_module \
--with-compat \
--add-dynamic-module=../ngx_http_geoip2_module \
--with-openssl=../openssl-4.0.1 \
--with-openssl-opt="no-tests" \
--with-cc-opt='-march=native -O3'
#编译/安装 nginx
make -j$(nproc) && make install
#安装wordpress
cd .. && wget -P /usr/local/nginx/html/ https://cn.wordpress.org/latest-zh_CN.zip && unzip /usr/local/nginx/html/latest-zh_CN.zip -d /usr/local/nginx/html/ && mv /usr/local/nginx/html/wordpress/* /usr/local/nginx/html && rm -rf /usr/local/nginx/html/latest-zh_CN.zip /usr/local/nginx/html/wordpress
#删除已使用文件
rm -rf libmaxminddb-1.13.3 nginx-1.30.3 nginx-1.30.3.tar.gz ngx_http_geoip2_module openssl-4.0.1
# 创建目录和设置权限.
mkdir -p /etc/nginx/ssl /etc/nginx/GeoLite2 /var/log/nginx /etc/init.d /run/php-fpm83
touch /var/log/nginx/access.log /var/log/nginx/error.log
chown -R nobody:nobody /usr/local/nginx/html /var/log/nginx
sed -i 's|#pid.*logs/nginx.pid;|pid /var/run/nginx.pid;|g' /etc/nginx/nginx.conf
sed -i 's|#user nobody;|user nobody;|g' /etc/nginx/nginx.conf
sed -i '/user nobody;/a \
load_module /usr/local/nginx/modules/ngx_http_geoip2_module.so;\
load_module /usr/local/nginx/modules/ngx_stream_geoip2_module.so;' /etc/nginx/nginx.conf
sed -i 's|worker_processes\s*1;|worker_processes auto;|g' /etc/nginx/nginx.conf
下载GeoLite2-Country数据
wget -O /etc/nginx/GeoLite2/GeoLite2-Country.mmdb \
https://raw.githubusercontent.com/P3TERX/GeoLite.mmdb/download/GeoLite2-Country.mmdb
GeoIP2 国家识别
sed -i '/http {/a \
# GeoIP2 Country Identification\n map $http_x_forwarded_for $clientRealIp {\n "" $remote_addr;\n ~^(?P<firstAddr>[0-9\\.]+),?.*$ $firstAddr;\n }\n\n geoip2 /etc/nginx/GeoLite2/GeoLite2-Country.mmdb {\n auto_reload 5m;\n $geoip2_data_country_code default=XX source=$clientRealIp country iso_code;\n }\n\n map $geoip2_data_country_code $allowed_country {\n CN yes;\n JP yes;\n HK yes;\n US yes;\n CA yes;\n FR yes;\n default no;\n }' /etc/nginx/nginx.conf
#安装nginx配置文件
vim /etc/nginx/nginx.conf
- server {下的
- location / {添加
if ($allowed_country = no) {
return 404;
}
添加dhparam
curl https://ssl-config.mozilla.org/ffdhe2048.txt > /etc/nginx/ssl/dhparam
修改 PHP-FPM 配置文件
sed -i 's|127.0.0.1:9000|/run/php-fpm83/www.sock|' /etc/php83/php-fpm.d/www.conf
sed -i 's|;listen.owner = nobody|listen.owner = nobody|' /etc/php83/php-fpm.d/www.conf
sed -i 's|;listen.group = nobody|listen.group = nobody|' /etc/php83/php-fpm.d/www.conf
sed -i 's|;listen.mode = 0660|listen.mode = 0660|' /etc/php83/php-fpm.d/www.conf
初始化数据库 MariaDB
mariadb-install-db --user=mysql --datadir=/var/lib/mysql
添加自启动脚本
cat > /entrypoint.sh <<EOF
#!/bin/sh
# 1. 初始化 MariaDB 数据库目录
if [ ! -d "/var/lib/mysql/mysql" ]; then
echo "初始化 MariaDB 数据库..."
mariadb-install-db --user=mysql --datadir=/var/lib/mysql > /dev/null
fi
# 2. 启动 MariaDB(后台运行)
echo "正在启动 MariaDB..."
/usr/bin/mariadbd-safe --user=mysql --datadir=/var/lib/mysql &
# ★★★ 核心优化:等待 MariaDB 真正启动完毕 ★★★
echo "等待 MariaDB 完全启动..."
while ! mysqladmin ping --silent; do
sleep 1
done
echo "MariaDB 已就绪!"
# 3. 修复 PHP-FPM 报错:自动创建缺失的 runtime 目录
echo "检查并创建 PHP-FPM 运行目录..."
mkdir -p /run/php-fpm83
# 4. 启动 PHP-FPM (后台运行)
echo "正在启动 PHP-FPM..."
/usr/sbin/php-fpm83 -D
# 5. 启动 Nginx (前台运行)
echo "正在启动 Nginx..."
exec /usr/local/nginx/sbin/nginx -g "daemon off;"
EOF
# 给脚本赋予可执行权限
chmod +x /entrypoint.sh
退出 容器
#键盘:
Ctrl+P+Q
- 在宿主机上锁定这个位置(最关键)脚本写在 /entrypoint.sh 后,必须在宿主机上通过 docker commit 告诉 Docker:“以后容器开机,就去执行根目录下的这个脚本”。
- 在宿主机执行:docker001/alpine3.24:v1
docker commit --change='ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]' 'CONTAINER ID' 'docker注册用户名/daocker建的库名:标签
#======推送(Push)镜像到云端=========
# 给本地镜像打标签(Tag)
# Docker 规定,上传镜像前必须把镜像名字改成 用户名/仓库名:标签 的格式,否则 Docker 不知道你想往谁的家门口送。在宿主机执行:
docker commit --change='ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]' 'CONTAINER ID' 'docker001/alpine3.24:v1'
#推送(Push)镜像到云端
docker login -u <用户名>
docker push docker001/alpine3.24:v1
#======同步下载(Pull)镜像到本地=========
#在宿主机终端执行登录命令,输入你的账号密码(或者 Access Token):
docker login -u <用户名>
docker pull docker001/alpine3.24:v1
#=====================================
删掉旧容器
docker stop alpine
docker rm -f alpine
docker run -itd \
-p 80:80 \
-p 443:443/tcp \
-p 443:443/udp \
-e TZ=Asia/Shanghai \
--restart=always \
-v /var/log/nginx:/var/log/nginx \
--name alpine \
docker001/alpine3.24:v1
#进入容器
docker exec -it alpine /bin/sh
mysql或MariaDB安全加固:会设置密码,界面1直接回车,界面2选N,剩的都选Y
mysql_secure_installation
root登录:
mysql -u root -p
#创建数据库:
CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
#创建用户
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY '你的安全密码';
#授予权限:
GRANT ALL PRIVILEGES ON wordpress.* TO 'wp_user'@'localhost';
#最后务必刷新权限
FLUSH PRIVILEGES;
#退出:
exit
vi /etc/nginx/nginx.conf
#===========80端口测试=========
location / {
root html;
index index.html index.htm;
}
#---------------修改为-----------------------------------------------
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm83/www.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
root /usr/local/nginx/html;
index index.php index.html index.htm;
#重新加载配置文件,不重启服务
/usr/local/nginx/sbin/nginx -s reload