使用docker搭建LNMP开发环境
宿主机环境
系统: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开发环境相关推荐
- Docker最全教程之使用Docker搭建Java开发环境(十八)
前言 Java是一门面向对象的优秀编程语言,市场占有率极高,但是在容器化实践过程中,发现官方支持并不友好,同时与其他编程语言的基础镜像相比(具体见各语言镜像比较),确实是非常臃肿. 本篇仅作探索,希望 ...
- Docker最全教程之使用Docker搭建Java开发环境
前言 Java是一门面向对象的优秀编程语言,市场占有率极高,但是在容器化实践过程中,发现官方支持并不友好,同时与其他编程语言的基础镜像相比(具体见各语言镜像比较),确实是非常臃肿. Java [Jav ...
- 使用 Docker 搭建本地开发环境!真心强啊
关注公众号,回复"1024"获取2TB学习资源! 本地开发之痛苦 在开发之前,首先你需要安装各种开发工具和服务支持到你的开发环境当中,可能会出依赖问题,环境变量问题,端口冲突,经编 ...
- 怎么使用Docker搭建PHP开发环境呢?
在Docker流行之前,要搭建开发环境通常有两种选择:一种是使用wamp.xampp.mamp等集成开发环境安装包,另外一种就是使用普通虚拟机来安装linux服务器,然后通过下载一键安装包(如:lnm ...
- 用Docker搭建Laravel开发环境
在这篇文章中我们将通过Docker在个人本地电脑上构建一个快速.轻量级.不依赖本地电脑所安装的任何开发套件的可复制的Laravel和Vue项目的开发环境(开发环境的所有依赖都安装在Docker构建容器 ...
- 使用docker 搭建 ceph 开发环境,使用aws sdk 存储数据
本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/79553386 1,关于ceph Ceph是加州大学Santa Cruz分校的Sa ...
- 用Docker搭建PHP开发环境
2019独角兽企业重金招聘Python工程师标准>>> 安装Docker,下载地址:https://www.docker.com/ 打开Kitematic,搜索php镜像 选择一个镜 ...
- ubuntu18.04中基于Docker搭建tensorflow-gpu开发环境
前提条件就不多提啦,首先得装好nvidia驱动和Docker19以上版本,网上有很多教程. 尝试1:拉取现有的deepo镜像制作 deepo是一个囊括几乎所有深度学习框架的开源镜像,这里我们选择拉取一 ...
- 通过VirtualBox与Vagrant在windows上搭建LNMP开发环境
1. 安装 VirtualBox 虚拟机还是得依靠 VirtualBox 来搭建,免费小巧 下载地址:https://www.virtualbox.org/wiki/Downloads 2. 下载 ...
最新文章
- cytoscape---插件clueGO的使用
- Codeforces 617E XOR and Favorite Number
- 最具中产气质的“网易考拉”,离“中国版Costco”还有多远?
- 【高并发】面试官:性能优化有哪些衡量指标?需要注意什么?
- 10年老电脑如何提速_中国电信宣布将对宽带免费提速,最高500Mbps
- gispython定义查询_Python与开源GIS:SpatiaLite 中的基本SQL数据库查询用法
- “ this”关键字如何工作?
- QT生成在Windows下有图标的exe文件(IDE=QT Creator)
- 每日算法系列【LeetCode 328】奇偶链表
- 【翻译】InterlockedIncrement内部是如何实现的?
- 2019.04.07 电商12 登录界面的验证
- 爬虫百度图片进入百度验证怎么办?
- 软件设计文档国家标准—软件需求说明书(GB856T——88)
- 计算机视觉方向大创题目,关于开展2020年大创项目学生选题或自拟题目申报工作的通知...
- PX4代码学习系列博客(1)——开发环境配置
- 纯HTML+CSS+js实现大型企业站小米商城官网之注册页面
- 装系统时的UEFI模式
- 英语手记——持续更新
- 康佳在埃及成立合资公司发力非洲中东市场
- 【元宵快乐】猜灯谜吃元宵 元气满满闹元宵~(附猜灯谜小游戏)