文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Docker-dnmp环境搭建

2023-09-01 21:57

关注

目录

本片文章搭建的环境是 nginx1.19 + php7.4 + php8.2 + mysql5.7 + mysql8.0 + redis,多版本 php 和多版本 mysql。
这里就直接使用 docker-compose 搭建环境,也可以找到镜像创建容器再关联映射端口部署。

资源包下载地址
参考文章:docker-compose使用nginx+php+mysql+redis部署fastadmin

1、dnmp目录结构

..env# 配置参数├── docker-compose.yml# docker-compose文件├── mysql57│   ├── conf│   │   └── my.cnf│   └── log│       ├── mysqld.log│       ├── tallylog│       └── yum.log├── mysql80│   ├── conf│   │   └── my.cnf│   ├── data# mysql8.0数据目录(我这里没有挂载)│   └── log├── nginx│   ├── conf│   │   ├── default.conf│   │   ├── php.conf│   └── logs│       ├── access.log│       └── error.log├── php74│   ├── Dockerfile# php7.4 Dockerfile文件│   └── conf│       ├── ini│       │   ├── conf.d│       │   │   ├── docker-php-ext-mysqli.ini│       │   │   ├── docker-php-ext-pdo_mysql.ini│       │   │   └── docker-php-ext-sodium.ini│       │   ├── php.ini-development│       │   └── php.ini-production│       └── php-fpm.d│           ├── docker.conf│           ├── www.conf│           ├── www.conf.default│           └── zz-docker.conf├── php824│   ├── Dockerfile# php8.2.4 Dockerfile文件│   ├── conf│   │   ├── php-fpm.conf│   │   └── php.ini│   ├── data│   │   └── composer│   └── logs│       ├── fpm.slow.log│       └── php.error.log└── redis    ├── redis.cnf    └── redis.conf

2、.env 配置文件

我只简单配置了 工作目录docker环境目录,可以根据需要把 docker-compose.yml 中容器参数放到这边。

## 项目目录/工作目录#PROJECT_DIR=/Users/yunsanmu/work/project## 当前docker开发环境目录#DEV_ENV_DIR=/Users/yunsanmu/dev-env

3、docker-compose.yml

为了方便操作,一般都会把容器的配置文件、日志文件等挂载映射。端口映射根据自己需要

version: "2.1"services:    nginx:        image: nginx:1.19.1-alpine        container_name: nginx        ports:            - "80:80"        volumes:            - ${PROJECT_DIR}:/usr/share/nginx/html            - ${DEV_ENV_DIR}/nginx/conf:/etc/nginx/conf.d            - ${DEV_ENV_DIR}/nginx/logs:/var/log/nginx        networks:            - lnmp-network    php74:        container_name: php74        build: ./php74 # 这个目录放上我们刚才做好的定制化php的Dockerfile        ports:            - "9001:9000"        volumes:            - ${PROJECT_DIR}:/www:rw            - ${DEV_ENV_DIR}/php74/conf/ini:/usr/local/etc/php            - ${DEV_ENV_DIR}/php74/conf/php-fpm.d:/usr/local/etc/php-fpm.d        restart: always        links:            - mysql57        networks:            - lnmp-network    php824:        container_name: php824        build: ./php824        ports:            - "9002:9000"        volumes:            - ${PROJECT_DIR}:/www/:rw            - ${DEV_ENV_DIR}/php824/conf/php.ini:/usr/local/etc/php/php.ini:ro            - ${DEV_ENV_DIR}/php824/conf/php-fpm.conf:/usr/local/etc/php-fpm.d/www.conf:rw            - ${DEV_ENV_DIR}/php824/logs:/var/log/php            - ${DEV_ENV_DIR}/php824/data/composer:/tmp/composer        restart: always        networks:            - lnmp-network    mysql57:        image: mysql/mysql-server:5.7.28        container_name: mysql57        ports:            - "3307:3306"        volumes:            - ${DEV_ENV_DIR}/mysql57/conf/my.cnf:/etc/my.cnf:ro            # - ${DEV_ENV_DIR}/mysql57/data:/var/lib/mysql/:rw # 这里我就不挂载了,有需要到容器里看            - ${DEV_ENV_DIR}/mysql57/log:/var/log/:rw        environment:            - MYSQL_ROOT_PASSWORD=root        restart: always        networks:            - lnmp-network    mysql80:        image: mysql:8.0        container_name: mysql80        ports:            - "3308:3306"        volumes:            - ${DEV_ENV_DIR}/mysql80/conf/my.cnf:/etc/my.cnf:ro            # - ${DEV_ENV_DIR}/mysql80/data:/var/lib/mysql/:rw            - ${DEV_ENV_DIR}/mysql80/log:/var/log/:rw        environment:            - MYSQL_ROOT_PASSWORD=root        networks:            - lnmp-network    redis:        image: redis:5.0.3-alpine        container_name: redis        ports:            - "6379:6379"        volumes:            - ${DEV_ENV_DIR}/redis/redis.cnf:/etc/redis.conf:ro        restart: always        entrypoint: [ "redis-server", "/etc/redis.conf" ]        networks:            - lnmp-networknetworks:    lnmp-network:        driver: bridge        ipam:            driver: default

由于我的电脑是 mac 的 m1 芯片 所以我这里使用的都是支持linux/arm64/v8 的镜像。
请添加图片描述

MySQL5.7的最新镜像就是不支持 linux/arm64/v8 平台,创建容器会报如下警告:

WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested

我这里使用 mysql/mysql-server:5.7.28 替代。

4、dockerfile

dockerfile 是自定义镜像的一套规则,由多条指令构成,在docker-compose.yml 中通过 build 参数引入。 上面的 docker-compose.yml 比较简单,我只对两个版本的PHP写了 dockerfile,其他的都只在 compose 中使用image,没有过多配置。

php7.4 的 dockerfile:

# 该装的都装上 # 版本7.4FROM php:7.4-fpm # composerRUN curl -sS https://getcomposer.org/installer | php \    && mv composer.phar /usr/bin/composer && chmod +x /usr/bin/composer # 各种依赖库和扩展RUN apt-get update \    && apt-get install -y \    vim \    git \    wget \    build-essential \    libmagickcore-dev \    libmagickwand-dev \    imagemagick \    libfreetype6-dev \    libmcrypt-dev \    libpng-dev \    libzip-dev \    libwebp-dev \    autoconf \    pkg-config \    gcc \    make \    zlib1g \    zlib1g-dev \    && docker-php-ext-configure gd  --with-webp=/usr/include/webp --with-jpeg=/usr/include --with-freetype=/usr/include/freetype2/ \    && docker-php-ext-install -j$(nproc) gd iconv pdo pdo_mysql pdo_odbc mysqli bcmath calendar exif gettext sockets dba  pcntl  shmop sysvmsg sysvsem sysvshm zip \    && pecl install redis-5.3.7 \    && pecl install imagick \    && pecl install mcrypt \    && docker-php-ext-enable redis imagick mcrypt \# 这句很重要,如果和你的nginx用户不同会导致你的服务起不来RUN groupadd www && useradd -g www www # 如果你需要别的扩展,还可以再加

php8.2.4 的 dockerfile:

# 该装的都装上# 版本8.2.4FROM php:8.2.4-fpm# composerRUN curl -sS https://getcomposer.org/installer | php \    && mv composer.phar /usr/bin/composer && chmod +x /usr/bin/composer# 各种依赖库和扩展RUN apt-get update \    && apt-get install -y \    vim \    git \    wget \    build-essential \    libmagickcore-dev \    libmagickwand-dev \    imagemagick \    libfreetype6-dev \    libmcrypt-dev \    libpng-dev \    libzip-dev \    libwebp-dev \    autoconf \    pkg-config \    gcc \    make \    zlib1g \    zlib1g-dev \    && docker-php-ext-configure gd  --with-webp=/usr/include/webp --with-jpeg=/usr/include --with-freetype=/usr/include/freetype2/ \    && docker-php-ext-install -j$(nproc) gd iconv pdo pdo_mysql mysqli bcmath calendar exif gettext sockets dba  pcntl  shmop sysvmsg sysvsem sysvshm zip \    && pecl install redis-5.3.7 \    && pecl install imagick \    && pecl install mcrypt \    && docker-php-ext-enable redis \    && docker-php-ext-enable imagick \    && docker-php-ext-enable mcrypt# 这句很重要,如果和你的nginx用户不同会导致你的服务起不来RUN groupadd www && useradd -g www www# 如果你需要别的扩展,还可以再加

5、启动

进入 docker-compose.yml 所在的目录,创建镜像那一步就直接跳过了,执行 docker-compose up -d 启动如下:

yunsanmu@yunsanmudeMacBook-Pro ~ % cd dev-env yunsanmu@yunsanmudeMacBook-Pro dev-env % docker-compose up -dStarting nginx   ... doneStarting redis   ... doneStarting php824  ... doneStarting mysql80 ... doneStarting mysql57 ... doneStarting php74   ... doneyunsanmu@yunsanmudeMacBook-Pro dev-env % 

打开docker 客户端如下图:
启动相关命令:

docker-compose up -d               # 创建并启动某个容器docker-compose down                # 停止并删除所有容器、网络、镜像等docker-compose stop   # 停止所有容器docker-compose start               # 启动所有容器docker-compose restart# 重启所有容器docker-compose rm# 删除容器(删除前必须关闭容器,执行stop)

启动完成后需要做一些操作,mysql默认root账号是没有远程连接权限,先通过命令行在mysql5.7和mysql8.0赋予root用户远程权限,生产环境添加专门的远程账号。

通过docker 客户端进入mysql57和mysql80容器内,都执行一遍下面的命令:

sh-4.2# mysql -uroot -pEnter password: mysql> use mysql;Database changedmysql> update user set host = '%' where user = 'root';Query OK, 1 row affected (0.03 sec)Rows matched: 1  Changed: 1  Warnings: 0mysql> flush privileges;Query OK, 0 rows affected (0.01 sec)mysql> exit

6、测试

下面的测试显示的都是成功的流程,如果遇到相同问题参考下面的解决方法,其他问题自行百度。

进入nginx配置文件目录添加两个配置文件:php74.confphp82.conf,并且在项目目录下创建两个文件夹:php74php82,分别测试不同版本PHP。

├── nginx│   ├── conf│   │   ├── default.conf│   │   ├── php74.conf│   │   ├── php82.conf
├── project│   ├── php74│   │   ├── index.php│   ├── php82│   │   ├── index.php

php74.conf :

server {    listen  80;    server_name www.php74.com;    location / {        root    /usr/share/nginx/html/php74;        index   index.html index.htm index.php;        if (!-e $request_filename) {            # rewrite ^.*$ /index.php last;            rewrite ^/(.*)$ /index.php/$1 last;        }    }    location ~ \.php$ {        fastcgi_pass    php74:9000;        fastcgi_index   index.php;        fastcgi_param   SCRIPT_FILENAME /www/php74/$fastcgi_script_name;        include         fastcgi_params;    }}

php82.conf :

server {    listen  80;    server_name www.php82.com;    location / {        root    /usr/share/nginx/html/php82;        index   index.html index.htm index.php;        if (!-e $request_filename) {            rewrite ^/(.*)$ /index.php/$1 break;            # rewrite . /index.php last;        }    }    location ~ \.php$ {        fastcgi_pass    php824:9000;        fastcgi_index   index.php;        fastcgi_param   SCRIPT_FILENAME /www/php82/$fastcgi_script_name;        include         fastcgi_params;    }}

修改 hosts,添加以下内容:

127.0.0.1       www.php74.com127.0.0.1       www.php82.com

虚拟域名访问:

mysql5.7、mysql8.0和redis连接测试,编辑两个域名下的index.php文件,添加相同测试代码,测试连接:
php74/index.php:

// redis 测试$redis = new \Redis();$redis->connect('redis',6379);echo "redis is running: ".$redis->ping();echo '
'
;// mysql5.7 测试try { # 连接的host要注意,与./nginx/default.conf中的php连接一样,不是ip,是docker-compose中配置的容器名,container_name $dsn = "mysql:host=mysql57;dbname=mysql;"; $username = "root"; $password = "root"; $db = new PDO($dsn, $username, $password); $sql = "SELECT * FROM user"; $stmt = $db->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); var_dump($result);} catch (PDOException $e) { echo $e->getMessage() . "
"
; exit;}echo '
'
;// mysql8.0 测试try { # 连接的host要注意,与./nginx/default.conf中的php连接一样,不是ip,是docker-compose中配置的容器名,container_name $dsn = "mysql:host=mysql80;dbname=mysql;"; $username = "root"; $password = "root"; $db = new PDO($dsn, $username, $password); $sql = "SELECT * FROM user"; $stmt = $db->prepare($sql); $stmt->execute(); $result = $stmt->fetchAll(PDO::FETCH_ASSOC); var_dump($result);} catch (PDOException $e) { echo $e->getMessage() . "
"
; exit;}

再次访问虚拟域名:

1、PHP8 打不开

报错:

[error] 26#26: *1 rewrite or internal redirection cycle while processing "/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/index.php/", client: 172.28.0.1, server: www.php82.com, request: "GET / HTTP/1.1", host: "www.php82.com"2

修改nginx配置文件的反向代理:

错误配置if (!-e $request_filename) {    rewrite ^/(.*)$ /index.php/$1 last;}正确配置,替换{}内容:rewrite ^/(.*)$ /index.php/$1 break;或rewrite . /index.php last;

2、MySQL 不允许主机连接到此MySQL服务器

报错:

Host '172.28.0.6' is not allowed to connect to this MySQL server

解决方法: 进入容器执行以下命令。

mysql> use mysql;mysql> update user set host = '%' where user = 'root';mysql> flush privileges;mysql> exit

执行第二个命令时可能会出现 Duplicate entry ‘%-root‘ for key ‘PRIMARY‘ 错误,参考:MySql出现ERROR 1062 (23000): Duplicate entry ‘%-root‘ for key ‘PRIMARY‘

3、Mysql 无法连接

错误:

Error!: could not find driver

原因:
当我们使用 navicat 连接 mysql 时是在容器外进行操作,是用 ip+映射端口 连接;当在 php 代码中使用 pdo 连接 mysql 是在 php 容器内部连接mysql 容器,所以是 容器名+3306端口 连接。

解决办法:

$conn = new PDO('mysql:host=容器名;dbname=数据库;port=端口','用户','密码');

来源地址:https://blog.csdn.net/weixin_43844718/article/details/129883644

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯