记录一次用Docker封装锦城数据实验室项目的完整经历。

随着时间的推移,我离学校的距离也越来越远。

之前我在大学的时候做的一些小项目,也会因为域名和服务器续费和其他原因导致暂时不可访问的情况。

学院有时候想用这些项目来演示时才临时联系,这一时半会还真让我手忙脚乱的。

这次想着也该做个“了断”了,我打算用Docker来封装一下这些项目,也算是我对Docker的一个深入学习。

整理项目

首先要为自己的项目整理一张清单,这样就像药师拿着医生给的用药单一样按需准确的抓药:

类别 描述
程序语言 PHP 7.x
语言框架 Laravel 5.6
语言依赖包工具 Composer
数据存储 Mysql
代理工具 Nginx 1.14.2
附带工具 Git(代码版本管理),NPM > Yarn(JS包管理)

环境安装和配置

以Centos发行版本的Linux系统为例,依次执行以下程序做好服务器上的准备工作。

这里我考虑用centos作为基础镜像,在centos的基础上来部署锦城数据实验室项目。

拉取镜像

  1. # 安装Docker
  2. yum install docker
  3. # 从Docker官方镜像中拉取centos基础镜像
  4. docker pull centos

创建容器

  1. # 创建一个别名为DataLabDokcer的以centos镜像为基础的容器,并将宿主机的8000端口到映射到容器内部的80端口
  2. docker run --privileged -ti -d -p 8000:80 -e "container=docker" --name DataLabDocker centos /usr/sbin/init
  3. 参数解读:
  4. -i: 以交互模式运行容器,通常与 -t 同时使用;
  5. -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
  6. -d: 在后台执行,不进入当前容器;
  7. -p: 端口映射,格式为:主机(宿主)端口:容器端口;
  8. --name: 为容器指定一个名称;
  9. -e: 设置环境变量 例如 username="ShareMan"
  10. -v:目录映射,将宿主机的某个目录映射到容器中某个目录; -v /sys/fs/cgroup:/sys/fs/cgroup
  11. user/sbin/init: 在容器创建后执行的命令,使用这个命令会进行系统初始化自动将dbus等服务启动起来;
  12. --privileged 有先权高权限参数.

注意:一定要添加 —privileged 参数,否则我们无法在容器中执行权限较高的操作(如下图),如systemctl。

用Docker封装DataLab项目(Laravel为主)过程实录 - 图1

创建完后会显示如下信息:

用Docker封装DataLab项目(Laravel为主)过程实录 - 图2

通过 docker ps 命令我们可以看到刚启动的容器的基础信息。

完成的上面的工作后,我们得到了一个全新且最新的以centos系统为基础的容器。

进入容器

接下来,我们使用 docker exec 命令进入到名为DataLabDocker的容器内部,开始进行我们的软件安装和配置步骤:

  1. docker exec -it DataLbaDocker /bin/bash

用Docker封装DataLab项目(Laravel为主)过程实录 - 图3

如图,我们的环境发生了变化带来了命令窗的变化,从宿主机进入到了容器。

进入容器以后如何想要回到宿主机,用快捷键ctrl+d。

安装 epel

EPEL的全称叫 Extra Packages for Enterprise Linux 。EPEL是由 Fedora 社区打造,为 RHEL 及衍生发行版如 CentOS、Scientific Linux 等提供高质量软件包的项目。装上了 EPEL之后,就相当于添加了一个第三方源。

这一步就相当于把我们的软件市场更新,使它更丰富更可靠。

装了epel之后会避免后续步骤出现没有匹配的package的情况发生。

  1. yum install epel-release -y
  2. -y: 该参数即yes,软件安装过程中会有问是否确定安装的步骤,这个参数表示自动默认无需人工确认。
  3. rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
  4. # 上面这条指令是一个附属镜像源,用于后面操作中安装高版本php

安装辅助工具

  1. yum install zip unzip openssl openssl-devel gcc vim git wget libxml2-devel net-tools tree autoconf make yum lrzsz -y
  2. # lrzsz是一款在linux里可代替ftp上传和下载的程序。用Xshell等SSH工具传输没有速度的时候可以用这个!

用Docker封装DataLab项目(Laravel为主)过程实录 - 图4

在这一波系统环境操作的辅助工具安装完成后,我们进入与项目相关的环境部署。

安装 nginx

  1. # 安装 nginx
  2. yum install nginx -y

Nignx的安装源就来自于我们刚才安装的epel,否则直接在centos系统默认的老旧市场中找不到该软件安装包。

最后启动我们的nginx,看服务是否生效:

  1. # 启动 nginx
  2. systemctl start nginx
  3. # 将 nginx 设置为开机启动
  4. systemctl enable nginx

安装 PHP

  1. yum install php72w php72w-fpm php72w-opcache php72w-cli php72w-gd php72w-imap php72w-mysqlnd php72w-mbstring php72w-mcrypt php72w-pdo php72w-pecl-apcu php72w-pgsql php72w-xml php72w-xmlrpc php72w-openssl php72w-tokenize -y --skip-broken

PHP安装完成后还要安装一个PHP的现代化包管理工具(本项目中用到),comoser:

  1. php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');"
  2. php composer-setup.php
  3. php -r "unlink('composer-setup.php');"
  4. mv composer.phar /usr/local/bin/composer
  5. composer self-update

composer是一个比较老实的软件,不允许在超级用户的状态下执行命令,我们还要添加一个普通用户组用来执行composer命令。

  1. adduser ShareMan # 添加用户 名为ShareMan本尊
  2. passwd ShareMan # 也可以不设置密码
  3. su ShareMan # 切换用户到ShareMan

添加了普通权限用户后我们用su命令切换用户身份,再执行如下命令进行源切换。

  1. composer config -g repo.packagist composer https://packagist.phpcomposer.com
  2. # 上面这条命令用于切换镜像源,走“中/国\社/会\主/义\特/色\加/速\路/线”

用Docker封装DataLab项目(Laravel为主)过程实录 - 图5

配置php服务器运行自启动

  1. # 启动PHP
  2. systemctl start php-fpm
  3. # 将它设置为开机启动
  4. systemctl enable php-fpm

安装 Mysql

这里我们选择安装Mysql的分支,原因如下:

MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可。开发这个分支的原因之一是:甲骨文公司收购了MySQL后,有将MySQL闭源的潜在风险,因此社区采用分支的方式来避开这个风险。MariaDB的目的是完全兼容MySQL,包括API和命令行,使之能轻松成为MySQL的代替品。

  1. # 安装mariadb,完全兼容mysql
  2. yum install mariadb-server mariadb -y

相关操作命令如下:

  1. #启动MariaDB
  2. systemctl start mariadb
  3. #停止MariaDB
  4. systemctl stop mariadb
  5. #重启MariaDB
  6. systemctl restart mariadb
  7. #设置开机启动
  8. systemctl enable mariadb

安装 Nodejs

nodejs主要我们后面用于项目的包管理工具npm,但我习惯使用yarn来替代nodejs中自带的npm,所以我们一并安装yarn。

  1. yum install nodejs -y
  2. npm config set registry https://registry.npm.taobao.org
  3. npm install -g yarn
  4. yarn config set registry https://registry.npm.taobao.org

配置 PHP

修改 /etc/php.ini 文件配置

  1. # 去掉cgi.fix_pathinfo的注释并把值设为0
  2. vim /etc/php.ini

用Docker封装DataLab项目(Laravel为主)过程实录 - 图6

可在命令行模式中键入 /cgi.fix_pathinfo 快速定位到fix_pathinfo的配置项。 将cgi.fix_pathinfo=1这一行去掉注释将1改为0的用意是防止用户直接通过地址访问到文件的二进制内容。

修改 /etc/php-fpm.d/www.conf 文件配置

  1. vim /etc/php-fpm.d/www.conf
  2. # 将 listen = 127.0.0.1:9000 修改为如下监听地址
  3. listen = /var/run/php-fpm/php-fpm.sock
  4. # 将 date.timezone 分号去掉设定为 Asia/Shanghai
  5. # 取消如下三行的注释,并把owner和group的值改为nginx
  6. # 保持nginx操作的用户与php的用户一致很重要,否则会遇到各种操作没有权限的问题
  7. listen.owner = nobody -> listen.owner = nginx
  8. listen.group = nobody -> listen.group = nginx
  9. listen.mode = 0660
  10. # 替换文件中用户和组设定的apache为nginx
  11. user = apache -> user = nginx
  12. group = apache -> group = nginx

配置 Nginx

  1. vim /etc/nginx/nginx.conf

修改该文件中 server 对象中的 root 和 loacation / 分别指定 项目目录 和 代理路径匹配规则。

  1. # 下面这一段是Larvel的路由转发处理规则,针对不同项目根据业务需要做不同的设定。
  2. location / {
  3. try_files $uri $uri/ /index.php?$query_string;
  4. }
  5. # php的处理支持
  6. location ~ \.php$ {
  7. try_files $uri /index.php =404;
  8. fastcgi_split_path_info ^(.+\.php)(/.+)$;
  9. fastcgi_pass unix:/var/run/php5-fpm.sock;
  10. fastcgi_index index.php;
  11. fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
  12. include fastcgi_params;
  13. }

用Docker封装DataLab项目(Laravel为主)过程实录 - 图7

接下来重启 Nginx 服务使配置生效。

  1. # 重启 nginx 服务
  2. systemctl restart nginx

检查步骤

至此,我们完成了我们的项目“三大件”的安装和基础配置。

我们可以使用top命令来查看相关服务是否已经正确启动并且在运行:

用Docker封装DataLab项目(Laravel为主)过程实录 - 图8

项目部署和配置

接下来进行项目的部署工作。

下面的内容是针对本项目所使用语言、技术栈来操作的。

下拉代码

首先,通过git或者目录映射以及其他各种方式把项目的源代码拉到我们的容器中。

我们这里使用git从github上把数据实验室的代码拉下来。

用Docker封装DataLab项目(Laravel为主)过程实录 - 图9

数据导出

数据导出方法就有很多了,这次我通过Navicat软件直接导出的SQL转储文件。

用Docker封装DataLab项目(Laravel为主)过程实录 - 图10

再将我们的SQL文件通过自己喜欢的方式传入docker容器内部。

我是通过XShell的ZMODE模式直接传入docker容器内:

用Docker封装DataLab项目(Laravel为主)过程实录 - 图11

文件传入后我们键入mysql命令进入mysql交互环境:

  1. # 新建空数据库
  2. mysql>create database ScujccDataLab;
  3. # 选择数据库
  4. mysql>use abc;
  5. # 设置数据库编码
  6. mysql>set names utf8;
  7. # 导入数据(注意sql文件的路径)
  8. mysql>source /www/data/ScujccDataLab.sql;

因为该项目本身是数据实验室相关的项目,数据库比较庞大,上传和导入了耗费很长时间。

一般情况下,还是因为改选 docker run 时将宿主的某个目录挂载的方式来上传,导入也应尝试更高效的方式。

数据库用户设置

  1. # 新建名为ScujccDataLab的用户并设定密码password
  2. CREATE USER 'ScujccDataLab'@'localhost' IDENTIFIED BY 'password';
  3. # 表示将数据库ScujccDataLab下所有表的权限授予用户 ScujccDataLab
  4. GRANT ALL PRIVILEGES ON ScujccDataLab.* TO 'ScujccDataLab'@'localhost';
  5. # 刷新权限使其生效
  6. FLUSH PRIVILEGES

程序配置

针对Laravel框架,要做如下程序配置。

项目环境配置

通过编辑.env文件来配置我们的Laravel项目:

  1. cp .env.example .env
  2. vim .env

PHP依赖安装

执行 composer install 命令安装项目的php依赖包:

0,如果composer执行过程中遇到了SSL相关报错的问题,需要为php配置SSL证书;

  1. wget http://curl.haxx.se/ca/cacert.pem
  2. vim /etc/php.ini
  3. 修改 openssl.cafile 的值为你存放cacert.pem文件的路径

1,修改项目项目文件夹的用户为ShareMan;

  1. chown -R ShareMan /www

2,切换到普通用户ShareMan进行composer命令的执行。

用Docker封装DataLab项目(Laravel为主)过程实录 - 图12

出现如上提示,说明composer install执行成功。

前端依赖安装

  1. # 这两句就不解释咯!
  2. yarn install
  3. yarn run production

目录权限

Laravel程序目录下的storage文件夹需要对文件进行日志和缓存写入等操作需要赋予高级别权限,否则会报500错误。

  1. chmod -R 777 /www/DataLab/storage

推送容器

此时,我们将锦城数据实验室已经部署到这个容器中,这个容器和刚开始的以centos为基础的容器区别在于我们的项目和项目所需的环境数据都放在了容器中。

下一步,我们要将这个阶段的容器推送到云端仓库中,这样以后我们想到其他的服务器上部署这个容器只需拉下来执行docker run的命令就可以了。

我们在 DockerHub.com 上注册一个账号,习惯用阿里云的朋友们还可以用阿里云的服务。

1,创建一个贮藏库(Repository):

用Docker封装DataLab项目(Laravel为主)过程实录 - 图13

2,本地提交容器的操作记录:

  1. docker commit -m "SCUJCC DataLab Project Docker" -a "ShareMan" b4a379d00f82 sharemant/datalab:v1

用Docker封装DataLab项目(Laravel为主)过程实录 - 图14

少顷,提交完成后会返回一个sha256的校验码。

3,commit后再进行push操作,如果未登陆过docker hub的信息需要先登陆:

  1. docker login
  2. docker push sharemant/datalab:v1

用Docker封装DataLab项目(Laravel为主)过程实录 - 图15

push成功后会返回如上信息,在docker hub里也能看到最近推送的docker images 的 tags。

用Docker封装DataLab项目(Laravel为主)过程实录 - 图16

检查步骤

键入网址和端口查看是否能够有效访问到:

用Docker封装DataLab项目(Laravel为主)过程实录 - 图17

Eureka!成功咯!

以后我想在其他的电脑上部署的时,只需要用如下两条小命令就可以让我们Docker小船扬帆远航。

  1. docker pull sharemant/datalab
  2. docker run --privileged -ti -d -p 8000:80 -e "container=docker" --name DataLabDocker sharemant/datalab /usr/sbin/init

访问地址 http://server2.share-man.com:8000/