這篇文章躺在草稿箱裏有一個多月了,恰逢最近一段時間遠程協作需求,以及 Traefik v2 的升級,於是便有了這篇文章。

如果你的團隊也需要一個內部看板,Phabricator 是個不錯的選擇:能提供簡單的任務管理、能提供工作看板、支持代碼討論、甚至能夠讓設計師也使用起來,當然還有它主打的代碼審計 / Review和管理功能。

寫在前面

最早接觸它是在 2012 年,八年之後,這款工具的開源版本變的更加好用了。

從開源倉庫可以看到,社區版的代碼一直在持續更新,而且現在還提供了 SaaS 版本,考慮到私密性和賬戶集成等定製要求,這裏決定自建服務,並自行封裝容器鏡像。

考慮到不是所有人都有定製需求,這裏分別提供兩個方案,Bitnami 的容器方案,和完全基於官方代碼進行定製的容器方案。

目前社區最新版是 《stable - Promote 2020 Week 5》  ,Bitnami 會定時從官方倉庫中獲取版本,並進行容器封裝,倉庫地址: https://github.com/bitnami/bitnami-docker-phabricator ,相比官方更新會稍有延時,但是基本不影響使用。

準備數據庫

生產環境推薦使用雲服務商提供的數據庫,但是如果小規模使用,使用容器啓動一個數據庫示例也未嘗不可。

version: '3.7'
 
services:
 
  mariadb:
    image: mariadb
    environment:
      - MYSQL_ROOT_PASSWORD=phabricator
      - MYSQL_DATABASE=phabricator
    command: --max_allowed_packet=33554432 --sql_mode="STRICT_ALL_TABLES" --local-infile=0
    ports:
      - 13306:3306
    networks:
      - traefik
    healthcheck:
      test: "mysqladmin --password=phabricator ping -h 127.0.0.1"
      timeout: 5s
      retries: 20
    volumes:
      - './mariadb_data:/var/lib/mysql'
 
networks:
  traefik:
    external: true

將上面的內容保存爲 docker-compose.yml 並執行 docker-compose up -d 即可。

準備好數據庫後,我們聊聊怎麼簡單啓動一個 phabricator 服務。

Bitnami 容器方案

這裏提供兩個版本的配置文件,更多搭配 Traefik 使用的前置知識可以在過往的文章中 找到。

搭配 Traefik v1 使用

如果你還在使用 Traefik v1 ,那麼使用下面的配置,可以一鍵啓動封裝好的穩定版本。

version: '2'
services:
 
  phabricator:
    image: 'bitnami/phabricator:2019'
    expose:
      - 80
      - 443
    volumes:
      - './phabricator_data:/bitnami'
      - './extensions:/opt/bitnami/phabricator/src/extensions'
    environment:
      - PHABRICATOR_HOST=phabricator.soulteary.com
      - PHABRICATOR_USERNAME=soulteary
      - PHABRICATOR_PASSWORD=soulteary
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.port=80"
      - "traefik.frontend.rule=Host:phabricator.soulteary.com"
      - "traefik.frontend.entryPoints=https,http"
 
networks:
  traefik:
    external: true

搭配 Traefik v2 使用

當然,這裏更推薦搭配 Traefik v2 一起使用。

version: '3.7'
 
services:
 
  phabricator:
    image: 'bitnami/phabricator:2019'
    expose:
      - 80
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.phab0.middlewares=https-redirect@file"
      - "traefik.http.routers.phab0.entrypoints=http"
      - "traefik.http.routers.phab0.rule=Host(`phabricator.lab.io`,`phabricator-file.lab.io`)"
      - "traefik.http.routers.phab1.middlewares=content-compress@file"
      - "traefik.http.routers.phab1.entrypoints=https"
      - "traefik.http.routers.phab1.tls=true"
      - "traefik.http.routers.phab1.rule=Host(`phabricator.lab.io`,`phabricator-file.lab.io`)"
      - "traefik.http.services.phabbackend.loadbalancer.server.scheme=http"
      - "traefik.http.services.phabbackend.loadbalancer.server.port=80"
    volumes:
      - './phabricator_data:/bitnami'
      - './extensions:/opt/bitnami/phabricator/src/extensions'
 
networks:
  traefik:
    external: true

對程序進行漢化

感謝社區網友提供了程序的 漢化補丁 ,下載倉庫中的  PhabricatorSimplifiedChineseTranslation.php 並放置於上面配置文件指定的 extensions 目錄中後,啓動應用,等待應用啓動就緒後,在個人設置中切換中文即可。

接下來開始正餐,如何基於源代碼對 phabricator 進行容器封裝。

封裝 Phabricator 容器鏡像

官方安裝文檔 寫的比較詳細,甚至封裝了一個基礎的安裝腳本,我們基於此進行容器的 Dockerfile 的編寫。

FROM ubuntu:18.04
 
LABEL maintainer="[email protected]"
 
ENV DEBIAN_FRONTEND noninteractive
 
RUN apt-get update && apt-get upgrade -y && \
    echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections && export DEBIAN_FRONTEND=noninteractive && \
    apt-get install -y lsb-release curl && \
    # deps from: https://raw.githubusercontent.com/phacility/phabricator/stable/scripts/install/install_ubuntu.sh
    apt-get install -y tzdata sudo && \
    ln -fs /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    apt-get install -y git apache2 libapache2-mod-php php php-mysql php-gd php-curl php-apcu php-cli php-json php-mbstring php-zip python python-pip && \
    a2enmod rewrite && \
    pip install Pygments
 
WORKDIR /opt
 
RUN git clone https://github.com/phacility/phabricator.git --branch=stable --depth=1 && \
    cd phabricator && \
    git checkout cc11dff7d317b5a1e82e24ab571fef9abb633a49
 
RUN git clone https://github.com/phacility/arcanist.git --branch=stable --depth=1 && \
    cd arcanist && \
    git checkout 729100955129851a52588cdfd9b425197cf05815
 
RUN git clone https://github.com/phacility/libphutil.git --branch=stable --depth=1 && \
    cd libphutil && \
    git checkout 034cf7cc39940b935e83923dbb1bacbcfe645a85
 
RUN git clone https://github.com/arielyang/phabricator_zh_Hans.git --branch=master --depth=1 && \
    cd phabricator_zh_Hans && \
    git checkout ba5e602d934a6efacdc09082cd3a762449de45cf && \
    cp dist/\(stable\)\ Promote\ 2019\ Week\ 50/PhabricatorSimplifiedChineseTranslation.php ../phabricator/src/extensions/
 
COPY phabricator/docker-assets ./assets
 
RUN sed -i -e "s/post_max_size = 8M/post_max_size = 32M/g" /etc/php/7.2/apache2/php.ini && \
    sed -i -e "s/;opcache.validate_timestamps=1/opcache.validate_timestamps = 0/g" /etc/php/7.2/apache2/php.ini
 
RUN useradd daemon-user && \
    mkdir -p /data/repo && \
    chown -R daemon-user:daemon-user /data/repo && \
    ln -s /usr/lib/git-core/git-http-backend /usr/bin/ && \
    echo "Cmnd_Alias GIT_CMDS = /usr/bin/git*" >> /etc/sudoers.d/www-user-git && \
    echo "www-data ALL=(daemon-user) SETENV: NOPASSWD: GIT_CMDS" >> /etc/sudoers.d/www-user-git && \
    chmod 0440 /etc/sudoers.d/www-user-git
 
ENTRYPOINT ["bash", "-c", "/opt/assets/entrypoint.sh"]
 
EXPOSE 80

Dockerfile 主要分爲三個部分,第一部分進行基礎系統環境配置、系統環境依賴;第二部分獲取當前這個版本的程序代碼和應用依賴;第三部分配置應用權限、設置容器啓動腳本。

這裏所需的程序啓動腳本 entrypoint.sh 內容如下:

#!/usr/bin/env bash
 
./phabricator/bin/storage upgrade --force && \
./phabricator/bin/phd start
 
apachectl -D FOREGROUND

執行的工作也很簡單:初始化Phabricator 配置,並啓動 Web Server。

相關代碼我已經上傳至 GitHub ,並推送至 DockerHub 有需求的同學可以自取。

編寫服務配置

服務配置分爲兩部分,第一部分是 Web Server 使用的。

<VirtualHost *>
  ServerName phabricator.lab.io
  DocumentRoot /opt/phabricator/webroot
  RewriteEngine on
  RewriteRule ^(.*)$	/index.php?__path__=$1 [B,L,QSA]
 
  SetEnv HTTPS true
 
  <Directory "/opt/phabricator/webroot">
    Require all granted
  </Directory>
 
</VirtualHost>
 
<VirtualHost *>
  ServerName phabricator-file.lab.io
  DocumentRoot /opt/phabricator/webroot
  RewriteEngine on
  RewriteRule ^(.*)$	/index.php?__path__=$1 [B,L,QSA]
 
  <Directory "/opt/phabricator/webroot">
    Require all granted
  </Directory>
 
</VirtualHost>

將上面內容中的域名替換爲自己實際使用的地址後,保存爲  phabricator.conf ,接着準備應用配置:

{
  "phabricator.base-uri": "https://phabricator.lab.io/",
  "security.alternate-file-domain":"https://phabricator-file.lab.io/",
  "pygments.enabled": true,
  "phabricator.timezone":"Asia/Shanghai",
  "storage.local-disk.path":"/data/stor",
  "repository.default-local-path": "/data/repo",
  "phd.user": "daemon-user",
  "mysql.pass": "phabricator",
  "mysql.user": "root",
  "mysql.port": "3306",
  "mysql.host": "mariadb"
}

同樣,替換域名爲你自己的,並且將配置中的數據庫相關內容替換爲實際的數值,將文件保存爲 local.json 。(如果數據庫使用的是本文的內容,可以不需要修改)

編寫容器啓動配置

將上面保存的配置文件放置到指定目錄後,編寫應用啓動使用的 docker-compose.yml

version: '3.7'
 
services:
 
  phabricator:
    image: soulteary/phabricator:stable-2020-week-5
    expose:
      - 80
    networks:
      - traefik
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.routers.phab0.middlewares=https-redirect@file"
      - "traefik.http.routers.phab0.entrypoints=http"
      - "traefik.http.routers.phab0.rule=Host(`phabricator.lab.io`,`phabricator-file.lab.io`)"
      - "traefik.http.routers.phab1.middlewares=content-compress@file"
      - "traefik.http.routers.phab1.entrypoints=https"
      - "traefik.http.routers.phab1.tls=true"
      - "traefik.http.routers.phab1.rule=Host(`phabricator.lab.io`,`phabricator-file.lab.io`)"
      - "traefik.http.services.phabbackend.loadbalancer.server.scheme=http"
      - "traefik.http.services.phabbackend.loadbalancer.server.port=80"
    volumes:
      - ./phabricator_data/stor:/data/stor
      - ./phabricator_data/repo:/data/repo
      - ./phabricator/docker-assets/phabricator.conf:/etc/apache2/sites-available/000-default.conf:ro
      - ./phabricator/docker-assets/local.json:/opt/phabricator/conf/local/local.json:ro
 
networks:
  traefik:
    external: true

使用 docker-compose up -d 將應用啓動,並執行 docker-compose logs -f 查看應用啓動狀況。

Creating phabricator-dockerize_phabricator_1 ... done
Attaching to phabricator-dockerize_phabricator_1
phabricator_1  | Loading quickstart template onto "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:db.paste" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190523.myisam.01.documentfield.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190718.paste.01.edge.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190718.paste.02.edgedata.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190718.paste.03.paste.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190718.paste.04.xaction.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190718.paste.05.comment.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190802.email.01.storage.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190802.email.02.xaction.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190815.account.01.carts.php" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190815.account.02.subscriptions.php" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190816.payment.01.xaction.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190816.subscription.01.xaction.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190822.merchant.01.view.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190909.herald.01.rebuild.php" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190924.diffusion.01.permanent.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20190924.diffusion.02.default.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20191028.uriindex.01.rebuild.php" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20191113.identity.01.email.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20191113.identity.02.populate.php" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20191113.identity.03.unassigned.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20191114.email.01.phid.sql" to host "mariadb:3306"...
phabricator_1  | Applying patch "phabricator:20191114.email.02.populate.php" to host "mariadb:3306"...
phabricator_1  | Storage is up to date. Use "storage status" for details.
phabricator_1  | Synchronizing static tables...
phabricator_1  | Verifying database schemata on "mariadb:3306"...
phabricator_1  | 
phabricator_1  | 
phabricator_1  | Database                 Table                 Name         Issues
phabricator_1  | phabricator_differential differential_revision phid         Surplus Key
phabricator_1  | phabricator_differential differential_revision key_modified Missing Key
phabricator_1  | phabricator_differential differential_revision key_phid     Missing Key
phabricator_1  | phabricator_repository   repository_identity   key_email    Missing Key
phabricator_1  | phabricator_phortune     phortune_accountemail key_account  Missing Key
phabricator_1  | phabricator_phortune     phortune_accountemail key_address  Missing Key
phabricator_1  | phabricator_phortune     phortune_accountemail key_phid     Missing Key
phabricator_1  | phabricator_user         user_email            key_phid     Missing Key
phabricator_1  | phabricator_conpherence  conpherence_index                  Better Table Engine Available
phabricator_1  | Applying schema adjustments...
phabricator_1  | Completed applying all schema adjustments.
phabricator_1  |  ANALYZE  Analyzing tables...
phabricator_1  |  ANALYZED  Analyzed 535 table(s).
phabricator_1  | Freeing active task leases...
phabricator_1  | Freed 0 task lease(s).
phabricator_1  | Starting daemons as daemon-user
phabricator_1  | Launching daemons:
phabricator_1  | (Logs will appear in "/var/tmp/phd/log/daemons.log".)
phabricator_1  | 
phabricator_1  |     (Pool: 1) PhabricatorRepositoryPullLocalDaemon
phabricator_1  |     (Pool: 1) PhabricatorTriggerDaemon
phabricator_1  |     (Pool: 1) PhabricatorFactDaemon
phabricator_1  |     (Pool: 4) PhabricatorTaskmasterDaemon
phabricator_1  | 
phabricator_1  | Done.
phabricator_1  | AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.20.0.4. Set the 'ServerName' directive globally to suppress this message

當看到 Done. 的時候,就可以打開瀏覽器對 Phabricator 進行進一步配置啦。

打開瀏覽器,輸入你配置的域名後,Phabricator 將跳轉至 Dashboard。

剩下的事情就是根據你自己的需求進行應用配置啦。

最後

Phabricator 的搭建只是第一步,與現有倉庫集成、與CI 集成等內容留與後續再寫吧。

–EOF

相關文章