利用Dockerfile构建lnmp运行环境

搭建之前,需要了解一下docker常用命令

目标

我们的目标是利用docker构建一个lnmp环境

目录结构

搭建一个lnmp环境,需要涉及到两个目录结构。一个是Dockerfile配置的目录结构,另一个是最终lnmp运行的目录结构。Dockerfile配置目录主要存放Dockerfile构建脚本和一些配置文件,lnmp运行目录主要存放程序运行产生的一些数据,比如mysql数据等。
以下是此次Dockerfile配置的目录结构,包括了nginx、php、mysql的配置文件。

lnmp
	- nginx
		- Dockerfile
		- nginx.conf
		- sites-enabled
			- default.conf
			...
	- php
		- Dockerfile
		- php.ini
		- php-fpm.conf
		- www.conf
	- mysql
		- Dockerfile
		- mysqld.cnf

以下是lnmp运行时的目录结构,主要是做容器内数据的持久化和共享。

/home/website
	- html
		- index.html
		- index.php
		...
	- mysql
		- data
			...
	- nginx
		- logs
			- access.log
			- error.log
	- php
		- logs
			- www.access.log

这里说明一下,html目录存放web网站内容,mysql目录存放的是数据库持久化的数据,nginx目录和php目录下主要存放相关运行日志。
在构建lnmp环境之前,需要先创建好这几个目录,并更改其拥有者为www-data。

另外,在部署配置lnmp之前,我们需要知道,容器内部的运行的服务,如nginx、mysql等,是会随着容器的销毁而消失的。所以

  1. 启动容器时,我们需要将相关的配置文件写入到容器应用程序中
  2. 容器运行时产生的数据,如数据库信息,我们要持久化到主机中

配置nginx

以下是nginx Dockerfile的配置

FROM nginx:1.14.2

ADD ./nginx.conf /etc/nginx/nginx.conf 
ADD ./sites-enabled /etc/nginx/conf.d/

RUN mkdir -p /home/website/nginx/logs && mkdir -p /home/website/html
RUN chown -R www-data:www-data /home/website/nginx && chown -R www-data:www-data /home/website/html

该脚本主要是拉取nginx1.14.2版本的包,然后将配置文件写入到容器内部,最后创建好容器内nginx的运行目录、添加相关权限。
这里共享一下我的nginx.conf配置

user www-data;

worker_processes  auto;

error_log /home/website/nginx/logs/error.log;

events {
    worker_connections  1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /home/website/nginx/logs/access.log  main;
    
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    client_max_body_size 20m;
    keepalive_timeout  65;
    include /etc/nginx/conf.d/*;
}

在nginx.conf中,我将nginx的日志写入到了/home/website/nginx/logs目录下,方便持久化时目录的映射。
以下是default.conf文件内容

server {
        listen          80;
        root            /home/website/html;
        index           index.php index.html index.htm;

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   /home/website/html;
        }

        location ~ \.php($|/) {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
            include        fastcgi_params;
        }

        location ~ .*\.(css|js|gif|jpg|jpeg|png|bmp|swf)$ {
            expires      30d;
        }
}

在default.conf中,我定义了一个简单的server,nginx的网站目录放在/home/website/html下
以上内容配置好了之后,就可以构建我们的镜像了。使用命令

docker build -t somehow/nginx ./nginx

创建好镜像somehow/nginx后,可以直接使用以下命令启动

docker run -itd -p 80:80 -v /home/website/html:/home/website/html -v /home/website/nginx/logs:/home/website/nginx/logs somehow/nginx 

在启动时,我指定了相关的端口映射、目录映射以及生成的镜像名称。
接下来就可以在浏览器中访问了。当然,请确保你的工作目录,也就是主机上的/home/website/html下有你要访问的文件

配置php

以下是php Dockerfile的配置

FROM php:7.2-fpm

ADD ./php.ini /usr/local/etc/php/php.ini
ADD ./php-fpm.conf /usr/local/etc/php-fpm.conf
ADD ./www.conf /usr/local/etc/php-fpm.d/www.conf

RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
    && docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
    && docker-php-ext-install -j$(nproc) gd \
    && docker-php-ext-install pdo_mysql \
    && docker-php-ext-install opcache \
    && apt-get install -y libxml2-dev \
    && docker-php-ext-install xml \
    && docker-php-ext-install bcmath \
    && docker-php-ext-install soap \
    && docker-php-ext-install zip


RUN pecl install redis-4.0.1 \
    && pecl install xdebug-2.6.0 \
    && docker-php-ext-enable redis xdebug

RUN mkdir -p /home/website/html && mkdir -p /home/website/php/logs
RUN chown -R www-data:www-data /home/website/html && chown -R www-data:www-data /home/website/php/logs

WORKDIR /home/website/html

php的构建文件内容比较多,但是基本都是Docker hub中说明过的一些操作,包括:

  1. 确定基础镜像为7.2版本的php-fpm
  2. 添加配置文件到容器中
  3. 安装容器扩展
  4. 创建工作目录,修改相应权限

关于其中的一些配置文件,其实可以从原始的php-fpm镜像中拷贝出来,然后再进行个性化的修改,添加进入容器中。我自己个人修改了www.conf这个文件,修改了其中两点:

  1. listen = 127.0.0.1:9000
  2. access.log = /home/website/php/logs/$pool.access.log

即设置了php-fpm的端口,并指定了访问日志文件的存放路径
接下来就可以创建镜像,使用命令

docker build -t somehow/php ./php

启动该镜像,使用命令

docker run -itd -p 9000:9000 -v /home/website/html:/home/website/html -v /home/website/php/logs:/home/website/php/logs somehow/php 

同样,这里进行了端口映射和目录映射。

部署好php还不够,我们还要将php和nginx连接起来,从而将php请求发送php-fpm进行处理。
将上述nginx配置文件中的default.conf中,php连接的地址改为主机的ip地址+端口号9000,修改部分如下

location ~ \.php($|/) {
	fastcgi_pass   **主机的ip**:9000;
	fastcgi_index  index.php;
	fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
	include        fastcgi_params;
}

这里注意要使用主机的ip而不是127.0.0.1。因为127.0.0.1配置的是容器内部的地址,放在外部是无法访问的,但是启动容器的时候进行了端口映射,所以可以通过主机端口来进行一次中转,从而将请求发送给正确的服务来处理。
配置好之后,重新build,run。nginx已经可以处理php请求了。

配置mysql

以下是mysql Dockerfile的配置

FROM mysql:5.7

Add ./mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf

MySQL的配置非常简单,直接拉取mysql5.7的官方镜像,然后添加配置文件到容器即可。
然后创建镜像,使用命令

docker build -t somehow/mysql ./mysql

启动该镜像,使用命令

docker run -itd -p 3306:3306 -v /home/website/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 somehow/mysql

mysql镜像的启动方式与上述两者略有不同,除了端口映射以及目录映射外,还新增了一个环境变量MYSQL_ROOT_PASSWORD,这个变量是官方景象中启动容器所必须指定的,代表着root用户的初始密码。

启动完成之后,现在使用数据库远程连接工具连接mysql,应当是可以连接成功的。

接下来是php与mysql的整合。
和nginx整合php的方式类似,php代码中若要调用mysql,需要在代码中指定主机的IP,而不能简单的使用127.0.0.1。
这里提供一个验证脚本,可以用来进行连接的验证

<?php
$dbms='mysql';     //数据库类型
$host=''; //数据库主机IP(使用真实主机IP)
$dbName='mysql';    //使用的数据库
$user='root';      //数据库连接用户名
$pass='123456';          //对应的密码
$dsn="$dbms:host=$host;dbname=$dbName";

try {
    $dbh = new PDO($dsn, $user, $pass); //初始化一个PDO对象
    echo "连接成功<br/>";
} catch (PDOException $e) {
    die ("Error!: " . $e->getMessage() . "<br/>");
}
//默认这个不是长连接,如果需要数据库长连接,需要最后加一个参数:array(PDO::ATTR_PERSISTENT => true) 变成这样:
$db = new PDO($dsn, $user, $pass, array(PDO::ATTR_PERSISTENT => true));

将该脚本部署到相应目录下,通过网页打开,会得到连接mysql成功的提示。你会注意到这里我们直接就能连接mysql,这是因为在php的构建过程中,我们已经在脚本中加入了pdo_mysql的扩展。

总结

以上就是使用docker构建lnmp运行环境的步骤。

以上的步骤看起来很复杂,但是当我们拿到一个新系统、需要搭建环境的时候,使用预先制作好的Dockerfile脚本无疑比手工重复快捷多了。
这其中当然有可以优化的部分,但是使用docker-compose无疑是更优的选择。关于docker-compose以及关于lnmp使用过程中的一些问题和坑,我会在接下来的几篇博文中记录下来,希望能对大家有所帮助。

另:构建lnmp环境的Dockerfile的配置文件已经上传,可以点击此处进行下载。

以上内容如有错误,或在使用过程中有问题,欢迎指正。

发布了136 篇原创文章 · 获赞 94 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/somehow1002/article/details/84963657