跳至内容

Jixun's Blog 填坑还是开坑,这是个好问题。

手动部署 Tandoor 食谱服务

Tandoor 是一个使用 Python 开发的食谱管理程序,使用 Web 访问。

如果环境允许,使用 Docker 部署是最方便的,这里就不介绍了。

我因为一些原因选择手动部署,踩了些坑,在此记录下。

基础信息 #

  • 官网: tandoor.dev
  • 内存: 运行时 ~300M,构建前端代码需要 ~2G 内存。
  • 参考: 参考了官网的手动部署教程。
  • 注意: 无官方中文语言包,但是这不会阻止你使用中文撰写食谱。

开始部署 #

范例环境为 Debian 12。大部分步骤一致,RHEL 系列系统需要注意替换部分指令。

建议:部署前将系统更新至最新,如 apt update && sudo apt dist-upgrade

如未特别说明,本文提及的指令均需要使用 root 账号执行。

数据库访问 #

数据库可以安装到同一个机器或单独一个机器。

执行下述 SQL 语句初始化一个用户名为 tandoor 密码为 tand00r 的数据库:

CREATE USER tandoor WITH PASSWORD 'tand00r';
CREATE DATABASE tandoor OWNER tandoor;

GRANT CONNECT ON DATABASE tandoor TO tandoor;
GRANT ALL PRIVILEGES ON DATABASE tandoor TO tandoor;

ALTER ROLE tandoor SET client_encoding TO 'utf8';
ALTER ROLE tandoor SET default_transaction_isolation TO 'read committed';
ALTER ROLE tandoor SET timezone TO 'UTC';

应用用户 #

单独分配一个用户给 Tandoor 储存数据。使用 root 执行下述指令:

adduser --system --shell "$(command -v nologin)" --home /var/lib/tandoor tandoor --no-create-home
mkdir -p /var/lib/tandoor/{app,logs,nodejs}

安装依赖 #

注意 Python 要求 3.9 或以上版本。

apt install -y curl nginx git python3 python3-dev python3-pip python3-venv \
    libpq-dev libsasl2-dev libldap2-dev libssl-dev

部署代码 #

下载源码并部署到指定目录:

curl -Ls https://github.com/TandoorRecipes/recipes/archive/refs/tags/1.5.4.tar.gz \
    | tar -zxf - -C /var/lib/tandoor/app --strip-components=1

然后初始化专属的虚拟环境:

python3 -m venv --prompt tandoor /var/lib/tandoor/venv
/var/lib/tandoor/venv/bin/pip install -r /var/lib/tandoor/app/requirements.txt

构建前端代码 #

首先需要简易部署一下比较新版本的 nodejs

curl -Ls https://nodejs.org/dist/v18.17.1/node-v18.17.1-linux-x64.tar.xz \
    | tar -Jxf - -C /var/lib/tandoor/nodejs --strip-components=1

因为是免安装,所以一会需要把指令包围在 PATH 环境变量配置内执行:

cd /var/lib/tandoor/app/vue

PATH="/var/lib/tandoor/nodejs/bin:$PATH" bash <<'EOF'

# 启用 yarn
corepack enable

# 安装依赖并构建
yarn install --frozen-lockfile && yarn build

EOF

最后,将构建后的文件部署到对应的位置:

# 部署构建后的文件
/var/lib/tandoor/venv/bin/python3 manage.py collectstatic --no-input
/var/lib/tandoor/venv/bin/python3 manage.py collectstatic_js_reverse

提示:如果机器的内存不够,你可以提前在其他设备构建好并打包,然后重复【部署代码】步骤:

# 使用 docker 容器构建:
#   node:18.17.1-bookworm
TANDOOR_VERSION="1.5.4"

# 部署源码
mkdir -p "tandoor-${TANDOOR_VERSION}"
curl -LfSs https://github.com/TandoorRecipes/recipes/archive/refs/tags/${TANDOOR_VERSION}.tar.gz \
    | tar -zx -C "tandoor-${TANDOOR_VERSION}" --strip-components 1

# 构建
pushd "tandoor-${TANDOOR_VERSION}"/vue
    yarn install --frozen-lockfile
    yarn build

    # 这个目录太大了,运行时不需要
    rm -rf node_modules
popd

# 打包
tar zcf tandoor-${TANDOOR_VERSION}.tar.gz "tandoor-${TANDOOR_VERSION}"

配置服务器 #

服务器设定需要在服务器端更改。

cd /var/lib/tandoor/app
cp -n .env.template .env
nano .env # 或其他你喜欢的编辑器

最基础的情况下需要修改下述内容:

  • SECRET_KEY: 随机生成,每个网站独一无二的密钥。
    • 例如 base64 /dev/urandom | head -c50
  • POSTGRES_*: PostgreSQL 服务器连接信息配置

最后,将该程序的目录所有权修改为 tandoor 系统用户:

chown -R tandoor /var/lib/tandoor

数据库迁移 #

第一次执行或升级应用程序后,需要更新数据库结构。这项操作在业内称之为数据库迁移(Database Migration)

cd /var/lib/tandoor/app/
env $(cat .env |grep "^[^#]" | xargs) \
    /var/lib/tandoor/venv/bin/python3 manage.py migrate

建立系统服务 #

首先安装一个名为 gunicorn_tandoor,然后设定为自动启动,并立即启动。

cat > /etc/systemd/system/gunicorn_tandoor.service <<EOF
[Unit]
Description=tandoor recipes
After=network.target

[Service]
Type=simple
Restart=always
RestartSec=3
User=tandoor
Group=www-data
WorkingDirectory=/var/lib/tandoor/app
EnvironmentFile=/var/lib/tandoor/app/.env
ExecStart=/var/lib/tandoor/venv/bin/gunicorn --bind unix:/var/lib/tandoor/tandoor.sock recipes.wsgi:application

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable gunicorn_tandoor
systemctl restart gunicorn_tandoor

配置 nginx 服务器 #

cat > /etc/nginx/conf.d/tandoor.conf <<'EOF'
server {
  listen 8002;
  access_log /var/log/nginx/access_tandoor.log;
  error_log /var/log/nginx/error_tandoor.log;

  # serve media files
  location /static/ {
    alias /var/lib/tandoor/app/cookbook/static/;
  }

  location /media/ {
    alias /var/lib/tandoor/mediafiles/;
  }

  location / {
    proxy_set_header Host $http_host;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://unix:/var/lib/tandoor/tandoor.sock;
  }
}
EOF

nginx -t && nginx -s reload

注意这个配置文件没有 HTTPS,推荐使用 acme.sh + DNS 验证方式获取免费证书,并配置自动续签。

结束 #

部署完成后,你应当可以通过 ip:8082 来访问该服务器了。

此时应该还会有一些基础的配置(如默认管理员账号),本文就此略过。

最终效果 #

部署后的首页截图

知识共享许可协议 本作品采用知识共享署名-相同方式共享 4.0 国际许可协议进行许可。

评论区