IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> PHP知识库 -> 使用docker搭建LNMP开发环境 -> 正文阅读

[PHP知识库]使用docker搭建LNMP开发环境

宿主机环境

系统:ubuntu 18.04
docker版本:18.03.1-ce

docker的安装请自行参考官方文档

前言

这篇文章用于介绍如何使用docker搭建一个LNMP开发环境,下面我们将会编写Dockerfile,基于官方docker hub镜像,分别构建我们自己的镜像,然后运行。要构建的镜像有:

  • PHP-FPM 7.4
  • Nginx 1.19
  • MySQL 5.7
  • Redis 6.2

为什么不直接使用官方镜像,而是自己再构建一个?
因为官方镜像一般安装的东西都很少,例如PHP-FPM的官方镜像,像redis、mysqli、pdo等等这些常用的扩展都是没有的,还有一些常用的系统命令也没有安装,例如ping、netstat、ps等等。

目录结构

我的项目路径是/home/rockyliang/mydocker,目录结构如下:
在这里插入图片描述

html目录用于存放网页文件和PHP文件,这个目录后面会通过挂载的方式,挂载到 PHP-FPM容器 和 nginx容器 里面去,以便它们可以访问这些文件。

redis目录下有一个redis.conf文件,这是从网上下载的redis配置文件,因为官方的redis镜像默认是没有配置文件的,后面构建redis镜像时,我们会把这个下载的配置文件复制进去。这个文件的下载地址是:
https://raw.githubusercontent.com/antirez/redis/6.2/redis.conf

注意URL里的版本号,因为我们要构建的redis镜像版本是6.2,因此配置文件版本也要用6.2的。

创建网络

因为各个容器之间需要通信,例如PHP-FPM容器需要跟MySQL、Redis容器连通,这样PHP才能查询数据库数据,因此我们先创建一个名为mynet的网络:

sudo docker create mynet

创建好网络后,后续把各个容器加入到这个网络里面来就可以。

构建PHP-FPM镜像

Dockerfile文件

# 从官方基础版本构建
FROM php:7.4-fpm-buster

# 镜像信息
LABEL maintainer="ljfrocky" \
    version="2020.03.30" \
    description="PHP-FPM 7.4"

# 安装install-php-extensions
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/

# 设置系统时区
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 修改debian软件源为国内源
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster main non-free contrib' > /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian-security buster/updates main' >> /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib' >> /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib' >> /etc/apt/sources.list \
    && apt-get update

# 安装常用命令工具包,根据自己的实际需要情况进行安装
# vim: vi、vim
# procps: ps
# iputils-ping: ping
# less: less
# net-tools: netstat
# iproute2: ss
RUN apt-get install -y --no-install-recommends vim procps iputils-ping less net-tools iproute2

# 安装mysqli、pdo等PHP扩展
# 如果需要安装特定版本的扩展,可以在扩展名后加版本号,例如:redis-5.1.1
RUN chmod +x /usr/local/bin/install-php-extensions \
    && install-php-extensions redis mysqli pdo_mysql pcntl gd mcrypt bcmath sockets zip

# 使用线上环境的php.ini配置文件
RUN cp "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

上面Dockerfile里有一个步骤是修改Debian系统的软件源,目的是为了加快apt-get命令在国内下载软件的速度。修改的时候要注意源地址要跟基础镜像的系统版本相匹配,例如php:7.4-fpm-buster这个镜像是基于Debian 10(代号buster)系统构建的,那么源地址里的系统代号也要保持一致,否则使用apt-get命令的时候会报错:
在这里插入图片描述

如何查询镜像的系统版本、代号等信息?
执行命令sudo docker run {镜像ID或名字} cat /etc/os-release,例如sudo docker run php:7.4-fpm-buster cat /etc/os-release

开始构建

执行docker build命令构建FPM镜像,镜像名字设置为img-php-fpm,标签(TAG)设置为7.4

cd /home/rockyliang/mydocker/php-fpm
sudo docker build -t img-php-fpm:7.4 .

因为国内访问github不太稳定,构建过程可能会在“安装install-php-extensions”这一步骤发生错误,一般重试构建多几次就可以解决。

构建完成后,执行docker images命令,已经能看到新的镜像:

sudo docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
img-php-fpm         7.4                 d511ba9f4c3d        2 minutes ago       456MB
php                 7.4-fpm-buster      c1bb99843706        3 days ago          389MB

执行docker run命令运行新镜像,容器名字设置为DOCKER_FPM,为了让容器能访问到宿主机的html目录,还需要把宿主机的html目录挂载到容器里的/var/www/html目录:

sudo docker run --name DOCKER_FPM \
-p 9000:9000 \
--network mynet \
-v /home/rockyliang/mydocker/html:/var/www/html:ro \
-d img-php-fpm:7.4

构建nginx镜像

Dockerfile文件

# 从官方基础版本构建
FROM nginx:1.19

# 镜像信息
LABEL maintainer="ljfrocky" \
    version="2020.03.30" \
    description="Nginx 1.19"

# 设置系统时区
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 修改debian软件源为国内源
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster main non-free contrib' > /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian-security buster/updates main' >> /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib' >> /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib' >> /etc/apt/sources.list \
    && apt-get update

# 安装常用命令工具包,根据自己的实际需要情况进行安装
# vim: vi、vim
# procps: ps
# iputils-ping: ping
# less: less
# net-tools: netstat
# iproute2: ss
RUN apt-get install -y --no-install-recommends vim procps iputils-ping less net-tools iproute2

开始构建

执行docker build命令构建nginx镜像,镜像名字设置为img-nginx,标签(TAG)设置为1.19

cd /home/rockyliang/mydocker/nginx
sudo docker build -t img-nginx:1.19 .

构建完成后,执行docker run命令运行新镜像,容器名字设置为DOCKER_NGINX,为了让容器能访问到宿主机的html目录,还需要把宿主机的html目录挂载到容器里的/usr/share/nginx/html目录:

sudo docker run --name DOCKER_NGINX \
-p 80:80 \
--network mynet \
-v /home/rockyliang/mydocker/html:/usr/share/nginx/html:ro \
-d img-nginx:1.19

容器运行起来后,进入容器修改nginx的配置文件,让nginx可以转发PHP请求:

sudo docker exec -it DOCKER_NGINX bash
vim /etc/nginx/conf.d/default.conf

将配置文件里的这一段
在这里插入图片描述
去除前面的注释,内容替换成:
在这里插入图片描述

在容器里重启nginx:nginx -s reload

测试

至此,nginx和PHP容器都搭建好了,测试一下看nginx能不能处理PHP请求,在宿主机的html目录里新建一个phpinfo.php文件:

<?php
phpinfo();

在浏览器访问一下http://localhost/phpinfo.php,内容显示正常:
在这里插入图片描述

构建MySQL镜像

Dockerfile文件

# 从官方基础版本构建
FROM mysql:5.7

# 镜像信息
LABEL maintainer="ljfrocky" \
    version="2020.03.31" \
    description="MySQL 5.7"

# 设置系统时区
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 修改debian软件源为国内源
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster main non-free contrib' > /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian-security buster/updates main' >> /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib' >> /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib' >> /etc/apt/sources.list \
    && apt-get update

# 安装常用命令工具包,根据自己的实际需要情况进行安装
# vim: vi、vim
# procps: ps
# iputils-ping: ping
# less: less
# net-tools: netstat
# iproute2: ss
RUN apt-get install -y --no-install-recommends vim procps iputils-ping less net-tools iproute2

开始构建

执行docker build命令构建MySQL镜像,镜像名字设置为img-mysql,标签(TAG)设置为5.7

cd /home/rockyliang/mydocker/mysql
sudo docker build -t img-mysql:5.7 .

构建完成后,执行docker run命令运行新镜像,容器名字设置为DOCKER_MYSQL,root账号密码设置为123456

sudo docker run --name DOCKER_MYSQL \
-p 3306:3306 \
--network mynet \
-e MYSQL_ROOT_PASSWORD=123456 \
-d img-mysql:5.7

构建Redis镜像

Dockerfile文件

# 从官方基础版本构建
FROM redis:6.2-buster

# 镜像信息
LABEL maintainer="ljfrocky" \
    version="2020.03.31" \
    description="Redis 6.2"

# 官方镜像默认是没有redis.conf配置文件的,如果需要配置文件,需要自己编写或者到网络上下载
# 6.2版本配置文件下载地址:https://raw.githubusercontent.com/antirez/redis/6.2/redis.conf
# 把宿主机上已下载好的配置文件复制到容器里去
COPY ./etc/redis.conf /usr/local/etc/redis/redis.conf

# 设置系统时区
RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

# 修改debian软件源为国内源
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster main non-free contrib' > /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian-security buster/updates main' >> /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster-updates main non-free contrib' >> /etc/apt/sources.list \
    && echo 'deb http://mirrors.aliyun.com/debian/ buster-backports main non-free contrib' >> /etc/apt/sources.list \
    && apt-get update

# 安装常用命令工具包,根据自己的实际需要情况进行安装
# vim: vi、vim
# procps: ps
# iputils-ping: ping
# less: less
# net-tools: netstat
# iproute2: ss
RUN apt-get install -y --no-install-recommends vim procps iputils-ping less net-tools iproute2

# 以指定配置文件的方式启动redis
CMD [ "redis-server", "/usr/local/etc/redis/redis.conf" ]

开始构建

执行docker build命令构建Redis镜像,镜像名字设置为img-redis,标签(TAG)设置为6.2

cd /home/rockyliang/mydocker/redis
sudo docker build -t img-redis:6.2 .

构建完成后,执行docker run命令运行新镜像,容器名字设置为DOCKER_REDIS

sudo docker run --name DOCKER_REDIS \
-p 6379:6379 \
--network mynet \
-d img-redis:6.2

容器运行起来后,进入容器修改redis配置文件:

sudo docker exec -it DOCKER_REDIS bash
vim /usr/local/etc/redis/redis.conf

bind 127.0.0.1 -::1这一行改为bind *,保存,退出容器,然后重启容器:

sudo docker restart DOCKER_REDIS

测试

在宿主机的html目录里新建一个test.php文件,用于测试PHP是否能查询MySQL和redis:

<?php

function display($msg) {
    echo "{$msg}<br>";
}

/*
 * 测试连接MySQL
 */
$mysqlConn = new mysqli();
$ok = $mysqlConn->real_connect('DOCKER_MYSQL', 'root', '123456');
if (!$ok) {
    exit("MySQL connect failed:" . $mysqlConn->connect_error);
}
$mysqlConn->close();
display("测试MySQL连接:OK");

/*
 * 测试连接redis
 */
$redis = new Redis();
try {
    $redis->connect('DOCKER_REDIS', 6379, 2);
} catch (Throwable $e) {
    exit("Redis connect failed:" . $e->getMessage());
}
$redis->close();
display("测试Redis连接:OK");

在浏览器访问一下http://localhost/test.php,连接数据库正常:
在这里插入图片描述

日志/数据/配置文件路径

在部署服务时,我们一般都会关注日志路径、数据存储路径、配置文件路径,下面列一下上面几个镜像的一些默认路径:

镜像日志配置文件数据
php:7.4-fpm-buster默认无日志文件,access log和error log都是输出到标准输出,需要使用docker logs命令查看,如果需要将日志记录到文件里,请参阅后面章节内容/usr/local/etc
(php.ini和php-fpm.conf等配置文件都在这个路径里)
nginx:1.19/var/log/nginx/access.log
/var/log/nginx/error.log
这两个文件都是软链接到标准输出的,无法查看里面的内容,只能通过docker logs命令查看。解决方法见后面章节内容
/etc/nginx/usr/share/nginx/html
mysql:5.7/var/log/mysql/etc/mysql/var/lib/mysql
redis:6.2-buster默认无日志文件,日志都是输出到标准输出,需要使用docker logs命令查看,如果需要将日志记录到文件里,请参阅后面章节内容默认无配置文件,可以自己指定/data
(rdb文件存放路径)

记录日志到文件

通过上一章节,我们知道PHP-FPM、nginx、redis的日志是不记录到实体文件里的,只能通过docker logs {容器名称或ID}命令来查看,那么,如果我们想把日志记录到实体文件里,可以怎么做呢?

PHP-FPM

进入PHP-FPM容器,修改/usr/local/etc/php-fpm.d/zz-docker.conf文件:
在这里插入图片描述
新增图中两行内容,保存并重启容器,这样PHP-FPM的 access log 和 error log 就会记录到我们指定的文件里了。

nginx

nginx容器里的日志文件是个软链接:

root@adb13aee521c:/var/log/nginx# ls -l
total 0
lrwxrwxrwx 1 root root 11 May 12  2021 access.log -> /dev/stdout
lrwxrwxrwx 1 root root 11 May 12  2021 error.log -> /dev/stderr

所以如果想把日志记录到文件里去,把软链接删除即可:

cd /var/log/nginx
unlink access.log
unlink error.log
nginx -s reload

redis

因为上面我们在构建redis镜像时,有通过COPY指令复制了一个redis.conf配置文件进去,我们通过修改配置文件来配置日志文件路径即可。

假设我们希望把日志文件保存在/var/log/redis目录里,首先我们要创建好这个目录,并确保redis用户对这个目录有写入的权限

mkdir /var/log/redis
chown redis:redis /var/log/redis/

修改/usr/local/etc/redis/redis.conf文件:
在这里插入图片描述
修改logfile参数,指定日志文件路径,保存退出,重启redis容器。

docker-compose

如果你觉得像上面那样一个一个的构建镜像和运行太麻烦,可以试下用docker-compose来减轻工作量,在项目根目录里编写一个docker-compose.yml,内容如下:

version: "3"
services:

  nginx:
    image: img-nginx:1.19
    build:
      context: ./nginx
      dockerfile: Dockerfile
    container_name: DOCKER_NGINX
    ports:
      - "80:80"
      - "443:443"
    networks:
      - lnmp-network
    volumes:
      - ./html:/usr/share/nginx/html:ro
    restart: always
    depends_on:
      - php-fpm

  php-fpm:
    image: img-php-fpm:7.4
    build:
      context: ./php-fpm
      dockerfile: Dockerfile
    container_name: DOCKER_FPM
    volumes:
      - ./html:/var/www/html:ro
    networks:
      - lnmp-network
    restart: always
    depends_on:
      - mysql
      - redis

  mysql:
    image: img-mysql:5.7
    build:
      context: ./mysql
      dockerfile: Dockerfile
    container_name: DOCKER_MYSQL
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: '123456'
    command: mysqld  --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
    networks:
      - lnmp-network
    restart: always

  redis:
    image: img-redis:6.2
    build:
      context: ./redis
      dockerfile: Dockerfile
    container_name: DOCKER_REDIS
    ports:
      - "6379:6379"
    networks:
      - lnmp-network
    restart: always

networks:
  lnmp-network:
    driver: bridge
    ipam:
      config:
        - subnet: '172.31.0.0/16'

然后执行sudo docker-compose up -d命令,docker-compose就会一次性把所有镜像构建好,并且运行。

在搭建环境时遇到的一些坑

1.配置文件修改错了,导致容器启动不起来了

一般修改完配置文件,都需要重启容器来让新配置生效的,但如果不小心配置错了,导致容器起不来了就麻烦了,容器起不来,就无法进去重新修正配置文件。这时候可以通过docker cp命令,把有问题容器里的配置文件复制到宿主机上来,然后在宿主机上修改,修改完后,再docker cp回去容器里,这样就可以解决这个问题了。

  PHP知识库 最新文章
Laravel 下实现 Google 2fa 验证
UUCTF WP
DASCTF10月 web
XAMPP任意命令执行提升权限漏洞(CVE-2020-
[GYCTF2020]Easyphp
iwebsec靶场 代码执行关卡通关笔记
多个线程同步执行,多个线程依次执行,多个
php 没事记录下常用方法 (TP5.1)
php之jwt
2021-09-18
上一篇文章      下一篇文章      查看所有文章
加:2022-04-04 11:48:41  更:2022-04-04 11:48:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 17:57:44-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码