[原创] Docker 安装 Lnmp 环境

Docker 安装 Lnmp 环境

日期:2021-11-5

原文链接:https://www.cnblogs.com/sochishun/p/15532133.html

一条龙快速安装流程

如果遇到什么问题,直接拉到文章后面的详解部分查找答案。

第一步:检查主机环境

检查 Docker 服务状态

docker version | docker -v | docker info | docker help # 查看 docker 版本信息等
docker-compose -v
systemctl start docker # 启动 docker 服务

创建 Docker 数据目录

在根目录创建 dockerdata 统一数据目录

mkdir -p /dockerdata/etc/{nginx/conf,php-fpm,mysql}
mkdir -p /dockerdata/var/log/{nginx,php-fpm,mysql}
mkdir -p /dockerdata/var/lib/mysql
mkdir -p /dockerdata/www/{html,backup}
mkdir -p /dockerdata/temp/

第二步:安装 Nginx

拉取镜像并创建容器

拉取镜像

docker pull nginx # 拉取镜像

创建容器

docker run --name nginx80 -p 80:80 -d nginx # 运行容器(测试)
docker exec -it nginx80 /bin/bash # 进入容器管理

Nginx 容器内的目录结构

nginx 容器内主要目录结构

/usr/share/nginx/html/ # 网站根目录
/etc/nginx/nginx.conf # nginx 配置文件
/etc/nginx/conf.d/default.conf # nginx 网站配置文件目录
/var/log/nginx/ # 日志文件目录

主机对应的统一映射目录

mkdir -p /dockerdata/www/html # 创建网站目录
mkdir -p /dockerdata/var/log/nginx/ # 创建日志目录
mkdir -p /dockerdata/etc/nginx/conf/ # 创建 nginx 配置目录

Nginx 容器的目录映射

容器内目录映射到容器外主机目录

docker run --name nginx80 -p 80:80 -v /dockerdata/www/html:/usr/share/nginx/html -d nginx # 运行容器并绑定目录

完整映射命令

docker run --name nginx80 -p 80:80 \
-v /dockerdata/etc/nginx/nginx.conf:/etc/nginx/nginx.conf \
-v /dockerdata/etc/nginx/conf.d:/etc/nginx/conf.d \
-v /dockerdata/www/html:/usr/share/nginx/html \
-v /dockerdata/var/log/nginx:/var/log/nginx \
-d nginx

测试结果

echo "hello nginx" > /dockerdata/www/html/index.html # 创建 index.html 测试文件
curl http://localhost:80/index.html # 测试结果

第三步:安装 php-fpm

拉取镜像并创建容器

拉取镜像

# docker pull php # 默认最新的 php 没有包含 fpm。
docker pull php:8.0.12-fpm # PHP版本号去 https://www.php.net/ 查看

创建容器

docker run --name php9000 -p 9000:9000 -v /dockerdata/www/html:/var/www/html -d php:8.0.12-fpm
docker exec -it php9000 bash

PHP 容器内的目录结构

PHP 容器内主要目录结构

/var/www/html/ # 网站根目录
/usr/local/var/log/ # 日志目录
/usr/local/etc/ # php-fpm 配置文件目录

主机对应的统一映射目录

mkdir -p /dockerdata/www/{html,backup} # 创建网站目录
mkdir -p /dockerdata/var/log/php-fpm/ # 创建日志目录
mkdir -p /dockerdata/etc/php-fpm/ # 创建 php-fpm 配置目录

PHP 容器的目录映射

容器内目录映射到容器外主机目录

docker run --name php9000 -p 9000:9000 -v /dockerdata/www/html:/var/www/html -d php:8.0.12-fpm # 运行容器并绑定目录

完整映射命令

docker run --name php9000 -p 9000:9000 \
-v /dockerdata/www/html:/var/www/html \
-v /dockerdata/var/log/php-fpm:/usr/local/var/log \
-v /dockerdata/etc/php-fpm:/usr/local/etc \
-d php:8.0.12-fpm # 运行容器并绑定目录

测试结果

echo "<?php echo 'hello php';" > /dockerdata/www/html/index.php # 创建 index.php 测试文件
docker exec php9000 bash -c "php index.php" # 测试结果

第四步:配置 Nginx 支持 PHP 脚本

查看 Nginx 容器的 IP

查看 Docker 自动分配的容器内网 IP

docker inspect php9000 # 查到IP地址是 172.17.0.3
docker inspect --format='{{.NetworkSettings.IPAddress}}' php9000

进入 Nginx 容器修改配置文件

进入 Nginx 容器

docker exec -it nginx80 bash # 进入交互模式的容器
nginx -t # 查看配置文件的目录(结果为 /etc/nginx/nginx.conf)

修改 Nginx 配置文件内容

cd /etc/nginx/conf.d/
cp default.conf default.conf.bak # 备份一下
vi default.conf # 打开默认配置文件

修改 Nginx 网站配置文件

# 默认首页新增 index.php
location / {
    index index.html index.htm index.php;
}
# 取消 php 配置的注释,修改 IP 和目录路径。
# IP 可以是主机的外网 IP 也可以是 Docker 容器的 IP,这里用 Docker 容器的 IP。注意:每次重启 Docker 服务后,Docker 分配的内网 IP 可能会改变。所以建议使用外网IP。
# 路径用 php 容器启动时配置的映射路径。
location ~ \.php$ {
    root           html;
    fastcgi_pass   172.17.0.3:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  /var/www/html$fastcgi_script_name;
    include        fastcgi_params;
}

重启 Nginx 服务

nginx -s reload

测试结果

curl http://localhost/index.php

第五步:安装 mysql

拉取镜像并创建容器

拉取镜像

docker pull mysql

创建容器

docker run --name mysql3306 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=iPwd000000 -d mysql

参数说明

-e MYSQL_ROOT_PASSWORD: 设置容器内环境变量,root 账号的密码为 iPwd000000

MySQL 容器内的目录结构

MySQL 容器内主要目录结构

/usr/sbin/mysqld # mysql 启动文件
/var/run/mysqld/mysqld.sock # mysqld.sock 文件
/etc/mysql/conf.d/ # mysql 配置文件目录
/var/log/ # mysql 日志文件目录
/var/lib/mysql/ # mysql 数据文件目录

主机对应的统一映射目录

mkdir -p /dockerdata/var/{log/mysql,lib/mysql} # 创建日志目录和数据目录
mkdir -p /dockerdata/etc/mysql/ # 创建 mysql 配置目录

MySQL 容器的目录映射

容器内目录映射到容器外主机目录

docker run --name mysql3306 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=iPwd000000 -d mysql

完整映射命令

docker run --name mysql3306 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=iPwd000000 \
-v /dockerdata/etc/mysql:/etc/mysql/conf.d \
-v /dockerdata/var/log/mysql:/var/log \
-v /dockerdata/var/lib/mysql:/var/lib/mysql \
-d mysql # 运行容器并绑定目录

进入容器登录 MySQL

docker exec -it mysql3306 bash
mysql -h localhost -u root -p

测试结果

show databases;
select `User`, `Host`, SUBSTRING(authentication_string, 1, 20) as `Password` from mysql.user;

第六步:LNMP 综合测试

创建 test.php 文件

vi /dockerdata/www/html/test.php
100dd # 删除前100行(清空文件内容)

把以下代码复制粘贴到 test.php 文件

<?php
// 注意:这里 IP 要用外网 IP,不要用 127.0.0.1。记得开放主机的 3306 端口。
$dsn = 'mysql:host=1xx.3x.2xx.2xx;port=3306';
$dbuser = 'root';
$dbpwd = 'iPwd000000';
$pdo = null;
echo 'Before connecting...', PHP_EOL;
try {
    $pdo = new PDO($dsn, $dbuser, $dbpwd);
} catch (\PDOException $ex) {
    echo 'Connect Fail: ', $ex->getMessage(), PHP_EOL;
    exit;
}
try {
    $list = $pdo->query('select `User`, `Host`, SUBSTRING(authentication_string, 1, 20) as `Password` from mysql.user;', PDO::FETCH_ASSOC);
    foreach ($list as $row) {
        echo $row['User'], ' | ', $row['Host'], ' | ', $row['Password'], PHP_EOL;
    }
} catch (\PDOException $ex) {
    echo 'SQL ERROR: ', $ex->getMessage(), PHP_EOL;
}
$pdo = null;

测试结果失败

curl http://localhost/test.php

提示数据库连接失败(未发现驱动)有木有,因为还需要安装 php-mysql 扩展等。

docker exec -it php9000 bash # 进入 php 容器
php -m # 查看已安装的 php 扩展(是不是发现没有 pdo_mysql)
ls /usr/local/bin # 查看容器内系统自带的安装和配置工具
# docker-php-ext-install -j$(nproc) bcmath calendar exif gettext sockets dba mysqli pcntl pdo_mysql shmop sysvmsg sysvsem sysvshm # 官方的各个扩展的安装
docker-php-ext-install -j$(nproc) pdo_mysql
docker restart php9000 # 重启容器,重新进入容器执行 php-m,就可以看到新安装的扩展名称了。

测试结果成功

curl http://localhost/test.php

参考材料

扩展知识

Linux 通用命令

cat /etc/os-release | cat /etc/debian_version # 查看发行版本信息
lsof -i:80 # 查看80端口是否被占用
curl http://localhost:80 # 访问本地80端口的网址
wget http://localhost:80 # 下载本地80端口的资源

Docker 常用命令

镜像管理命令

docker images # 查看本地镜像
docker search nginx # 查找镜像
docker pull nginx # 拉取镜像到本地
docker rmi nginx # 移除镜像
docker run --name hi_nginx -p 80:80 nginx # 运行镜像到容器

容器管理命令

docker ps # 列出所有容器
docker run --name hi_nginx -p 80:80 nginx
docker rename hi_nginx my_nginx # 重命名容器
docker stop my_nginx # 停止容器
docker start my_nginx # 启动容器
docker restart my_nginx # 重启容器
docker rm my_nginx # 移除容器
docker exec -it my_nginx /bin/bash # 进入容器(-it 关键词要紧跟着 exec)

镜像运行命令

docker run --name my_nginx -p 81:80 -v /dockerdata/www/html:/usr/share/nginx/html -d nginx
docker run --name my_php -p 9000:9000 -v /dockerdata/www/html:/usr/share/nginx/html -itd php:8.0.12-fpm

参数详解:

--name: 为容器指定一个名称
-p: 添加主机到容器的端口映射(主机端口:容器端口)
-v: 添加主机到容器的目录映射(主机目录:容器目录)(主机目录需提前手动创建)
-i: 以交互模式运行容器,通常与 -t 同时使用
-t: 为容器重新分配一个输入伪终端,通常与 -i 同时使用
-d: 在后台运行容器,并返回容器ID(常驻后台运行)
-e: 设置环境变量
-m: 设置容器使用内存的最大值
--link: 添加链接到另一个容器(这样就可以在当前的容器使用另一个容器里面的服务)
--expose: 开放一个端口或一组端口
ro: 只读权限

容器内配置加速源

# sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list # ubuntu镜像源
sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list # debian镜像源
apt-get clean
apt-get update

容器内安装管理软件

apt-get update # 必须先更新才能安装其他软件,记得设置国内镜像源,不然慢的很
apt-get install -y vim # 安装 vim
apt-get install -y procps # 安装 ps
apt-get install -y net-tools # 安装 netstat
ps -ef | grep "nginx" # 根据名称查看 nginx 进程状态和PID
ps aux | grep "nginx" | greo -v grep # 根据名称查看 nginx 进程是否启动
netstat -anop | grep 0.0.0.0:80 # 根据端口查看 PID

查看进程的启动路径

ps -ef | grep "nginx" # 根据名称查看 nginx 进程的PID(第二列,结果为 1)
netstat -anop | grep 0.0.0.0:80 # 或者根据端口查看 PID(结果为 1/nginx)
ls -l /proc/1/exe # 列出进程的exe文件信息(结果为 /usr/sbin/nginx)

Nginx 容器管理命令

Nginx 常用命令

nginx -h # 查看默认的日志文件和配置文件路径等
nginx -s reload # 重新加载配置文件(优雅地重启nginx服务)
nginx -s quit # 处理完所有请求再停止服务(优雅地停止nginx服务)
nginx -v # 显示版本信息
nginx -V # 显示安装时的所有配置信息
nginx -t # 检测配置文件是否有语法错误(可以查看到配置文件目录)
# 查看配置文件目录的两种方法
nginx -t
ps -ef | grep "nginx"
nginx -V

Nginx 配置管理

nginx -h # 查看配置文件的目录
vi /etc/nginx/conf.d/default.conf # 查看默认访问目录
cd /usr/share/nginx/html

Dockerdata 统一数据目录

Docker 容器到主机的数据映射目录。

目录结构

/dockerdata/
- etc/
  - nginx/
    - nginx.conf # nginx.conf 配置文件
    - conf.d/ # nginx 网站配置目录
  - php-fpm/
    - php-fpm.conf # php-fpm 配置文件
  - mysql
    - mysql.conf # mysql 配置文件
- var/
  - log/
    - nginx/ # nginx 日志目录
    - php-fpm/ # php-fpm 日志目录
    - mysql/ # mysql 日志目录
  - lib/
    - mysql/ # mysql 数据库 datadir 目录
- www/
  - html/
  - backup/
- temp/
  - gitdata/

批量创建目录的 shell 脚本

mkdir -p /dockerdata/etc/{nginx/conf,php-fpm,mysql}
mkdir -p /dockerdata/var/log/{nginx,php-fpm,mysql}
mkdir -p /dockerdata/var/lib/mysql
mkdir -p /dockerdata/www/{html,backup}
mkdir -p /dockerdata/temp/
上一篇:LNMP-nginx配置文件解析


下一篇:lnmp部署