前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用 Docker 和 Traefik 搭建 Flarum 轻论坛应用

使用 Docker 和 Traefik 搭建 Flarum 轻论坛应用

作者头像
soulteary
发布2019-09-27 19:22:24
1.3K0
发布2019-09-27 19:22:24
举报

本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 署名 4.0 国际 (CC BY 4.0)

本文作者: 苏洋

创建时间: 2019年07月16日 统计字数: 10682字 阅读时间: 22分钟阅读 本文链接: https://soulteary.com/2019/07/16/building-a-flarum-forum-app-with-docker-and-traefik.html


使用 Docker 和 Traefik 搭建 Flarum 轻论坛应用

最近在做社区类型的项目,出于后续从市场招人成本的考虑,不得不优选市场招聘培养难度较低的 PHP,再三挑选,选择了这款还在 beta 状态的软件。

这是一款 Beta 了差不多 5 年的软件,在 GitHub 上拥有接近一万 star 的耀眼成绩,第一条提交记录 是2014年末的 v0.1.0-beta 发布。

本文将介绍使用容器如何简单快速的搭建 Flarum ,如果你还不熟悉 Traefik,请翻阅之前的文章。

写在前面

关于选型的顾虑,我想此刻看到文章的你,也一定有所考虑。

前面提到这款软件还在 beta ,处于不是特别稳定的状况。而且前一阵主要的贡献者在论坛里发布了一条消息,宣布“farewell”,看起来是情况不是特别乐观,那么除了招聘维护成本的考虑之外,为什么还要选择它呢:

  • 交互体验和项目架子搭的还不错,基本面做的都还行。
  • 作为开源应用迭代了五年,有提交记录和开放的代码,程序不是特别复杂,相对好追溯和解决问题。
  • 项目文档虽然不全,但是基础的部分还差不多是有的。
  • 应用市场虽然东西不多,但是插件机制已经建设好了,功能扩展相对比较简单。
  • 同语言实现的、功能比较强大的某两款国产软件,一个论坛停止运营,一个计划重构(原因你懂的),显然当当下时间点都不值得托付。
  • WordPress 的 BuddyPress 生态可以考虑,但是做同样需求改动量会更大一些,因为冗余内容更多。

构建 PHP 容器

官方安装文档对于环境要求是这样的

  • 支持 URL Rewrite 的服务器软件:Apache、Nginx…
  • PHP 7.1+,以及 domgdjsonmbstringopenssl, 、 pdo_mysqltokenizer 组件。
  • MySQL5.6+MariaDB10.0.5+
  • Composer

所以,Docker Hub 默认的提供的 PHP 镜像是使用不了的,需要进行额外配置,安装以上需要的软件。我们默认不允许在已经运行起来的软件中执行插件卸载(删除程序部分文件),所以最后一点提到的 composer 可以在本地安装,或者干脆不进行安装。

这里以 PHP-FPM-ALPINE 7.3.2 为例:

代码语言:javascript
复制
FROM php:7.3.2-fpm-alpine
ENV LANG en_US.UTF-8ENV LANGUAGE en_US.UTF-8ENV LC_ALL=en_US.UTF-8
RUN echo '' > /etc/apk/repositories && \    echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.9/main"         >> /etc/apk/repositories && \    echo "https://mirror.tuna.tsinghua.edu.cn/alpine/v3.9/community"    >> /etc/apk/repositories && \    echo "Asia/Shanghai" > /etc/timezone
RUN apk --no-cache --no-progress update && \    apk --no-cache --no-progress upgrade
RUN apk add libpng libpng-dev libjpeg-turbo-dev libwebp-dev zlib-dev libxpm-dev
RUN docker-php-ext-install pdo pdo_mysql mbstring gd
ENTRYPOINT ["docker-php-entrypoint"]
STOPSIGNAL SIGQUIT
EXPOSE 9000CMD ["php-fpm"]

使用 build 命令将容器构建起来:

代码语言:javascript
复制
docker build -t php-fpm-flarum:7.3.2  -f Dockerfile .

使用 docker images 查看构建后的 PHP 镜像,一百兆出头。

代码语言:javascript
复制
REPOSITORY                               TAG                     IMAGE ID            CREATED             SIZEphp-fpm-flarum                           7.3.2                   ef5ad124a35d        3 minutes ago       105MB

搭建数据库

上一小节有提到过,官方对于数据库方面的要求是: MySQL5.6+MariaDB10.0.5+,所以你可以根据自己喜好来搞,如果有性能要求,建议使用云厂商的 RDS 产品。

下面给出一个数据库编排文件示例:

代码语言:javascript
复制
version: '3.6'
services:
  database:    image: ${DB_IMAGE}    restart: always    container_name: ${DB_HOST}    ports:      - 3306:3306    networks:      - traefik    environment:      MYSQL_DATABASE: ${DB_NAME}      MYSQL_USER: ${DB_USER}      MYSQL_PASSWORD: ${DB_PASS}      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASS}    volumes:      - ./data:/var/lib/mysql
networks:  traefik:    external: true

将上面的配置保存为 docker-compose.yml ,继续编写配置需要的 .env 文件。我这边为了测试方便,就都用弱密码了,实际使用应改成安全度较高的复杂密码。

代码语言:javascript
复制
DB_IMAGE=mysql:5.7.26DB_HOST=flarumDB_NAME=flarumDB_USER=flarumDB_PASS=flarumDB_ROOT_PASS=flarum

然后执行 docker-compose up-d 数据库就运行起来啦。

搭建应用运行框架

时至今日,官方提供的安装方案也从传统的软件压缩包变成了一条简约的命令:

代码语言:javascript
复制
composer create-project flarum/flarum . --stability=beta

但是这样做对于持续迭代的项目的开发部署体验是不友好的,即使使用版本锁定功能,项目构建还是时间会变长,把代码都打到容器里由显得笨重,并且造成了相同应用的代码割裂,维护成本颇高。

而且后续需要在程序框架上做一些改动,还要解决和未来的版本更新合并的问题,并不只是简单的安装使用就完事了,所以这里需要将应用代码储存下来。

安装 Composer PHP 包管理软件

因为软件发布模式变化,所以我们下载软件包需要使用 Composer (PHP 环境安装不赘述)。

代码语言:javascript
复制
wget -O composer-setup.php https://getcomposer.org/installer
php composer-setup.php --install-dir=bin --filename=composer

Composer 在国内下载比较慢,这里可以选择借助阿里云的加速镜像,使用方法很简单,就一条命令。

代码语言:javascript
复制
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/

下载 Flarum 程序代码

接着使用下面的命令将软件下载至 flarum 目录。

代码语言:javascript
复制
`composer create-project flarum/flarum ./flarum --stability=beta`

完成安装后的目录结构是下面的样子:

代码语言:javascript
复制
flarum├── CHANGELOG.md├── LICENSE├── README.md├── composer.json├── composer.lock├── extend.php├── flarum├── public│   ├── assets│   └── index.php├── storage│   ├── cache│   ├── formatter│   ├── less│   ├── locale│   ├── logs│   ├── sessions│   ├── tmp│   └── views└── vendor

现在软件还运行不起来,我们需要继续配置应用的运行环境。

配置软件运行环境

在上面的操作都就绪之后,我们就可以进行程序运行环境搭建了。这里使用 Nginx 作为 PHP 的前端,整个环境搭建非常简单。

代码语言:javascript
复制
version: "3.6"
services:
  nginx:    image: ${DOCKER_NGINX_IMAGE}    restart: always    expose:      - 80    volumes:      - ./logs:/var/log/nginx      - ./conf/docker-nginx.conf:/etc/nginx/nginx.conf      - ./wwwroot:/wwwroot    links:      - php:php    extra_hosts:      - "${DOCKER_DOMAIN_NAME}:127.0.0.1"    networks:      - traefik    labels:      - "traefik.enable=true"      - "traefik.port=80"      - "traefik.frontend.rule=Host:${DOCKER_DOMAIN_NAME}"      - "traefik.frontend.entryPoints=https,http"    healthcheck:      test: ["CMD-SHELL", "wget -q --spider --proxy off http://${DOCKER_DOMAIN_NAME}/get-health || exit 1"]      interval: 5s      retries: 12    logging:        driver: "json-file"        options:            max-size: "100m"
  php:    image: ${DOCKER_PHP_IMAGE}    restart: always    expose:      - 9000    volumes:      - ./logs:/var/log      - ./wwwroot:/wwwroot    extra_hosts:      - "${DOCKER_DOMAIN_NAME}:127.0.0.1"    networks:      - traefik    healthcheck:      test: ["CMD-SHELL", "pidof php-fpm"]      interval: 5s      retries: 12    logging:      driver: "json-file"      options:        max-size: "100m"
networks:  traefik:    external: true

搭配使用的 .env 可以这么写:

代码语言:javascript
复制
DOCKER_DOMAIN_NAME=flarum.lab.comDOCKER_PHP_IMAGE=php-fpm-flarum:7.3.2DOCKER_NGINX_IMAGE=nginx:1.17.1-alpine

Nginx 的配置则可以参考下面的文件:

代码语言:javascript
复制
user nginx;worker_processes 1;error_log /var/log/nginx/error.log warn;pid /var/run/nginx.pid;events { worker_connections 1024; }
http {    include /etc/nginx/mime.types;    default_type application/octet-stream;    log_format main '$http_x_forwarded_for - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"';    access_log off;    sendfile on;    keepalive_timeout 65;
    server {        listen 80;        server_name flarum.lab.com;        server_tokens off;        access_log /var/log/nginx/docker-access.log;        error_log /var/log/nginx/docker-error.log;        root /wwwroot/public;        index index.php index.html;
        location ~ \.php$ {            try_files $uri =404;            fastcgi_split_path_info ^(.+\.php)(/.+)$;            fastcgi_pass php:9000;            fastcgi_index index.php;            include fastcgi_params;            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;            fastcgi_param PATH_INFO $fastcgi_path_info;        }
        location / {            try_files $uri $uri/ /index.php?$query_string;        }        # The following directives are based on best practices from H5BP Nginx Server Configs        # https://github.com/h5bp/server-configs-nginx        # Expire rules for static content        location ~* \.(?:manifest|appcache|html?|xml|json)$ {            add_header Cache-Control "max-age=0";        }        location ~* \.(?:rss|atom)$ {            add_header Cache-Control "max-age=3600";        }        location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|mp4|ogg|ogv|webm|htc)$ {            add_header Cache-Control "max-age=2592000";            access_log off;        }        location ~* \.(?:css|js)$ {            add_header Cache-Control "max-age=31536000";            access_log off;        }        location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {            add_header Cache-Control "max-age=2592000";            access_log off;        }        location = /get-health {            access_log off;            default_type text/html;            return 200 'alive';        }        # 可以考虑交给后面的程序去处理,比如 traefik ...        # Gzip compression        gzip on;        gzip_comp_level 5;        gzip_min_length 256;        gzip_proxied any;        gzip_vary on;        gzip_types  application/atom+xml                    application/javascript                    application/json                    application/ld+json                    application/manifest+json                    application/rss+xml                    application/vnd.geo+json                    application/vnd.ms-fontobject                    application/x-font-ttf                    application/x-web-app-manifest+json                    application/xhtml+xml                    application/xml                    font/opentype                    image/bmp                    image/svg+xml                    image/x-icon                    text/cache-manifest                    text/css                    text/plain                    text/vcard                    text/vnd.rim.location.xloc                    text/vtt                    text/x-component                    text/x-cross-domain-policy;    }}

将之前下载完毕的 flarum 程序放置到 wwwroot 目录中,便可以开始程序的安装了。

使用 docker-compose up-d 将程序运行起来,访问 flarum.lab.com 对程序进行配置。

安装应用

简单填写安装界面需要的要素后,点击安装按钮。

片刻之后,程序安装就完毕了,可以看到界面还是十分清爽的。

管理后台比较简单,很难满足我们的日常使用需求,不过好在现在可以编写插件进行功能增强。

对程序运行框架做优化

程序的安装部分已经结束了,但是考虑到后续的维护,我们还需要做一些额外的工作。

让应用自适应运行环境

应用安装完毕,我们再次查看应用目录,发现目录中多了一个 config.php 文件。

代码语言:javascript
复制
wwwroot├── CHANGELOG.md├── LICENSE├── README.md├── composer.json├── composer.lock├── config.php├── extend.php├── flarum├── public│   ├── assets│   └── index.php├── storage│   ├── cache│   ├── formatter│   ├── less│   ├── locale│   ├── logs│   ├── sessions│   ├── tmp│   └── views└── vendor

文件内容如下,记录了程序运行配置:

代码语言:javascript
复制
<?php return array (  'debug' => false,  'database' =>  array (    'driver' => 'mysql',    'host' => 'flarum',    'port' => 3306,    'database' => 'flarum',    'username' => 'flarum',    'password' => 'flarum',    'charset' => 'utf8mb4',    'collation' => 'utf8mb4_unicode_ci',    'prefix' => 'flarum_',    'strict' => false,    'engine' => 'InnoDB',    'prefix_indexes' => true,  ),  'url' => 'https://flarum.lab.com',  'paths' =>  array (    'api' => 'api',    'admin' => 'admin',  ),);

考虑到程序可能运行在不同的环境中(生产、测试、开发),数据库、网站地址等信息存在变化的可能,如果它能够自动读取环境变量可以免除维护多份配置的麻烦事,并简化发布过程。

对它进行简单的修改:

代码语言:javascript
复制
<?php return array (  'debug' => ($_SERVER['FLARUM_APP_DEBUG'] === 'true'),  'database' =>  array (    'driver' => 'mysql',    'host' => $_SERVER['FLARUM_DB_HOST'],    'database' => $_SERVER['FLARUM_DB_NAME'],    'username' => $_SERVER['FLARUM_DB_USER'],    'password' => $_SERVER['FLARUM_DB_PASS'],    'charset' => 'utf8mb4',    'collation' => 'utf8mb4_unicode_ci',    'prefix' => 'flarum_',    'port' => '3306',    'strict' => false,  ),  'url' => $_SERVER['FLARUM_APP_URL'],  'paths' =>  array (    'api' => 'api',    'admin' => 'admin',  ),);

同时也要对 docker-compose.yml 进行简单的修改,把 .env 当作环境变量“注入”到应用中。

代码语言:javascript
复制
  php:    image: ${DOCKER_PHP_IMAGE}    restart: always    expose:      - 9000    env_file: .env

最后,在 .env 里声明上面配置文件需要的变量名称即可。

代码语言:javascript
复制
DOCKER_DOMAIN_NAME=flarum.lab.comDOCKER_PHP_IMAGE=php-fpm-flarum:7.3.2DOCKER_NGINX_IMAGE=nginx:1.17.1-alpine
FLARUM_DB_HOST=flarumFLARUM_DB_NAME=flarumFLARUM_DB_USER=flarumFLARUM_DB_PASS=flarum
FLARUM_APP_DEBUG=trueFLARUM_APP_URL=//flarum.lab.com

继续拆分项目结构

前文提过,如果我们要持续修改完善这个处于 beta 状态下的软件,需要对其代码进行保存维护,但是如果将环境和代码放置一处,修改调试的效率不免太低。

所以我们可以对上面的应用目录进行简化操作,将“应用代码”和“基础环境”进行拆分,未来调试发布仅需要更新文件即可,而不必对环境进行重新部署、重启等重操作。

如果你也有类似需求,也可以参考下图进行拆分,将应用软件的基础环境、Vendor 代码进行分拆。

简化后的目录如下:

代码语言:javascript
复制
.├── LICENSE├── README.md├── .env├── conf│   └── docker-nginx.conf├── logs├── update.sh└── wwwroot    ├── config.php    ├── extend.php    ├── flarum    ├── public    │   └── index.php    ├── storage    └── vendor

可以看到, wwwroot 目录被简化到只留下四个 PHP 文件,和几个空目录。

对程序进行修改发布,则可以使用 CI 配合 update.sh 更新脚本使用,将程序需要的 vendor 依赖文件进行同步更新,更新脚本可以参考下面:

代码语言:javascript
复制
#!/usr/bin/env bash
# 关闭服务echo "stop services."docker-compose down --remove-orphans
# 确保容器镜像存在cat .env | grep _IMAGE | cut -d '=' -f2 | while read image ; do  if test -z "$(docker images -q $image)"; then    echo "prepare docker images."    docker pull $image  fidone
# 清理之前存在的历史文件,并将新文件同步到执行目录中if [ -d "wwwroot/vendor" ]; then    echo "cleanup wwwroot/vendor."    rm -rf wwwroot/vendorfiif [ -d "/data/forum-test-vendor" ]; then    echo "update vendor."    cp -r /data/forum-test-vendor/vendor/ wwwroot/    cp /data/forum-test-vendor/composer.* wwwroot/fi

# 清理 & 重建目录echo 'cleanup directory'rm -rf ./wwwroot/storagemkdir -p ./wwwroot/storage/cachemkdir -p ./wwwroot/storage/formattermkdir -p ./wwwroot/storage/lessmkdir -p ./wwwroot/storage/localemkdir -p ./wwwroot/storage/logsmkdir -p ./wwwroot/storage/sessionsmkdir -p ./wwwroot/storage/tmpmkdir -p ./wwwroot/storage/views
# 重启服务echo 'restart services.'docker-compose up -d
# 修正文件权限docker ps -q -f status=running -f name=flarum_php |  while read container ; do   echo "fix container $container own && mod."   docker exec $container chown -R www-data:www-data /wwwroot   docker exec $container chmod -R 755 /wwwroot/storagedone

在进行了目录拆分后,项目的测试发布时间将可以从之前的分钟级缩短到 5~10s 秒。

最后

关于这个软件的折腾细节还有不少,后续陆续慢慢写出来吧。

引用我前一段时间在朋友圈发的内容作为结束:

合作单位在关键时刻因不可抗力取消了合作,周五机器删除代码、数据库下线。所有人五十天的忙碌付诸东流,项目按计划上线压力骤大。 只好重定方案,从MVP做起。不得不再次变身救火队员?‍?。 从收拾遗留问题、到做新架构设计、搭建各种环境和基础设施、调通后端基本流程,整了差不多三天。目测再搞一周应该就差不多啦!? 感谢各种开源软件,让问题变得快速可解,让我这个月还能空出时间办个“大事”。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 折腾技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用 Docker 和 Traefik 搭建 Flarum 轻论坛应用
    • 写在前面
      • 构建 PHP 容器
        • 搭建数据库
          • 搭建应用运行框架
            • 安装 Composer PHP 包管理软件
            • 下载 Flarum 程序代码
            • 配置软件运行环境
          • 安装应用
            • 对程序运行框架做优化
              • 让应用自适应运行环境
              • 继续拆分项目结构
            • 最后
            相关产品与服务
            容器镜像服务
            容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档