基于Docker一键LNMP(Nginx+MySQL+PHP7/5+Redis)安装程序
xsobi 2024-12-12 15:44 1 浏览
一键部署LNMP环境的目的,该环境特点:
完全开源
支持多版本PHP切换(PHP5.4、PHP5.6、PHP7.2...)
支持绑定任意多个域名
支持HTTPS和HTTP/2
PHP源代码位于host中
MySQL data位于host中
所有配置文件可在host中直接修改
所有日志文件可在host中直接查看
内置完整PHP扩展安装命令
本站实际使用,确保100%可用
实现一次配置,Windows、Linux、MacOs皆可用
1 快速使用
1、安装git、docker和docker-compose。
2、使用git下载完整代码:
nbsp;git clone https://github.com/yeszao/dnmp.git
3、用docker-compose命令启动容器,首次使用需要下载镜像,会稍慢:
nbsp;docker-compose up
4、然后在浏览器中访问localhost,就可以看到如下页面:
5、源代码在:./www/site1/ 目录下。
2 安装docker和docker-compose
具体安装步骤:
docker:https://docs.docker.com/engine/installation/
docker-compose:https://docs.docker.com/compose/install/
注意:Docker安装要求Linux 3.10以上版本,用uname -a命令可查看到。
安装之后,可查看版本:
nbsp;docker -v nbsp;docker-compose -v
然后把当前用户加到docker用户组里面:
nbsp;sudo gpasswd -a ${USER} docker
就不用每次启动Docker都得加sudo了。
注意,执行gpasswd命令之后要重新登陆才有效。
3 使用国内镜像仓库
在没有梯子的情况下,Docker默认从Docker Hub仓库下载镜像,完整的LNMP镜像估计需要一两天时间。
所以只能换个途径,比如使用阿里云的加速仓库。
首先注册一个阿里云账号,然后访问阿里云的Docker镜像仓库,能找到加速器地址。
对于Docker 1.10+,打开配置文件 /etc/docker/daemon.json(没有时新建该文件):
{ "registry-mirrors": ["https://6evg8u3r.mirror.aliyuncs.com"] }
以上是我的加速地址。
然后重启Docker Daemon:
sudo systemctl daemon-reloadsudo systemctl restart docker
就可以了。
Docker 1.10以下请看:https://yq.aliyun.com/articles/29941。
4 目录说明
大致框架如下:
(图片使用UMLet绘制,下载原文件)
4.1 目录结构
目录结构如下:
. ├── docker-compose.yml 容器启动配置文件 ├── Dockerfile PHP-FPM构建配置文件 ├── conf 配置目录 │ ├── mysql MySQL配置文件目录 │ │ └── my.cnf MySQL配置文件 │ ├── nginx Nginx配置文件目录 │ │ ├── conf.d 站点配置文件目录 │ │ │ ├── certs SSL认证文件、密钥和加密文件目录 │ │ │ │ └── site2 站点2的认证文件目录 │ │ │ ├── site1.conf 站点1 Nginx配置文件 │ │ │ └── site2.conf 站点2 Nginx配置文件 │ │ └── nginx.conf Nginx通用配置文件 │ └── php PHP配置目录 │ ├── php-fpm.d PHP-FPM配置目录 │ │ └── www.conf PHP-FPM配置文件 │ └── php.ini PHP配置文件 ├── log 日志目录 │ ├── mysql MySQL日志目录 │ ├── nginx Nginx日志目录 │ └── php-fpm PHP-FPM日志目录 ├── mysql MySQL数据文件目录 └── www 站点根目录 ├── site1 站点1根目录 └── site2 站点2根目录
4.2 站点部署
本文有默认加了两个站点:www.site1.com(同localhost)和www.site2.com。
要在本地访问这两个域名,需要修改你的hosts文件,添加以下两行:
127.0.0.1 www.site1.com127.0.0.1 www.site2.com
其中,www.site2.com为支持SSL/https和HTTP/2的示例站点。
因为站点2的SSL采用自签名方式,所以浏览器有安全提示,继续访问就可以了,自己的站点用第三方SSL认证证书替换即可。
如果只用到站点1,把站点2相关的目录和配置文件删除:
./conf/nginx/conf.d/certs/site2/./conf/nginx/conf.d/site2.conf ./www/site2/
重启容器内的Nginx生效:
docker exec -it dlnmp_nginx_1 nginx -s reload
4.3 HTTPS使用
在容器中我们也是可以用HTTPS的,具体的配置请参考如下文件:
./conf/nginx/conf.d/site2.conf
如果是自签名,可以用廖雪峰提供的一个自动生成认证文件、私钥脚本:gencert.sh,
这个脚本已经放在项目中,在这个目录下:
./conf/nginx/conf.d/certs/site2/
在Bash中输入:
nbsp;./gencert.sh
输入一次域名,和几次密码(内容随意)后,就会生成几个认证文件。
其中自签名情况不需要.csr和.origin.key后缀的文件。
然后修改Nginx配置文件,配置SSL支持就可以了。
5 docker-compose.yml文件
如下是docker容器的运行配置docker-compose.yml的内容:
nginx: image: nginx:alpine ports: - "80:80" - "443:443" volumes: - ./www/:/var/www/html/:rw - ./conf/nginx/conf.d:/etc/nginx/conf.d/:ro - ./conf/nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./log/nginx/:/var/log/nginx/:rw links: - php-fpm:fpm php-fpm: build: . expose: - "9000" volumes: - ./www/:/var/www/html/:rw - ./conf/php/php.ini:/usr/local/etc/php/php.ini:ro - ./conf/php/php-fpm.d/www.conf:/usr/local/etc/php-fpm.d/www.conf:rw - ./log/php-fpm/:/var/log/php-fpm/:rw links: - mysql:mysql - redis:redismysql: image: mysql:latest ports: - "3306:3306" volumes: - ./conf/mysql/my.cnf:/etc/mysql/my.cnf:ro - ./mysql/:/var/lib/mysql/:rw - ./log/mysql/:/var/log/mysql/:rw environment: MYSQL_ROOT_PASSWORD: "123456"redis: image: redis:latest ports: - "6379:6379"
这里我们用了nginx的alpine镜像,以及php-fpm和MySQL的最新镜像。
这里默认加了redis容器,不需要的话可以把文件的最后4行以及php-fpm块下的- redis:redis删除。
5.1 为什么用nginx:alpine?
因为相比nginx:latest,nginx:alpine有几点优势:
用的是最新版nginx镜像,功能与nginx:latest一模一样
alpine镜像用的是Alpine Linux内核,比ubuntu内核要小很多。
nginx:alpine默认支持http2。
Alpine的更多请看《Alpine Linux,一个只有5M的Docker镜像》。
如要进入alpine容器,命令是(后面的路径不是/bin/bash):
nbsp;docker exec -it dnmp_nginx_1 /bin/sh
5.2 站点根目录挂载
为什么站点根目录在Nginx和PHP-FPM都这样挂载?
./www/:/var/www/html/
我们知道,Nginx配置都有这样一项:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
其中,$document_root就是server块下root所指的路径:
server { #... root /var/www/html; #...}
这里$document_root就是/var/www/html。
如果Nginx和PHP-FPM在同一主机,Nginx会通过9000端口把这个目录值和脚本URI传给PHP-FPM。
PHP-FPM再通过9000端口接收Nginx发过来的目录值和脚本URI,发给PHP解析。
PHP收到后,就到指定的目录下查找PHP文件并解析,完成后再通过9000端口返回给Nginx。
如果Nginx和PHP-FPM在同一个主机里面,PHP就总能找到Nginx指定的目录。
但是,如果他们在不同的容器呢?
未做任何处理的情况,Nginx容器中的站点根目录,PHP-FPM容器肯定不存在。
所以,这里需要保证Nginx和PHP-FPM都挂载了Host的./www/,并且都挂载在容器的:/var/www/html。
(当然,你也可以指定别的目录,确保统一即可)
5.3 修改docker-compose.yml文件之后?
如果容器已经生成,回头再编辑docker-compose.yml,用
docker-compose up
命令会直接启动原来的容器,修改的内容不会体现在启动的容器里。
所以,要使修改的docker-compose.yml生效,需要以下4步:
nbsp;docker stop dnmp_nginx_1 # 第一步:停止容器nbsp;docker rm dnmp_nginx_1 # 第二步:删除容器# !!第三步:重启Docker服务!!nbsp;docker-compose up -d --no-deps --build mysql # 第四步:重新启动容器
其中最后一条命令参数作用:
-d:后台执行
--no-deps:不启动link的容器
--build:启动容器前先构建镜像
6 Dockerfile文件
因为PHP-FPM构建稍微复杂,涉及到很多扩展。
所以单独用Dockerfile文件构建PHP-FPM:
FROM php:fpm## Copy sources.list to container.## Here we use 163.com sources list.## PHP 5.6.31+ should use jessie sources list## PHP 7.2.0+ should use stretch sources list## For more please check:## PHP official docker repository: https://hub.docker.com/r/library/php/#COPY ./files/sources.list.stretch /etc/apt/sources.list#COPY ./files/sources.list.jessie /etc/apt/sources.list## Update UbuntuRUN apt-get update## mcryptRUN apt-get install -y libmcrypt-dev RUN docker-php-ext-install mcrypt## GDRUN apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng12-dev RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/RUN docker-php-ext-install -j$(nproc) gd## IntlRUN apt-get install -y libicu-dev RUN docker-php-ext-install -j$(nproc) intl## GeneralRUN docker-php-ext-install zip RUN docker-php-ext-install pcntl RUN docker-php-ext-install opcache RUN docker-php-ext-install pdo_mysql RUN docker-php-ext-install mysqli RUN docker-php-ext-install mbstring## ...
完整Dockerfile请移步本项目GitHub仓库。
7 nginx配置文件
这里,我们还需要稍微修改nginx配置文件:
location ~ \.phpnbsp;{ fastcgi_pass fpm:9000; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; }
这里,我们仅需把fastcgi_pass改成:fpm:9000。
也就是,PHP-FPM的侦听主机改成:Nginx links PHP-FPM容器的别名,在docker-compose.yml文件里面我们设置为fpm。
这样Nginx容器启动的时候,就会自动修改自己的/etc/hosts,让fpm指向php-fpm容器的IP。
修改之后,重启容器中的nginx:
nbsp;docker exec dlnmp_nginx_1 nginx -s reload
其中,dlnmp_nginx_1是容器的名称,也可以指定容器的ID。
8 站点根目录写权限
有时候,我们的PHP代码需要某个目录的写权限。
比如,Wordpress的wp-content/uploads目录,只有写权限我们才能正常上传文件。
默认的,容器中的/var/www/html目录属于root,我们需要修改为www-data,PHP才能正常写目录。
先进入到容器中:
nbsp;docker exec -it dlnmp_php-fpm_1 /bin/bash
然后修改目录权限:
nbsp;chown -R www-data:www-data /var/www/html
这样PHP就能正常读写目录了。
9 数据库
9.1 使用MySQL
在docker-compose.yml文件中,我们指定了MySQL数据库root用户的密码为123456。
所以,我们就可以在主机中通过:
nbsp;mysql -h 127.0.0.1 -u root -p
输入密码,就可以进入MySQL命令行。
说明:这里MySQL的连接主机不能用localhost,因为MySQL客户端默认使用unix socket方式连接,应该直接用本地IP。
在PHP代码中的使用方式与在主机中使用稍有不同,如下:
$pdo = new PDO('mysql:host=mysql;dbname=site1', 'root', '123456');
其中,host的值就是在docker-compose.yml里面指定的MySQL容器的名称。
这是因为PHP代码是在FPM容器中,FPM容器启动时会自动在/etc/hosts中加上:
172.17.0.2 mysql 11e55f91c4c3 dlnmp_mysql_1
就是说,mysql自动指向了MySQL容器动态生成的IP。
9.2 使用Redis
Redis使用和MySQL类似。
在主机和容器内部都通过地址127.0.0.1,端口6379访问。
PHP则是跨容器访问,host参数用redis(links指定的名称),端口用6379。
10 让DNMP随系统启动
到这里我们用docker搭建的Docker (Linux) + Nginx + MySQL + PHP环境已经可以正常使用了。
但每次启动系统都得切换到项目目录,再执行compose up,就略显繁琐。
要是能在系统启动的时候自动启动容器,岂不是更好,下面是具体的方法。
10.1 Ubuntu系统Unity桌面
从Launcher中搜索Startup Applications(启动应用程序),
然后Add一项,名字:Dnmp,命令填:
docker-compose -f /home/gary/dnmp/docker-compose.yml up -d
其中,-f 指定docker-compose.yml文件的位置。
然后保存即可。
10.2 其他Linux系统
其他命令行下的Linux系统,可以直接编辑 /etc/rc.local 文件,加上上面的命令
相关推荐
- 好用的云函数!后端低代码接口开发,零基础编写API接口
-
前言在开发项目过程中,经常需要用到API接口,实现对数据库的CURD等操作。不管你是专业的PHP开发工程师,还是客户端开发工程师,或者是不懂编程但懂得数据库SQL查询,又或者是完全不太懂技术的人,通过...
- 快速上手:Windows 平台上 cURL 命令的使用方法
-
在工作流程中,为了快速验证API接口有效性,团队成员经常转向直接执行cURL命令的方法。这种做法不仅节省时间,而且促进了团队效率的提升。对于使用Windows系统的用户来说,这里有一套详细...
- 使用 Golang net/http 包:基础入门与实战
-
简介Go的net/http包是构建HTTP服务的核心库,功能强大且易于使用。它提供了基本的HTTP客户端和服务端支持,可以快速构建RESTAPI、Web应用等服务。本文将介绍ne...
- #小白接口# 使用云函数,人人都能编写和发布自己的API接口
-
你只需编写简单的云函数,就可以实现自己的业务逻辑,发布后就可以生成自己的接口给客户端调用。果创云支持对云函数进行在线接口编程,进入开放平台我的接口-在线接口编程,设计一个新接口,设计和配置好接口参...
- 极度精神分裂:我家没有墙面开关,但我虚拟出来了一系列开关
-
本内容来源于@什么值得买APP,观点仅代表作者本人|作者:iN在之前和大家说过,在iN的家里是没有墙面开关的。...
- window使用curl命令的注意事项 curl命令用法
-
cmd-使用curl命令的注意点前言最近在cmd中使用curl命令来测试restapi,发现有不少问题,这里记录一下。在cmd中使用curl命令的注意事项json不能由单引号包括起来json...
- Linux 系统curl命令使用详解 linuxctrl
-
curl是一个强大的命令行工具,用于在Linux系统中进行数据传输。它支持多种协议,包括HTTP、HTTPS、FTP等,用于下载或上传数据,执行Web请求等。curl命令的常见用法和解...
- Tornado 入门:初学者指南 tornados
-
Tornado是一个功能强大的PythonWeb框架和异步网络库。它最初是为了处理实时Web服务中的数千个同时连接而开发的。它独特的Web服务器和框架功能组合使其成为开发高性能Web...
- PHP Curl的简单使用 php curl formdata
-
本文写给刚入PHP坑不久的新手们,作为工具文档,方便用时查阅。CURL是一个非常强大的开源库,它支持很多种协议,例如,HTTP、HTTPS、FTP、TELENT等。日常开发中,我们经常会需要用到cur...
- Rust 服务器、服务和应用程序:7 Rust 中的服务器端 Web 应用简介
-
本章涵盖使用Actix提供静态网页...
- 我给 Apache 顶级项目提了个 Bug apache顶级项目有哪些
-
这篇文章记录了给Apache顶级项目-分库分表中间件ShardingSphere提交Bug的历程。说实话,这是一次比较曲折的Bug跟踪之旅。10月28日,我们在GitHub上提...
- linux文件下载、服务器交互(curl)
-
基础环境curl命令描述...
- curl简单使用 curl sh
-
1.curl--help#查看关键字2.curl-A“(添加user-agent<name>SendUser-Agent<name>toserver)”...
- 常用linux命令:curl 常用linux命令大全
-
//获取网页内容//不加任何选项使用curl时,默认会发送GET请求来获取内容到标准输出$curlhttp://www.baidu.com//输出<!DOCTYPEh...
- 三十七,Web渗透提高班之hack the box在线靶场注册及入门知识
-
一.注册hacktheboxHackTheBox是一个在线平台,允许测试您的渗透技能和代码,并与其他类似兴趣的成员交流想法和方法。它包含一些不断更新的挑战,并且模拟真实场景,其风格更倾向于CT...
- 一周热门
- 最近发表
-
- 好用的云函数!后端低代码接口开发,零基础编写API接口
- 快速上手:Windows 平台上 cURL 命令的使用方法
- 使用 Golang net/http 包:基础入门与实战
- #小白接口# 使用云函数,人人都能编写和发布自己的API接口
- 极度精神分裂:我家没有墙面开关,但我虚拟出来了一系列开关
- window使用curl命令的注意事项 curl命令用法
- Linux 系统curl命令使用详解 linuxctrl
- Tornado 入门:初学者指南 tornados
- PHP Curl的简单使用 php curl formdata
- Rust 服务器、服务和应用程序:7 Rust 中的服务器端 Web 应用简介
- 标签列表
-
- grid 设置 (58)
- 移位运算 (48)
- not specified (45)
- patch补丁 (31)
- strcat (25)
- 导航栏 (58)
- context xml (46)
- scroll (43)
- element style (30)
- dedecms模版 (53)
- vs打不开 (29)
- nmap (30)
- webgl开发 (24)
- parse (24)
- c 视频教程下载 (33)
- paddleocr (28)
- listview排序 (33)
- firebug 使用 (31)
- transactionmanager (30)
- characterencodingfilter (33)
- getmonth (34)
- commandtimeout (30)
- hibernate教程 (31)
- label换行 (33)
- curlpost (31)