[3/4] Dockerify:迁移 Nodejs 和 PHP 站点

文章已合并进 e1200

迁移 Nodejs 站点(Express)

接下来我们实战迁移一个由 Nodejs 写的 Express SSR 站点

我打算怎么做

网站使用 Ejs 模板渲染页面。在没迁移 Docker 之前,若我想更新线上网站中内容时,需要:

  1. 本地修改好 Ejs 或者其他文件
  2. 手动通过 FTP 上传到服务器
  3. 在服务器端重启 Nodejs 进程。若有 npm 包依赖改动,需要在VPS服务器上手动执行npm install
  4. git push更新 Github 源码

稍微有点麻烦,因此我打算这样改:

  1. 执行git push
  2. 自动检测到 github 有代码更新,自动打包出一个 Docker 镜像
  3. CI 编译完成后,SSH 登录 VPS,删掉现有容器,用新镜像创建一个新容器

而这样做的好处是:

  1. 不必再手动 FTP 上传文件
  2. 不必手动维护服务器的 Nodejs 运行环境

实施

具体的过程和处理静态站点没有什么特别的区别,无非是:

  1. 编写 Dockerfile 文件
  2. 在 CI 时自动打包镜像
  3. 在VPS增加一个 Nginx 反向代理

这次就不重复讲了,具体的配置可以参考项目中的相关文件

Tips: 你可能发现了 Dockerfile 中的ENTRYPOINT命令必须指定一个前台进程。若你的 Nodejs 应用是使用 PM2 进行保活的,你需要替换pm2 start app.jspm2-docker app.js

docker-compose

当将 Nodejs 站点迁移完成,我们的 VPS 服务器上已经运行了2个容器。每次镜像更新都要手动的docker container create带一堆参数是比较麻烦的,尤其是当日后容器日益增多的时候。而这时,就轮到docker-compose登场了~

docker-compose 是 Docker 官方提供的一个 Docker 管理工具。若你是通过桌面端的 Docker 安装包安装的 Docker,它是会默认为你安装 docker-compose 的。可以试试如下命令:

docker-compose --help

如果是在 Linux,可以通过如下命令安装 docker-compose:

curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
chmode +x /usr/local/bin/docker-compose

docker-compose 和 Docker 差不多,也是只要一份文件就能跑起来。docker-compose 主要的作用就是能够让你不必手敲那么多 Docker 命令

建立一个目录,然后在目录中建立docker-compose.yml,内容如下:

version: "3.7" # 这个是配置文件的版本,不同的版本号声明方式会有细微的不同
services:
    info:
        container_name: pea3nut-info
        image: pea3nut/pea3nut-info:latest
        ports:
            - "8082:80"
        restart: on-failure

然后在目录中键入如下命令就能将服务跑起来:

docker-compose up info

docker-compose 会帮我们自动去拉镜像,创建容器,将容器中的80端口映射为宿主机的8082端口。restart字段还要求 docker-compose 当发现容器意外挂掉时重新启动容器,类似于 pm2,所以你不必再在容器内使用 pm2

如果想要更新一个镜像创建新容器,只需要:

docker-compose pull info
docker-compose stop info
docker-compose rm info
docker-compose up -d info # -d 代表后台运行

笔者已将自己网站部署方式开源,可参考github/pea3nut-hub

迁移 WordPress 站点(Apache + PHP + MySQL)

接下来我们实战迁移一个 WordPress 站点

可能你也发现了这个站点和其他站点的一个非常大的不同——他的源码和数据是不能公开的

之前我们打包镜像时,都是直接将代码打进镜像内的。这条方案用在这里显然是不行的,有两个问题:

  1. 我不想公开 MySQL 数据文件和网站内容(如图片)。若将这些打包进镜像,任何人都能docker image pull下载到镜像,然后取得镜像内的文件
  2. 当容器被删掉,存储的 MySQL 数据都将丢失

Volume

Docker 提供了一个叫做 Volume 的东西,可以将容器内和宿主机的某个文件夹进行”绑定“,任何文件改动都会得到同步。所以,我可以将整个站点目录和 MySQL 目录都挂载为 Volume。这样,当容器删除时,所有数据文件和源码都会保留。

在本地建立./blog/mysql-data目录存储 MySQL 数据,建立./blog/wordpress目录存储 WordPress 源码。然后修改docker-compose.yml如下:

version: "3.7"
services:
    info:
        container_name: pea3nut-info
        image: pea3nut/pea3nut-info:latest
        ports:
            - "8082:80"
        restart: on-failure
+   blog:
+       container_name: pea3nut-blog
+       image: tutum/lamp:latest
+       ports:
+           - "8081:80"
+       volumes:
+           - ./blog/mysql-data:/var/lib/mysql
+           - ./blog/wordpress:/app
+       restart: on-failure

可以看到这次根本没有打包镜像,而是直接使用tutum/lamp镜像提供的 LAMP 环境(Linux + Apache + MySQL + PHP),然后将 MySQL 数据目录/var/lib/mysql和源码目录/app都挂载出来就可以了

Tips: 通过 Volume 我们只是解决了部署问题,而如何本地开发然后将源码同步到服务器呢?用 FTP 当然是可以的,但是稍微有点麻烦。其实你可以自建一个 Git 服务器!详见:pea3nut.blog/e127

  • 浏览:93
  • 评论:0

发表新的回复