当前位置: 首页 > 后端技术 > PHP

使用Docker一键部署LNMP+Redis环境

时间:2023-03-29 20:50:51 PHP

使用Docker部署LNMP+Redis环境Docker简介Docker是一个开源的应用容器引擎,允许开发者将自己的应用和依赖打包到一个可移植的容器中,然后发布到任何流行的Linux机器,虚拟化也是可能的。容器完全使用沙箱机制,它们之间不会有任何接口。推荐内核3.8及以上版本为什么使用Docker加快本地开发构建过程,可以在开发环境中构建容器,然后轻松提交到测试环境,最后进入生产环境启用独立的服务或应用在不同的环境中获得相同的运行结果创建隔离环境进行测试高性能、超规划的主机部署从头开始??编译或扩展现有的OpenShift或CloudFoundry平台来构建自己的PaaS环境PHP扩展安装Composer安装常见问题处理常用命令Dockerfile语法docker-compose语法说明项目源码地址:GitHub安装Dockerwindows安装参考macdocker工具箱参考linux#下载安装curl-sSLhttps://get.docker.com/|sh#settingsBootself-startsudosystemctlenabledocker.servicesudoservicedockerstart|restart|stop#安装docker-composecurl-Lhttps://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname-s`-`uname-m`>/usr/local/bin/docker-composechmod+x/usr/local/bin/docker-compose目录结构docker_lnmp├──v2├──mysql│└──Dockerfile│└──my.cnf├──nginx│├──Dockerfile│├──nginx.conf│├──log││└──error.log│└──www│├──index.html│├──index.php│├──db.php│└──redis.php├──php│├──Dockerfile│├──www.conf│├──php-fpm.conf│├──php.ini│└──日志│└──php-fpm.log└──redis└──Dockerfile└──redis.conf创建镜像并安装纯CentOS镜像,通过Dockerfile相关命令编译源码安装各种服务,所以这种方式自定义你需要的镜像非常方便,但是占用空间大,构建速度慢。gitclonehttps://github.com/voocel/docker-lnmp.gitcddocker-lnmpdocker-composeup-dversion2(推荐)gitclonehttps://github.com/voocel/docker-lnmp.gitcddocker-lnmp/v2chmod777./redis/redis.logchmod-R777./redis/datadocker-composeup-d这个版本拉取官方已经做好的各种服务的镜像,然后根据Dockerfile相关的命令做相应的到自己的需要Adjustment。因此,该方法构建速度快,使用方便,并且由于基于AlpineLinux,占用空间小。测试使用dockerps查看容器的启动状态。如果一切正常启动,访问127.0.0.1、127.0.0.1/index.php、127.0.0.1/db.php、127.0.0.1/redis.php即可完成测试(如果要使用https,请修改nginx下的dockerfile,根据提示去掉nginx.conf中的注释,ling需要在ssl文件夹下添加自己的证书文件,这个工程自带的是空的,需要自己替换。保留文件同名)进入容器使用dockerexecdockerexec-itngixn/bin/shusensentercommand#cd/tmp;卷曲https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz|焦油-zxf-;cdutil-linux-2.24;#./configure--without-ncurses#makensenter&&sudocpnsenter/usr/local/bin为了连接到容器,你还需要找到第一个进程的PID容器的名称,可以通过以下命令获取并执行。PID=$(dockerinspect--format"{{.State.Pid}}"container_id)#nsenter--target$PID--mount--uts--ipc--net--pidPHP扩展安装安装PHP官方源码包在扩展中(例如:同时安装pdo_mysqlmysqlipcntlgd四个扩展)添加如下命令RUNapkaddlibpng-dev\&&docker-php-ext-installpdo_mysqlmysqlipcntlgd\注意:因为imagelibpng-缺少gd库需要的dev包,所以需要先下载这个包PECL扩展安装#安装扩展RUNpeclinstallmemcached-2.2.0\#启用扩展&&docker-php-ext-enablememcached\通过下载扩展源码,编译安装安装#安装Redis和swoole扩展RUNcd~\&&wgethttps://github.com/phpredis/phpredis/archive/4.2.0.tar.gz\&&tar-zxvf4.2.0.tar.gz\&&mkdir-p/usr/src/php/ext\&&mvphpredis-4.2.0/usr/src/php/ext/redis\&&docker-php-ext-installredis\&&apk添加libstdc++\&&cd~\&&wgethttps://github.com/swoole/swoole-src/archive/v4.2.12.tar.gz\&&tar-zxvfv4.2.12.tar.gz\&&mkdir-p/usr/src/php/分机\&&mvswoole-src-4.2.12/usr/src/php/ext/swoole\&&docker-php-ext-installswoole\注意:因为这个镜像需要先安装swoole依赖的libstdc++,否则不能安装成功后正常加载swooleextensionComposerinstallationAddRUNcurl-sStoDockerfilehttps://getcomposer.org/installer|php----install-dir=/usr/bin/--filename=composer\Commonproblemhandlingredisstartupfailureprobleminv2版本,redis的启动用户是redis,不是root,所以./redis/宿主机挂载的redis.log和./redis/data需要有写权限chmod777./redis/redis.logchmod777./redis/dataMYSQLconnectionfailure问题v2版本是最新的MySQL8,这个版本的密码验证方式是Caching_sha2_password,低版本的php和可能不支持mysql可视化工具,可以通过phpinfo中mysqlnd的Loadedplugins查看认证方式是否支持,否则需要修改为原来的认证方式mysql_native_password:selectuser,host,plugin,authentication_stringfrommysql.user;更改用户'root'@'%'用mysql_native_passwordBY'123456'标识;冲洗特权;注意挂载目录的权限,否则启动成功后容器会在几秒后关闭,例如:下面的/data/run/mysql目录将没有权限,会出现刚才的情况dockerrun--namemysql57-d-p3306:3306-v/data/mysql:/var/lib/mysql-v/data/logs/mysql:/var/log/mysql-v/data/run/mysql:/var/run/mysqld-eMYSQL_ROOT_PASSWORD=123456-itcentos/mysql:v5.7注意php.ini中要挂载的mysql的配置目录对应的目录获取文件内容,否则php无法挂载连接到mysql#php。inimysql.default_socket=/data/run/mysql/mysqld.sockmysqli.default_socket=/data/run/mysql/mysqld.sockpdo_mysql.default_socket=/data/run/mysql/mysqld.sock#mysqld.cnfpid-file=/var/运行/mysqld/mysqld.pidsocket=/var/run/mysqld/mysqld.sock无法使用php连接redis#错误$redis=newRedis;$rs=$redis->connect('127.0.0.1',6379);php无法连接,查看错误日志PHPFatalerror:UncaughtRedisException:Redisserverwoneawayin/www/index.php:7考虑到docker之间的通信不应该使用127.0.0.1,应该使用容器内的ip,所以检查redis容器的ip[root@localhostdocker]#dockerpsCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESb5f7dcecff4cdocker_nginx"/usr/sbin/nginx-..."4secondsagoUp3seconds0.0.0.0:80->80/tcp,0.0.0.0:443->443/tcpnginx60fd2df36d0edocker"/usr/local/php/sb..."7秒前Up5秒9000/tcpphp7c7df6f8eb91hub.c.163.com/library/mysql:latest"docker-entrypoint..."12秒前向上11秒3306/tcpmysqla0ebd39f0f64docker_redis"usr/local/redis/s..."13秒前Up12秒6379/tcpredis注意,测试的时候,连接地址需要容器的ip或者容器名,比如redis,mysql。比如nginx配置php文件解析fastcgi_passphp:9000;比如php连接redis$redis=newRedis;$res=$redis->connect('redis',6379);因为容器ip是动态的,重启后会发生变化,所以可以创建静态ip第一步:创建自定义网络#备注:这里选择172.172.0.0网段,其他任意空闲网段也可以指定dockernetworkcreate--subnet=172.171.0.0/16docker-atdockerrun--nameredis326--netdocker-at--ip172.171.0.20-d-p6379:6379-v/data:/data-itcentos/redis:v3.2.6连接redis可以配置对应的ip地址,连接成功$redis=newRedis;$rs=$redis->connect('172.171.0.20',6379);另外还有一种可能是phpredis无法连接redis,需要稍微修改redis.conf配置bind127.0.0.1改为:bind0.0.0.0启动dockerweb服务时,虚拟机端口转发无法对外访问。一般发生在yumupdate(WARNING:IPv4forwardingisdisabled.Networkingwillnotwork.)或主机可以访问,但外部无法访问vi/etc/sysctl.conf或vi/usr/lib/sysctl.d/00-system.conf添加如下代码:net.ipv4.ip_forward=1重启网络服务systemctlrestartnetwork查看是否修改成功sysctlnet如果.ipv4.ip_forward返回“net.ipv4.ip_forward=1”,表示成功。如果使用最新的MySQL8不能正常连接,是因为最新版本的密码加密方式改变导致无法远程连接。#修改密码加密方式ALTERUSER'root'@'%'IDENTIFIEDWITHmysql_native_passwordBY'123456';常用命令dockerstart容器名(容器ID也可以)dockerstop容器名(容器ID也可以)dockerrun命令加上-d参数,docker会把容器放在后台运行dockerpsrunningcontainerdockerlogs--tail10-tf容器名查看容器的日志文件,加-t是加时间戳,f是跟踪一个容器的最新日志,而不用读取整个日志文件dockertop容器名来查看容器内运行的进程dockerexec-dcontainernametouch/etc/new_config_file通过后台命令创建一个空文件dockerrun--restart=always--namecontainername-dubuntu/bin/sh-c"whiletrue;doechohelloworld;sleep1;done"不管退出码是什么,docker都会自动重启容器,可以设置--restart=on-failure:5自动重启次数dockerinspectcontainer来详细查看容器,您可以添加--format='{(.State.Running)}'获取指定信息dockerrmcontainerID删除容器,注意,不能删除正在运行的容器dockerrm$(dockerps-aq)删除所有容器dockerrmi$(dockerimages-aq)删除所有镜像dockerimageslistimagesdockerpull镜像名称:labelpullimagedockersearch在dockerHub上查找公开可用的镜像dockerbuild-t='AT/web_server:v1'命令后直接添加Dockerfile即可github仓库主目录下的文件。这些命令在编写Dockerfile后使用。-t选项为新镜像设置仓库和名称:标签dockerlogin登录DockerHub,个人认证信息会保存到$HOME/.dockercfg,dockercommit-m="comment"--author="AT》容器ID镜像用户名/仓库名:label不推荐这种方式,推荐使用dockerfiledockerhistory镜像ID探究镜像是如何构建的dockerport镜像ID端口查看容器ID和容器端口号的映射状态,假设查询80端口对应的映射端口run运行一个容器,-p8080:80将容器中的80端口映射到docker宿主机的特定端口,将容器的80端口绑定到宿主机的8080端口,另外127.0.0.1:80:80是将容器的80端口绑定到宿主机IP的80端口,-P是将容器中的80端口暴露给本地宿主机http://docs.docker.com/refere...查看更多命令dockerpushimagename将镜像推送到DockerHubdockerrmiimagenamedeleteimagedockerattachcontainerIDentercontainerdockernetworkcreate--subnet=172.171.0.0/16docker-atselect172.172.0.0网段dockerbuild即可添加-ip指定容器ip172.171.0.10删除所有容器和镜像。dockerrm`dockerps-a|awk'{print$1}'|grep[0-9a-z]`deletestoppedcontainersdockerrmi$(dockerimages|awk'/^/{print$3}')Dockerfile语法MAINTAINER标识镜像的作者和联系方式EXPOSE可以指定多个EXPOSE对外暴露多个端口,可以帮助多个容器链接FROMcommandspecifiedAnexistingimage\#symbol代表注释RUN运行命令,将在shell中使用命令wrapper/bin/sh-c执行.如果运行在不支持shell或者不想在shell中运行的平台,也可以使用exec格式的RUN命令ENVREFRESHED_AT环境变量这个环境也是用来表示最后更新时间的图像模板VOLUME容器添加一个卷。卷是可以存在于一个或多个容器中的特定目录。对卷的修改立即生效。对卷的修改不会影响更新镜像产品,例如:VOLUME["/opt/project","/data"]ADD将构建环境中的文件和目录复制到镜像中。比如ADDnginx.conf/conf/nginx.conf也可以是url的地址文件。如果是压缩包,ADD命令会自动解压。USER指定使用哪个USER来运行图像。COPY是复制本地文件,不会做文件解压(解压包不会自动解压)例子:COPYconf.d//etc/apache2/将本地conf.d目录下的文件复制到/etc/apache2/目录docker-compose.yml语法描述image指定为Imagename或imageID。如果图像不存在,Compose将尝试从Internet中拉取该图像。build指定Dockerfile所在文件夹的路径。Compose会用它来自动构建这个镜像,然后用这个镜像命令覆盖容器启动后执行的默认命令。到docker-compose.yml之外的容器,甚至不是Compose管理的容器。参数格式类似于链接和端口公开端口信息。宿主机端口:容器端口(HOST:CONTAINER)格式或者直接指定容器的端口(宿主机会随机分配端口)(注意:使用HOST:CONTAINER格式映射端口时,如果你使用的容器端口小于60可能会得到错误的结果,因为YAML会将xx:yy的数字格式解析为60。所以建议使用字符串格式。)expose暴露端口,和posts的区别是expose只能暴露端口,不映射到主机,仅用于对外服务连接;只能指定内部端口来设置参数卷的卷安装路径。可以设置宿主机路径:容器路径(host:container)或者添加访问方式(host:container:ro)ro表示只读,只读模式volumes_from挂载其他服务或容器环境的所有数据卷设置环境变量。可以属于数组或者字典两种格式。如果只给出变量名,它在Compose主机上的值会被自动加载,可以用来防止不必要的数据泄露。env_file从文件中获取环境变量,可以是单个文件路径,也可以是列表。如果通过docker-compose-fFILE指定模板文件,env_file中的路径将以模板文件路径为准。如果变量名和环境命令有冲突,以后者为准(环境变量文件中每一行必须有注释,支持以#开头的注释行)在已有服务的基础上扩展服务。比如我们已经有一个webapp服务,模板文件是common.yml。编写一个新的development.yml文件,在common.yml中扩展webapp服务。后者会自动继承common.yml中的webapp服务和相关的环境变量net来设置网络模式。使用与docker客户端的--net参数相同的值来与主机系统共享进程命名空间。启用该选项的容器可以通过进程id访问和操作dns配置DNS服务器。可以是一个值或一个列表cap_add,cap_drop添加或删除容器的Linux能力(Capability)dns_search配置DNS搜索域。它可以是一个值或一个列表。注意:使用compose编排和管理Docker容器时,需要编写docker-compose.yml文件。第一次写的时候,很容易遇到一些比较底层的问题,导致docker-composeup的执行。先解析yml文件的错误。比较常见的是yml对缩进的严格要求。yml文件OK后的缩进不允许使用tab键字符,只能使用空格,而且空格个数也是有要求的,一般是两个空格。项目源码地址:GitHub