7

Phabricator 切换使用 Bitnami 容器镜像

 3 years ago
source link: https://soulteary.com/2021/04/18/phabricator-switched-to-bitnami-docker-image.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Phabricator 切换使用 Bitnami 容器镜像

2021年04月18日阅读Markdown格式7591字16分钟阅读

分享如何将自定义容器镜像切换到 Bitnami 容器镜像,以及如何搭配反向代理软件(如 Traefik)配置使用。

去年曾分享过一篇关于 Phabricator 的内容,《使用 Docker 和 Traefik v2 搭建 Phabricator》,当时介绍了如何构建自定义的容器镜像,以及如何搭配汉化补丁使用应用。

时隔一年,伴随着软硬件升级,Phabricator 的服务迁移也被提上了日程。

考虑到尽可能省心的长期使用,我选择将镜像切换至了 Bitnami 的镜像,这样可以使用到每小时都由 GitHub 构建的透明可信的镜像,以及更少的操心各种安全补丁和升级的事情。

Bitnami 的镜像提供非常多的环境变量配置,用来应对各种场景。然而针对以下两个场景的支持却不够完善:

  • 使用已有数据库运行软件,而非从零到一进行初始化。
  • 使用反向代理服务,而非直接提供服务。

浏览仓库代码中的 Dockerfile ,可以看到项目启动前的入口脚本和预执行脚本各有一个文件:

ENTRYPOINT [ "/opt/bitnami/scripts/phabricator/entrypoint.sh" ]
CMD [ "/opt/bitnami/scripts/phabricator/run.sh" ]

观察 entrypoint.sh 脚本,可以看到这个脚本调用了 Web 服务器、数据库、以及应用初始化相关的脚本。

#!/bin/bash

# shellcheck disable=SC1091

set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace # Uncomment this line for debugging purpose

# Load Phabricator environment
. /opt/bitnami/scripts/phabricator-env.sh

# Load libraries
. /opt/bitnami/scripts/libbitnami.sh
. /opt/bitnami/scripts/liblog.sh
. /opt/bitnami/scripts/libwebserver.sh

print_welcome_page

if [[ "$1" = "/opt/bitnami/scripts/phabricator/run.sh" || "$1" = "/opt/bitnami/scripts/$(web_server_type)/run.sh" || "$1" = "/opt/bitnami/scripts/nginx-php-fpm/run.sh" ]]; then
    info "** Starting Phabricator setup **"
    /opt/bitnami/scripts/"$(web_server_type)"/setup.sh
    /opt/bitnami/scripts/php/setup.sh
    /opt/bitnami/scripts/mysql-client/setup.sh
    /opt/bitnami/scripts/phabricator/setup.sh
    /post-init.sh
    info "** Phabricator setup finished! **"
fi

echo ""
exec "$@"

其中有一个脚本路径 /opt/bitnami/scripts/phabricator/setup.sh 比较可疑,对这个脚本进行 phabricator/setup.sh 翻阅,可以看到除了一些检查环境就绪与否的准备工作外,还可以找到两个基础依赖:

...

# Load libraries
. /opt/bitnami/scripts/libphabricator.sh
. /opt/bitnami/scripts/libwebserver.sh

...

继续翻阅 /opt/bitnami/scripts/libphabricator.sh 这个脚本,会看到这个脚本真正定义了 phabricator 所有的应用配置,有一部分和容器环境变量(包含未被文档说明的),也和这个脚本进行了绑定,所以从这里入手进行修改,再合适不过了。

调整脚本:添加时区设置

如果想让 phabricator 时间展示正确,需要进行时区设置,我们找到 phabricator_initialize 函数,在其中添加对 phabricator.timezone 的设置:

########################
# Ensure Phabricator is initialized
# Globals:
#   PHABRICATOR_*
# Arguments:
#   None
# Returns:
#   None
#########################
phabricator_initialize() {
    # Check if Phabricator has already been initialized and persisted in a previous run
    local -r app_name="phabricator"
    local -r port="${WEB_SERVER_HTTP_PORT_NUMBER:-"$WEB_SERVER_DEFAULT_HTTP_PORT_NUMBER"}"
    if ! is_app_initialized "$app_name"; then
        info "Creating Phabricator configuration file"
        # Modified by @soulteary
        phabricator_conf_set "phabricator.timezone" "Asia/Shanghai"

调整脚本:更新数据库命名空间

找到 phabricator_configure_database_credentials 函数,对 storage.default-namespace 配置项目进行更新,如果你没有设置过,需要将这个项目删除或注释掉,避免应用启动之后找不到之前的数据:

#########################
# Configure Phabricator database
# Globals:
#   PHABRICATOR_*
# Arguments:
#   $1 - database user name
#   $2 - database user password
# Returns:
#   None
#########################
phabricator_configure_database_credentials() {
    local -r db_user="${1:?missing database user}"
    local -r db_pass="${2:?missing database password}"

    info "Configuring database"
    phabricator_conf_set "mysql.host"                     "$PHABRICATOR_DATABASE_HOST"
    phabricator_conf_set "mysql.port"                     "$PHABRICATOR_DATABASE_PORT_NUMBER"
    phabricator_conf_set "mysql.user"                     "$db_user"
    phabricator_conf_set "mysql.pass"                     "$db_pass"
    # Modified by @soulteary
    # phabricator_conf_set "storage.default-namespace"      "bitnami_phabricator"
    phabricator_conf_set "storage.mysql-engine.max-size"  "0"
}

调整编排文件:设置数据库

因为我们要直接使用老数据库,所以这里不能让脚本运行“数据库初始化”那一套流程,需要针对编排文件进行环境变量设置,让脚本认为数据库结构已就绪,不需要进行初始化,并且使用已有的数据库配置提供服务:

...
    environment:
      ...
      # 需要和 PHABRICATOR_SKIP_BOOTSTRAP 一起使用,否则还需要设置更多的冗余内容
      - ALLOW_EMPTY_PASSWORD=yes
      - PHABRICATOR_SKIP_BOOTSTRAP=yes
      - PHABRICATOR_DATABASE_HOST=database
      - PHABRICATOR_DATABASE_PORT_NUMBER=3306
      - PHABRICATOR_EXISTING_DATABASE_USER=root
      - PHABRICATOR_EXISTING_DATABASE_PASSWORD=QV8}!P![&QmR
      ...

调整脚本:调整应用链接以支持反向代理

为了能够支持反向代理环境,尤其是支持由反向代理网关提供“HTTPS”协议访问的能力,我们需要修改 phabricator_configure_hostphabricator_configure_alternate_file_domain 函数,让应用能够在运行在非 HTTPS 状况下,将页面链接渲染为 https:// 协议。

#########################
# Configure Phabricator host
# Globals:
#   PHABRICATOR_*
# Arguments:
#   None
# Returns:
#   None
#########################
phabricator_configure_host() {
    local host
    local scheme

    get_hostname() {
        if [[ -n "${PHABRICATOR_HOST:-}" ]]; then
            echo "$PHABRICATOR_HOST"
        else
            dns_lookup "$(hostname)" "v4"
        fi
    }

    host="$(get_hostname)"
    if is_boolean_yes "$PHABRICATOR_ENABLE_HTTPS"; then
        scheme="https"
        [[ "$PHABRICATOR_EXTERNAL_HTTPS_PORT_NUMBER" != "443" ]] && host+=":${PHABRICATOR_EXTERNAL_HTTPS_PORT_NUMBER}"
    else
        scheme="http"
        [[ "$PHABRICATOR_EXTERNAL_HTTP_PORT_NUMBER" != "80" ]] && host+=":${PHABRICATOR_EXTERNAL_HTTP_PORT_NUMBER}"
    fi
    info "Configuring Phabricator URL to ${scheme}://${host}"
    # Modified by @soulteary
    scheme="https"
    phabricator_conf_set "phabricator.base-uri" "${scheme}://${host}"
}

#########################
# Configure Phabricator alternate file domain
# Globals:
#   PHABRICATOR_*
# Arguments:
#   None
# Returns:
#   None
#########################
phabricator_configure_alternate_file_domain() {
    local afd="$PHABRICATOR_ALTERNATE_FILE_DOMAIN"
    local scheme
    if is_boolean_yes "$PHABRICATOR_ENABLE_HTTPS"; then
        scheme="https"
        [[ "$PHABRICATOR_EXTERNAL_HTTPS_PORT_NUMBER" != "443" ]] && afd+=":${PHABRICATOR_EXTERNAL_HTTPS_PORT_NUMBER}"
    else
        scheme="http"
        [[ "$PHABRICATOR_EXTERNAL_HTTP_PORT_NUMBER" != "80" ]] && afd+=":${PHABRICATOR_EXTERNAL_HTTP_PORT_NUMBER}"
    fi
    # Modified by @soulteary
    scheme="https"
    info "Configuring Phabricator Alternate File Domain to ${scheme}://${afd}"
    phabricator_conf_set "security.alternate-file-domain" "${scheme}://${afd}"
}

编排文件对应的配置也需要声明:

...
    environment:
      ...
      - PHABRICATOR_ENABLE_HTTPS=false
      - PHABRICATOR_HOST=board.lab.com
      - PHABRICATOR_ALTERNATE_FILE_DOMAIN=board-file.lab.com
      ...

完整的容器编排配置

将上面提到的内容更新到 libphabricator.sh 中,然后编写容器编排配置文件:

version: '3.7'

services:

  phabricator:
    image: bitnami/phabricator:2021.13.0
    expose:
      - 8080
    environment:
      - APACHE_HTTP_PORT_NUMBER=8080
      - PHABRICATOR_ENABLE_HTTPS=false
      - PHABRICATOR_HOST=board.lab.com
      - PHABRICATOR_ALTERNATE_FILE_DOMAIN=board-file.lab.com
      - ALLOW_EMPTY_PASSWORD=yes
      - PHABRICATOR_SKIP_BOOTSTRAP=yes
      - PHABRICATOR_DATABASE_HOST=board.data.lab.com
      - PHABRICATOR_DATABASE_PORT_NUMBER=3306
      - PHABRICATOR_EXISTING_DATABASE_USER=root
      - PHABRICATOR_EXISTING_DATABASE_PASSWORD=QV8}!P![&QmR
      - PHABRICATOR_ENABLE_PYGMENTS=true
    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(`board.lab.com`, `board-file.lab.com`, `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(`board.lab.com`, `board-file.lab.com`, `phabricator.lab.io`, `phabricator-file.lab.io`)"
      - "traefik.http.services.phabbackend.loadbalancer.server.scheme=http"
      - "traefik.http.services.phabbackend.loadbalancer.server.port=8080"
    volumes:
      - ./libphabricator.sh:/opt/bitnami/scripts/libphabricator.sh:ro

networks:
  traefik:
    external: true

将上面的内容保存为 docker-compose.yml, 使用 docker-compose up -d,即可将应用启动起来了。

重设用户密码

在切换数据库和应用版本后,我们可能会遇到用户无法登陆的状况。

这里可以采取官方issue中的方式进行用户密码重置,以用户名 soulteary 为例,执行下面的脚本,可以快速获得密码重置链接:

docker-compose exec phabricator /opt/bitnami/phabricator/bin/auth recover soulteary
Use this link to recover access to the "soulteary" account from the web interface:

    https://board.lab.com/login/once/recover/1/eedkghmtxrvkktaqof7di54n5lkabcd/

After logging in, you can use the "Auth" application to add or restore authentication providers and allow normal logins to succeed.

访问链接,即可重置密码,再次登陆应用中。

这篇关于 Phabricator 切换 Bitnami 镜像的内容,就先写到这里。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK