详细:docker手动部署lnmp以及记录遇到的问题

一、基本思路(背景)

部署时间:2024.04.25
主机为deepin 20.9
安装好docker,从官网下载nginx php mysql三个镜像
设置并启动相应三个容器,并配置portainer

二、安装docker

Debian
系统版本 (系统代号)
Debian 12.x (bookworm)
Debian 11.x (bullseye)
Debian 10.x(buster)
Debian 9.x(stretch)
Debian 8.x(jessie)
Debian 7.x(wheezy)
Debian 6.x(squeeze)

.安装docker-ce
$sudo apt install docker-ce -y
.查看安装好的docker版本

docker version

docker -v

9.免sudo 使用docker
为了避免次次都使用sudo对docker daemon进行访问 这里设置为免sudo访问docker模式


cat /etc/group | grep docker
没有就创建docker用户组
sudo groupadd docker
用户加入到用户组
sudo usermod -aG docker $USER
检查是否有效
cat /etc/group
重启docker-daemon
sudo systemctl restart docker
给docker.sock添加权限
sudo chmod a+rw /var/run/docker.sock

三、配置docker mysql
1.$docker pull mysql ##未指定版本的话,自动从hub.docker.com官方下载mysql最新版镜像
2.创建一个mysql volume ##需要长期保存有关数据,创建一个volume挂载映射到mysql容器
$docker volume create mysql_data
3.运行并配置mysql容器
$docker run --name mysql -p 3306:3306 -v mysql_data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql
有关配置参数说明

docker run                        ##新建一个容器
--name mysql                   ##指定容器名字为mysql
-p 3306:3306                   ##指定映射端口,从容器3306端口映射至主机3306端口(哪个在前哪个在后,还有点迷糊)
-v  mysql_data:/var/lib/mysql          ##将本地mysql_data目录映射至容器/var/lib/mysql目录
-e  MYSQL_ROOT_PASSWORD=123456       ##设置mysql的root用户,密码设为123456
-d                                   ##后台启动
mysql                            ##启动本容器所需要用到的镜像名

其他参数配置(等待补充)
--privileged=true ##使容器对映射挂载的文件、目录拥有相关权限(具体作用还不是很明白),放在-v之前

四、安装配置php-fpm

1.下载有关镜像
$ docker pull php:fpm
2.启动php临时容器
这次启动php临时容器的目的主要是为了将有关配置文件cp至本地目录,好做相应修改调整,并在后期再行挂载映射至新容器。
$ docker run --name php-fpm -p 9001:9001 -d php:fpm

php-fpm的默认端口是9000,这里我改为9001,后续将会在相应配置文件中修改有关配置。为什么我要将端口调整至9001,是因为我先安装了portainer,其所用端口就是9000,我担心端口会冲突,所以就调整至9001,但是不是真的会冲突,我也没试验。

3.将php相应配置目录文件cp至本地
首先在本地/home/xxx/www新建目录 ##xxx是主机当前用户名
我是把网站有关目录和php配置文件以及后续nginx配置文件、nginx的log文件将统一放到/home/xxx/www目录下
新建以下目录
html ##用于存放网站文件,即web的根目录
nginx_config ##用于存放nginx相应的配置文件
php_config ##用于存放php相应的配置文件
nginx_log ##用于存放nginx的日志文件
其实还有一个php相应的日志文件,因为我自己没有设置成功,所以这里先不贴了。
php相应的配置文件主要是两个www.conf和php.ini
但后续我发现还有其他的配置文件也可能需要调整,这个后面会讲到。
这是一位博主的方案,后面我会贴上自己的方案

$ cd /home/xxx/www/php_config

$ docker cp php-fpm:/usr/local/etc/php-fpm.d/www.conf www.conf 

复制www.conf到本地的www/config中

查看容器的 containerID

$docker ps -a

进入到正在运行的php-fpm容器中

$docker exec -it containerID /bin/bash

进入到src中会看到2个压缩包

root@e8f61e487bb6:/usr/src#cd /usr/src/
root@e8f61e487bb6:/usr/src#ls -ll
-rw-r--r-- 1 root root 11928820 Dec  4 18:40 php.tar.xz
-rw-r--r-- 1 root root      850 Dec  4 18:40 php.tar.xz.asc
#解压tar.xz文件:先 xz -d xxx.tar.xz 将 xxx.tar.xz解压成 xxx.tar 然后,再用 tar xvf xxx.tar来解包。
root@e8f61e487bb6:/usr/src# xz -d php.tar.xz
root@e8f61e487bb6:/usr/src#ls -ll
-rw-r--r-- 1 root root 139786240 Dec  4 18:40 php.tar
-rw-r--r-- 1 root root       850 Dec  4 18:40 php.tar.xz.asc
root@e8f61e487bb6:/usr/src#tar xvf php.tar
root@e8f61e487bb6:/usr/src#ls -ll
drwxr-xr-x 14 1000 1000      4096 Dec  4 16:12 php-7.3.0
-rw-r--r--  1 root root 139786240 Dec  4 18:40 php.tar
-rw-r--r--  1 root root       850 Dec  4 18:40 php.tar.xz.asc
exit;

回到宿主机的config文件夹中,把容器里面的php.ini复制下来

$ docker cp php-fpm:/usr/src/php-8.3.6/php.ini-production php.ini

这里php-8.3.6根据实际安装的版本来,因为我是自动安装的最新版,当前是php-8.3.6

我的方案,因为后来我发现我在设置php-fpm非默认的9000端口后,除了www.conf和php.ini需要修改zz-docker.conf(位于php-fpm.d目录下),所以我把php整个配置文件目录都cp至本地并再进行挂载映射。

$ cd /home/xxx/www/
$ docker cp php-fpm:/usr/local/etc  php_config/

4.php的有关修改
(1)在本地修改 php.ini 的内容,设置cgi.fix_pathinfo=0(要先删除前面的;注释符):
cgi.fix_pathinfo=0
(2)修改www.conf

user = www-data
gropu = www-data

默认是www-data,但是nginx配置文件中的用户默认为nginx,我是把nginx的配置文件中的用户名修改www-data。如果修改www.conf中的用户名会导致容器启动失败,自己暂时没有找到解决办法。
listen = [::]:9001
为什么这么改,我也不清楚,网上查资料说要这么改的,端口是我自己调整到9001的。
默认是listen = 127.0.0.1:9000
(3)修改zz-docker.conf

[www]
listen = 9000

因为我调整了端口,所以这里我改成
listen = 9001
5.删除临时php-fpm容器

docker stop php-fpm
docker rm php-fpm

6.设置运行新的php-fpm容器
docker run --name php-fpm -p 9001:9001 --link mysql:mysql --privileged=true -v /home/xxx/www/html:/var/www/html -v /home/xxx/www/php_config:/usr/local/etc -d php:fpm
/var/www/html是php-fpm容器中默认的web文件根目录,需要将本地目录映射至容器。
--link mysql:mysql 将php-fpm与mysql容器连接,会在php-fpm容器/etc/hosts中添加mysql容器的地址信息。

五、安装配置nginx
1.下载镜像
$ docker pull nginx
2.运行临时nginx容器
$ docker run --name nginx -p 80:80 -d nginx
这次启动临时容器的目的主要是为了将有关配置文件cp至本地目录,好做相应修改调整,并在后期再行挂载映射至新容器。
3.cp配置文件 nginx.conf default.conf
将配置文件cp至本地目录

cd /home/xxx/www/nginx_config
docker cp nginx:/etc/nginx/nginx.conf  nginx.conf
docker cp nginx:/etc/nginx/conf.d/default.conf  default.conf
cd /home/xxx/www/
docker cp nginx:/var/log/nginx nginx_log/

4.nginx有关配置
(1)nginx.conf
默认user = nginx
我改为user = www-data 与php配置一致。
(2)default.conf配置

server {
    listen       80;
    server_name  localhost;
    #access_log  /var/log/nginx/host.access.log  main;
    location / {
        root   /usr/share/nginx/html;  ##这里是设置nginx的web根目录,也是nginx容器默认的目录
        index  index.php index.html index.htm;  ##这里记得加上index.php
    }

 error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

  location ~ \.php$ {
        root           /var/www/html;    ##这里设置的是php-fpm容器默认的web根目录
        fastcgi_pass   php-fpm:9001;     ##这是php容器名:端口,也可设为php容器ip:端口
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/html/$fastcgi_script_name;
        fastcgi_param  SCRIPT_NAME      $fastcgi_script_name;
        include        fastcgi_params;
    }

5.删除临时nginx容器,并运行建立新nginx容器,并设置与php-fpm连接

docker stop nginx
docker rm nginx

docker run --name nginx -p 80:80 --link php-fpm --privileged=true -v /home/xxx/www/html:/usr/share/nginx/html -v /home/xxx/www/nginx_config/default.conf:/etc/nginx/conf.d/default.conf -v /home/xxx/www/nginx_config/nginx.conf:/etc/nginx/nginx.conf -v /home/xxx/www/nginx_log/:/var/log/nginx -d nginx

在本地html目录中新建index.php进行测试

编辑内容

<?php
phpinfo();
?>

以上顺利运行后,访问localhost,phpinfo测试通过

六、过程中遇到的问题以及几个要点

1.nginx容器在读取和执行映射的根目录html中的文件无权限的问题(临时解决)
网上有的资料说在docker run 中加入 --privileged=true 参数,但我试过好像没有。
我是在主机中设置html及目录内文件所有权限
chmod -R 777 html
简单粗暴,肯定不是一个好办法,但是能跑起来了,网上搜索到的资料好多看不懂,只能这样,好办法有待以后再慢慢找。
2.html静态网页可正常访问,php网页一直报错404 502
查看nginx的error.log日志,有两个错误一直出现
一是如下:

recv() failed (104: Connection reset by peer) while reading response header from upstream

二是如下

connect() failed (111: Connection refused) while connecting to upstream

一直在网上找资料,php.ini,www.conf,default.conf 甚至还有php-fpm.conf等各种配置文件修改,均没有解决。
直到看到一个博主的资料中说到,要看看php-fpm的映射端口是否正常
使用telnet来测试
telnet 172.17.0.4 9001 #php-fpm容器的ip和设置的端口
显示:
unable to connect to remote host:connection refused

正常的显示应是类似:

这下我明白了,这是php-fpm的端口映射不正常,所以nginx是无法调用php了。
但问题出在哪呢?我在php-fpm中的配置文件目录中逐个排查,发现了一个zz-docker.conf的配置文件,我也不清楚它有什么用,但是我在他的配置中发现了这么一个内容:

[www]
listen = 9000

把其改成我自行设置的端口9001

listen = 9001

果然重启相应容器后,php测试通过。

参考文章:

https://www.jianshu.com/p/e6b6268956ec

https://www.cnblogs.com/Jhaiha0/p/13328514.html

还有一些其他网上的资料,记不太清出处了,请大佬们不要怪罪,在此一并感谢。

posted @ 2024-04-27 15:35  糖伯虎点蚊香  阅读(321)  评论(0)    收藏  举报