宿主机环境

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

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

前言

这篇文章用于介绍如何使用docker在ubuntu系统上搭建一个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:

<?phpfunction 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.19build:context: ./nginxdockerfile: Dockerfilecontainer_name: DOCKER_NGINXports:- "80:80"- "443:443"networks:- lnmp-networkvolumes:- ./html:/usr/share/nginx/html:rorestart: alwaysdepends_on:- php-fpmphp-fpm:image: img-php-fpm:7.4build:context: ./php-fpmdockerfile: Dockerfilecontainer_name: DOCKER_FPMvolumes:- ./html:/var/www/htmlnetworks:- lnmp-networkrestart: alwaysdepends_on:- mysql- redismysql:image: img-mysql:5.7build:context: ./mysqldockerfile: Dockerfilecontainer_name: DOCKER_MYSQLports:- "3306:3306"environment:MYSQL_ROOT_PASSWORD: '123456'command: mysqld  --character-set-server=utf8mb4 --collation-server=utf8mb4_general_cinetworks:- lnmp-networkrestart: alwaysredis:image: img-redis:6.2build:context: ./redisdockerfile: Dockerfilecontainer_name: DOCKER_REDISports:- "6379:6379"networks:- lnmp-networkrestart: alwaysnetworks:lnmp-network:driver: bridgeipam:config:- subnet: '172.31.0.0/16'

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

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

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

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

使用docker搭建LNMP开发环境相关推荐

  1. Docker最全教程之使用Docker搭建Java开发环境(十八)

    前言 Java是一门面向对象的优秀编程语言,市场占有率极高,但是在容器化实践过程中,发现官方支持并不友好,同时与其他编程语言的基础镜像相比(具体见各语言镜像比较),确实是非常臃肿. 本篇仅作探索,希望 ...

  2. Docker最全教程之使用Docker搭建Java开发环境

    前言 Java是一门面向对象的优秀编程语言,市场占有率极高,但是在容器化实践过程中,发现官方支持并不友好,同时与其他编程语言的基础镜像相比(具体见各语言镜像比较),确实是非常臃肿. Java [Jav ...

  3. 使用 Docker 搭建本地开发环境!真心强啊

    关注公众号,回复"1024"获取2TB学习资源! 本地开发之痛苦 在开发之前,首先你需要安装各种开发工具和服务支持到你的开发环境当中,可能会出依赖问题,环境变量问题,端口冲突,经编 ...

  4. 怎么使用Docker搭建PHP开发环境呢?

    在Docker流行之前,要搭建开发环境通常有两种选择:一种是使用wamp.xampp.mamp等集成开发环境安装包,另外一种就是使用普通虚拟机来安装linux服务器,然后通过下载一键安装包(如:lnm ...

  5. 用Docker搭建Laravel开发环境

    在这篇文章中我们将通过Docker在个人本地电脑上构建一个快速.轻量级.不依赖本地电脑所安装的任何开发套件的可复制的Laravel和Vue项目的开发环境(开发环境的所有依赖都安装在Docker构建容器 ...

  6. 使用docker 搭建 ceph 开发环境,使用aws sdk 存储数据

    本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/79553386 1,关于ceph Ceph是加州大学Santa Cruz分校的Sa ...

  7. 用Docker搭建PHP开发环境

    2019独角兽企业重金招聘Python工程师标准>>> 安装Docker,下载地址:https://www.docker.com/ 打开Kitematic,搜索php镜像 选择一个镜 ...

  8. ubuntu18.04中基于Docker搭建tensorflow-gpu开发环境

    前提条件就不多提啦,首先得装好nvidia驱动和Docker19以上版本,网上有很多教程. 尝试1:拉取现有的deepo镜像制作 deepo是一个囊括几乎所有深度学习框架的开源镜像,这里我们选择拉取一 ...

  9. 通过VirtualBox与Vagrant在windows上搭建LNMP开发环境

    1. 安装 VirtualBox 虚拟机还是得依靠 VirtualBox 来搭建,免费小巧 下载地址:https://www.virtualbox.org/wiki/Downloads 2. 下载  ...

最新文章

  1. cytoscape---插件clueGO的使用
  2. Codeforces 617E XOR and Favorite Number
  3. 最具中产气质的“网易考拉”,离“中国版Costco”还有多远?
  4. 【高并发】面试官:性能优化有哪些衡量指标?需要注意什么?
  5. 10年老电脑如何提速_中国电信宣布将对宽带免费提速,最高500Mbps
  6. gispython定义查询_Python与开源GIS:SpatiaLite 中的基本SQL数据库查询用法
  7. “ this”关键字如何工作?
  8. QT生成在Windows下有图标的exe文件(IDE=QT Creator)
  9. 每日算法系列【LeetCode 328】奇偶链表
  10. 【翻译】InterlockedIncrement内部是如何实现的?
  11. 2019.04.07 电商12 登录界面的验证
  12. 爬虫百度图片进入百度验证怎么办?
  13. 软件设计文档国家标准—软件需求说明书(GB856T——88)
  14. 计算机视觉方向大创题目,关于开展2020年大创项目学生选题或自拟题目申报工作的通知...
  15. PX4代码学习系列博客(1)——开发环境配置
  16. 纯HTML+CSS+js实现大型企业站小米商城官网之注册页面
  17. 装系统时的UEFI模式
  18. 英语手记——持续更新
  19. 康佳在埃及成立合资公司发力非洲中东市场
  20. 【元宵快乐】猜灯谜吃元宵 元气满满闹元宵~(附猜灯谜小游戏)

热门文章

  1. Golang 代理https
  2. 扫地机器人杂牌的怎么样_国内扫地机器人哪个牌子好?
  3. 西普实验吧CTF-杯酒人生
  4. python制作一个接水果和金币的小游戏
  5. python爬虫携程机票
  6. Mustache教程
  7. dpdpdpdpdpdp
  8. 2.MySQL表操作
  9. js原生代码实现购物车
  10. SharePoint Server 2013 安装篇