用docker升级站点环境

该项目中有的插件需要PHP7的支持,而目前服务器的PHP版本是5.6,导致部分功能不能正常使用。服务器除了运行当前这个项目外,还运行有多个其它项目。如果直接升级服务器上的PHP版本,又担心升级后对其它运行的项目造成影响,而且升级PHP版本还会造成其它所有项目的访问受到影响。新购一台服务器,成本又太高。所以先尝试一下在服务器上搭建docker环境,在docker中运行PHP7然后将项目由docker中的PHP7运行。

目前服务器系统:CentOS 7

先安装docker

yum update
yum install -y docker
yum install -y docker-compose

查看安装结果

[root@iZwz9bb1rjtnkht5zwpln3Z ~]# docker-compose -v
docker-compose version 1.18.0, build 8dd22a9
[root@iZwz9bb1rjtnkht5zwpln3Z ~]# docker -v
Docker version 1.13.1, build b2f74b2/1.13.1

在服务器上配置之前,我先在本机做一下测试:

在项目中创建一个文件夹docker,并往dokcer里添加一个文件Dockerfile用于创建php7镜像

FROM php:7.1.27-fpm-alpine3.8
MAINTAINER seven <82294148@qq.com>

RUN apk add --no-cache freetype libpng libjpeg-turbo \
freetype-dev libpng-dev libjpeg-turbo-dev && \
  docker-php-ext-configure gd \
    --with-gd \
    --with-freetype-dir=/usr/include/ \
    --with-png-dir=/usr/include/ \
    --with-jpeg-dir=/usr/include/ && \
  NPROC=$(grep -c ^processor /proc/cpuinfo 2>/dev/null || 1) && \
  docker-php-ext-install -j${NPROC} gd && docker-php-ext-enable gd && apk del \
  freetype-dev libpng-dev libjpeg-turbo-dev && \
  apk add gettext-dev  \
&& /usr/local/bin/docker-php-ext-install gettext pdo pdo_mysql opcache mysqli dba\
&& apk add --no-cache\
            autoconf \
            file \
            g++ \
            gcc \
            libc-dev \
            make \
            pkgconf \
            re2c \
            zlib-dev \
            libmemcached-dev && \
        cd /tmp && \
        wget https://github.com/php-memcached-dev/php-memcached/archive/php7.zip && \
        unzip php7.zip && \
        cd php-memcached-php7 && \
        phpize || return 1 && \
        ./configure --prefix=/usr --disable-memcached-sasl --with-php-config=php-config || return 1 && \
        make || return 1 && \
        make INSTALL_ROOT="" install || return 1 && \
        install -d "/etc/php7/conf.d" || return 1 && \
        echo "extension=memcached.so" > /etc/php7/conf.d/20_memcached.ini && \
        cd /tmp && rm -rf php-memcached-php7 && rm php7.zip && \
        docker-php-ext-enable memcached &&\
cd /tmp \
        && wget https://github.com/igbinary/igbinary/archive/2.0.4.zip \
        && unzip 2.0.4.zip && cd igbinary-2.0.4 \
        && phpize && ./configure --with-php-config=php-config \
        && make && make install \
        && echo extension=igbinary.so >> /etc/php7/conf.d/01_igbinary.ini &&\
        wget https://github.com/phpredis/phpredis/archive/3.1.2.zip \
        && unzip 3.1.2.zip && cd phpredis-3.1.2 \
        && phpize && ./configure --enable-redis-igbinary --with-php-config=php-config \
        && make && make install \
        && echo extension=redis.so >> /etc/php7/conf.d/01_redis.ini && \
        docker-php-ext-enable igbinary redis && apk del autoconf \
                                                                    file \
                                                                    g++ \
                                                                    gcc \
                                                                    libc-dev \
                                                                    make \
                                                                    pkgconf \
                                                                    re2c \
                                                                    zlib-dev

再在项目目录下创建一个docker-compose.yml,写入启动配置参数

version: '3'

networks:
  host:

services:
  php7:
    build: docker
    networks:
      - host
    ports:
      - "9007:9000"
    container_name: php7
    volumes:
      - $PWD:/var/www

现在用bash进入项目目录,使用如下命令启动docker

docker-compose up

项目启动起来了

wenqidongdeMBP:blog wenqidong$ docker-compose up
Recreating php7 ... done
Attaching to php7
php7    | [18-Apr-2019 02:32:41] NOTICE: fpm is running, pid 1
php7    | [18-Apr-2019 02:32:41] NOTICE: ready to handle connections
php7    | 172.23.0.1 -  18/Apr/2019:02:32:48 +0000 "GET /index.php" 500

现在只是添加了一个PHP运行环境,接下来我把本机的nginx配置改一下。主要是配置一下root和fastcgi_pass的地址端口号

location ~ \.php {
        #root           /usr/share/nginx/present/public;
        root /var/www/web;
        fastcgi_pass   127.0.0.1:9007;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

        include        fastcgi_params;
        fastcgi_split_path_info ^(.+\.php)(.*)$;     #添加
        fastcgi_param PATH_INFO $fastcgi_path_info;    #添加
        fastcgi_param RUN_ENV 'dev';
        fastcgi_connect_timeout 180;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        client_max_body_size 100m;
        client_body_buffer_size 8m;
        #client_header_buffer_size 128k;
        #large_client_header_buffers 4 128k;
     }

改好之后,重启一下nginx

nginx -s reload

访问一下本地域名,可以看到页面response header中的PHP版本确实是docker中的php7.1.27。但是,好像连接不到数据库。。。

百度一阵猛搜没有找到实际解决方法,csdn记录的答案完全行不通,而且很多解决方式,一看就知道是错误的〜

虽然,知道使用docker时数据库也用docker比较好,但是docker连接宿主机上的数据库这种需求总还是会有,有这种需求,就应该有解决方式,于是上google找找答案..找到了如下回复:

Edit: If you are using Docker-for-mac or Docker-for-Windows 18.03+, just connect to your mysql service using the host host.docker.internal. Use --network="host" in your docker run command, then 127.0.0.1 in your docker container will point to your docker host.

Note: This mode only works on Docker for Linux, per the documentation. https://docs.docker.com/network/host/

  • 意思是说,如果在Mac或是Windows上要连接宿主机,如果把host.docker.internal作为数据库的host
  • 设置network="host"就可以使用127.0.0.1连接宿主机这种方式,只适用于linux系统。。。国内搜到的答案基本都是设置host,但我测试就是行不通,原来是系统问题.

修改代码中数据库host

'driver' => 'mysql',
    'host' => 'host.docker.internal',
    'database' => 'blog',
    'username' => 'dev',
    'password' => '',
    'charset' => 'utf8',
    'collation' => 'utf8_general_ci',
    'prefix' => 'w_',
    'port' => '3306'

保存,重新访问。欧啦:) !

本地测试好像是可以了,现在push到服务器上试一下

进入服务器项目文件夹, 执行docker-compose up -d,以后台方式启动试一下。

[root@iZwz9bb1rjtnkht5zwpln3Z blog]# docker-compose up -d
ERROR: Couldn't connect to Docker daemon at http+docker://localunixsocket - is it running?

If it's at a non-standard location, specify the URL with the DOCKER_HOST environment variable.

嗯,报错了,docker服务还没有行运起来,先启动一下docker服务,然后再执行上面的命令

[root@iZwz9bb1rjtnkht5zwpln3Z blog]# systemctl start docker
[root@iZwz9bb1rjtnkht5zwpln3Z blog]# docker-compose up -d
Creating network "blog_host" with the default driver
Building php7
Step 1/3 : FROM php:7.1.27-fpm-alpine3.8
Trying to pull repository docker.io/library/php ... 
7.1.27-fpm-alpine3.8: Pulling from docker.io/library/php
c87736221ed0: Pull complete
bcb58026c06e: Pull complete
6c24eee1bf47: Pull complete
864f09cef0fe: Pull complete
...
---> Running in 7d9a35e193a7

nsenter: could not ensure we are a cloned binary: Function not implemented
container_linux.go:247: starting container process caused "process_linux.go:245: running exec setns process for init caused \"exit status 17\""
ERROR: Service 'php7' failed to build: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:245: running exec setns process for init caused \"exit status 17\""

执行到一半又报错了 :(

先看一下已安装的情况

[root@iZwz9bb1rjtnkht5zwpln3Z blog]# docker images
REPOSITORY          TAG                    IMAGE ID            CREATED             SIZE
<none>              <none>                 35f3e56d236e        4 minutes ago       68.2 MB
docker.io/php       7.1.27-fpm-alpine3.8   45297c976686        5 weeks ago         68.2 MB
[root@iZwz9bb1rjtnkht5zwpln3Z blog]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
7d9a35e193a7        35f3e56d236e        "/bin/sh -c 'apk a..."   About a minute ago   Created                                 lucid_kare
d196c5f4f2e8        35f3e56d236e        "/bin/sh -c 'apk a..."   5 minutes ago        Created                                 epic_cray
[root@iZwz9bb1rjtnkht5zwpln3Z blog]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@iZwz9bb1rjtnkht5zwpln3Z blog]# 

PHP的基础镜像已经拉下来了,我的PHP镜像是在基础镜像的基础上,再安装一个我需要用的到PHP扩展。这里好像是构建我自定义扩展出错了。:(

据github问题返馈情况,这个似乎是一个跟系统相关的bug,我该如何是好:(

  • 想到一个方法,把Dockerfile提交到阿里云的容器服务中,先在阿里云中创建镜像,再到服务器上拉取镜像到服务器本地。启动docker的docker-compose.yml中设置使用本地镜像启动.

已在阿里云容器服务中创建好了镜像

现在来拉镜像到服务器本地

[root@iZwz9bb1rjtnkht5zwpln3Z ~]# sudo docker login --username=茵科美信 registry.cn-shenzhen.aliyuncs.com
Password: 
Login Succeeded
[root@iZwz9bb1rjtnkht5zwpln3Z ~]# sudo docker pull registry.cn-shenzhen.aliyuncs.com/swooledo/php7:1.0
Trying to pull repository registry.cn-shenzhen.aliyuncs.com/swooledo/php7 ... 
1.0: Pulling from registry.cn-shenzhen.aliyuncs.com/swooledo/php7
c87736221ed0: Already exists 
bcb58026c06e: Already exists 
6c24eee1bf47: Already exists 
864f09cef0fe: Already exists 
ba0720ee9bda: Already exists 
453e0280f68b: Already exists 
a34a71013a6a: Already exists 
5f68710aa59c: Already exists 
428d22454494: Already exists 
579646151b34: Pull complete 
Digest: sha256:c399744917c7d664d17825763bcc966eb6f4ddb547402202adfe4b861a91f5eb
Status: Downloaded newer image for registry.cn-shenzhen.aliyuncs.com/swooledo/php7:1.0
[root@iZwz9bb1rjtnkht5zwpln3Z ~]# 

查看一下

[root@iZwz9bb1rjtnkht5zwpln3Z ~]# docker images
REPOSITORY                                        TAG                    IMAGE ID            CREATED             SIZE
registry.cn-shenzhen.aliyuncs.com/swooledo/php7   1.0                    0e1e7058bf18        4 minutes ago       99.9 MB
<none>                                            <none>                 35f3e56d236e        43 minutes ago      68.2 MB
docker.io/php                                     7.1.27-fpm-alpine3.8   45297c976686        5 weeks ago         68.2 MB
[root@iZwz9bb1rjtnkht5zwpln3Z ~]# 

镜像已经拉取下来了,名字太长,对镜像做一下重命名

[root@iZwz9bb1rjtnkht5zwpln3Z ~]# docker tag 0e1e7058bf18 blog_php7:latest
[root@iZwz9bb1rjtnkht5zwpln3Z ~]# docker images
REPOSITORY                                        TAG                    IMAGE ID            CREATED             SIZE
blog_php7                                         latest                 0e1e7058bf18        7 minutes ago       99.9 MB
registry.cn-shenzhen.aliyuncs.com/swooledo/php7   1.0                    0e1e7058bf18        7 minutes ago       99.9 MB
<none>                                            <none>                 35f3e56d236e        46 minutes ago      68.2 MB
docker.io/php                                     7.1.27-fpm-alpine3.8   45297c976686        5 weeks ago         68.2 MB
[root@iZwz9bb1rjtnkht5zwpln3Z ~]# docker rmi 0e1e7058bf18
Error response from daemon: conflict: unable to delete 0e1e7058bf18 (must be forced) - image is referenced in multiple repositories
[root@iZwz9bb1rjtnkht5zwpln3Z ~]# 

这里,我把名称改为了 blog_php7 ,使用latest作为tag。 我偿试了一下删除名称比较长的那个镜像,这里显示是不是能删除。

先不管这个了,先改docker-compose.yml试一下能不能启动php7吧...

[root@iZwz9bb1rjtnkht5zwpln3Z blog]# docker-compose up -d
Creating php7 ... error

ERROR: for php7  Cannot start service php7: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:245: running exec setns process for init caused \"exit status 17\""

ERROR: for php7  Cannot start service php7: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:245: running exec setns process for init caused \"exit status 17\""

ERROR: Encountered errors while bringing up the project.

还是启动不起来 :(

网上还是说是由于linux内核与docker不匹配造成的, 在CentOS7.4上不能有这个问题。因为当前服务器的版本是Centos7.0。还有一台服务器的版本是CentOS7.4,于是在另外一台服务器上试了一下。竟然可以运行!!