ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Deployer Provision Recipe 详解:从裸机到可部署 Web 服务器的全自动配置指南

Deployer Provision Recipe 详解:从裸机到可部署 Web 服务器的全自动配置指南 Deployer Provision Recipe 详解从裸机到可部署 Web 服务器的全自动配置指南【免费下载链接】deployerThe PHP deployment tool with support for popular frameworks out of the box项目地址: https://gitcode.com/gh_mirrors/de/deployerProvision Recipe 是 Deployer 提供的服务器自动化配置方案用于将一台全新的 Ubuntu 服务器一键配置成可直接运行 PHP 应用的生产环境——包括系统更新、PHP/FPM、Node.js、数据库、Caddy Web 服务器、防火墙、SSH 安全策略与部署用户等全部环节。本文以 docs/recipe/provision.md 为骨架结合 recipe/provision.php 及各子任务源码完整讲解该 Recipe 的配置参数、15 个编排任务的作用与执行顺序、以及每个子模块PHP、数据库、Node.js、用户、网站的实现细节让你既能读懂源码也能直接上手将一台新服务器纳入 Deployer 管理。一、Recipe 概览与引入方式Provision Recipe 不是一个独立的单一文件而是由 5 个子 Recipe 组合而成的总入口。在 Deployer 部署脚本deploy.php中通过以下方式引入require recipe/provision.php;引入后recipe/provision.php 会自动再引入 5 个子模块子 Recipe文件负责内容Databasesrecipe/provision/databases.phpMySQL / MariaDB / PostgreSQL 的安装与建库建用户Nodejsrecipe/provision/nodejs.php通过 fnm 安装 Node.js默认 LTS 版本Phprecipe/provision/php.phpPHP 与 PHP-FPM 的安装与调优、ComposerUserrecipe/provision/user.php创建部署用户deployer、配置 sudo 与 SSHWebsiterecipe/provision/website.phpCaddy 服务器配置与网站站点落盘此外源码中还有一行add(recipes, [provision]);recipe/provision.php将provision注册进 Deployer 的配方列表便于dep recipe:list之类的命令检索。二、配置参数ConfigurationProvision Recipe 定义了两个顶层配置项其余大量参数如php_version、db_type、domain等由各子 Recipe 定义。它们共同构成了整个配置流程所需的全部输入。2.1 lsb_release// Name of lsb_release like: focal, bionic, etc. // As only Ubuntu 20.04 LTS is supported for provision should be the focal. set(lsb_release, function () { return run(lsb_release -s -c); });含义返回远端服务器的 LSB 发行版代号例如focalUbuntu 20.04、bionicUbuntu 18.04。默认值run(lsb_release -s -c)即动态执行远端命令获取。适用前提文档明确说明 Provision 仅官方支持 Ubuntu 20.04 LTS因此该值应为focal。它用于在后续流程中判断系统环境与选择匹配的软件源。源码位置recipe/provision.php。2.2 provision_user// Default user to use for provisioning. set(provision_user, root);含义执行整个 provisioning 流程时使用的远程账号。默认值root。作用所有provision:*任务在开始处都会执行set(remote_user, get(provision_user))将当前任务的执行用户切换到该账号通常是root以保证有权限安装软件包、修改系统配置。源码位置recipe/provision.php。2.3 子 Recipe 中的交互式参数这些参数大多不是写死在配置里而是在访问时通过交互式提问自动收集Deployer 的ask系列函数保证一台新服务器在无任何预配置的情况下也能完成初始化。全部参数如下参数默认值 / 交互提示定义位置sudo_passwordaskHiddenResponse( Password for sudo: )密码隐藏输入recipe/provision/user.phpdomainask( Domain: , get(hostname))默认取主机名recipe/provision/website.phppublic_pathask( Public path: , public)recipe/provision/website.phpphp_version自动探测composer.json中的require.php并归一化如^8.2→8.2探测失败默认8.4可选5.6/7.4/8.2/8.3/8.4/8.5recipe/provision/php.phpdb_typeaskChoice( What DB to install? , [none,mysql,mariadb,postgresql], 0)默认none第 3 个参数为默认选项下标 0recipe/provision/databases.phpdb_nameask( DB name: , prod)recipe/provision/databases.phpdb_userask( DB user: , deployer)recipe/provision/databases.phpdb_passwordaskHiddenResponse( DB password: )recipe/provision/databases.phpnode_version--lts即安装 Node.js 长期支持版recipe/provision/nodejs.php关键机制——provision:configure的配置回显当某些参数未被你在部署脚本中显式设置即Context::get()-getConfig()-hasOwn($name)为 false时provision:configure会逐个调用get($name)触发交互式提问并在结束时把收集到的值以host(...)配置代码的形式打印出来见 recipe/provision.php形如 Configuration Start host({{alias}}) -set(sudo_password, xxx) -set(domain, example.com) -set(public_path, public) -set(php_version, 8.4) -set(db_type, mysql) -set(db_user, deployer) -set(db_name, prod) -set(db_password, xxx); Configuration End 这是设计上的一等公民用法首次 provisioning 采用交互问答之后把回显的代码固化进deploy.php后续即可全自动重跑。注意sudo_password、db_password属于敏感信息回显时请谨慎处理实际生产中建议改用环境变量或密钥管理。三、核心任务provision 编排与 15 个执行步骤provision是 Recipe 的入口任务源码 recipe/provision.php 中它被定义为一个分组任务group task按严格顺序依次执行 15 个子任务provision:check → provision:configure → provision:update → provision:upgrade → provision:install → provision:ssh → provision:firewall → provision:user → provision:php → provision:node → provision:databases → provision:composer → provision:server → provision:website → provision:verify运行方式dep provision会应用到当前 host 配置中的所有主机。下面按执行顺序逐个解析每个子任务的目的与实现。3.1 provision:check —— 检查前置系统状态源码recipe/provision.php任务首先将remote_user切到provision_user然后读取/etc/os-release并解析出NAME与VERSION_ID仅支持 Ubuntu若非 Ubuntu打印醒目的警告横幅并默认拒绝继续askConfirmation(Do you want to continue? (Not recommended), false)默认否用户坚持继续才会放行否则抛出RuntimeException。版本约束version_compare($version, 20, )即只接受 Ubuntu 20 及以上版本低于 20 同样需要用户二次确认。任务标记了-oncePerNode()同一节点主机在一次执行周期内只运行一次避免多主机并发时的重复检查。3.2 provision:configure —— 收集必需参数源码recipe/provision.php依次确保以下参数可用sudo_password、domain、public_path、php_version、db_type若db_type ! none再额外确保db_user、db_name、db_password。凡是未显式配置的参数都会触发交互式提问并把完整配置代码回显给用户见上文 2.3 节。该任务不标记oncePerNode但通常由provision编排顺序保证只执行一次。3.3 provision:update —— 添加软件源并更新源码recipe/provision.php按顺序执行apt-get update全程设置DEBIAN_FRONTENDnoninteractive避免交互卡死安装前置工具curl gpg software-properties-common添加 PHP PPAapt-add-repository ppa:ondrej/php -y设置LC_ALLC.UTF-8防止 locale 问题添加Caddy Web 服务器官方稳定源通过 Cloudsmith 下载 GPG 密钥去装甲后存入/usr/share/keyrings/caddy-stable-archive-keyring.gpg并把仓库描述写入/etc/apt/sources.list.d/caddy-stable.list再次apt-get update刷新索引。任务标记-oncePerNode()与-verbose()输出详细日志。3.4 provision:upgrade —— 升级全部软件包源码recipe/provision.php执行apt-get upgrade -y并设置900 秒超时软件包升级可能较慢同样使用非交互前端、oncePerNode与 verbose。3.5 provision:install —— 安装系统级软件包源码recipe/provision.php一次性安装 24 个基础包涵盖Web/服务caddy、sendmail、redis构建工具链build-essential、gcc、make、pkg-config、libpcre3-dev、libsqlite3-dev、libmcrypt4运维/安全fail2ban、ufw防火墙、whois提供mkpasswd、ncdu磁盘分析通用工具acl、apt-transport-https、curl、git、unzip、uuid-runtime、debian-keyring、debian-archive-keyring、python-is-python3、sqlite3、nodejs其中nodejs只是系统基础包真正的 Node 版本管理由后面的provision:nodefnm负责whois包中的mkpasswd会在provision:user中用于生成密码哈希。任务同样有 900 秒超时、oncePerNode与 verbose。3.6 provision:ssh —— 配置 SSH 安全策略源码recipe/provision.phpsed -i s/PasswordAuthentication .*/PasswordAuthentication no/ /etc/ssh/sshd_config——禁用密码登录强制密钥认证ssh-keygen -A—— 生成缺失的主机密钥service ssh restart—— 重启 SSH 服务生效若/root/.ssh不存在则创建并初始化authorized_keys。⚠️安全提示禁用密码登录前请务必确保你的公钥已部署可先用dep provision:ssh_copy_id或手动写入authorized_keys否则可能把自己锁在服务器外。3.7 provision:firewall —— 配置防火墙源码recipe/provision.php使用 UFWufw allow 22 # SSH ufw allow 80 # HTTP ufw allow 443 # HTTPS ufw --force enable--force保证无交互直接启用。默认只放行 22/80/443 三个端口其余全部拒绝符合 Web 服务器的最小暴露面原则。3.8 provision:user —— 创建 deployer 部署用户源码recipe/provision/user.php这是从root 一次性配置切换到日常部署用户的关键步骤若id deployer已存在直接提示deployer user already exist并跳过源码中留有 TODO 注释表明后续版本可能补充对既有用户的校验与密码同步。否则依次执行useradd deployer创建用户创建/home/deployer/.ssh与/home/deployer/.deployeradduser deployer sudo加入 sudo 组chsh -s /bin/bash deployer设置默认 shell从 root 复制.profile、.bashrc并开启彩色提示符force_color_promptyes用mkpasswd -m sha-512将sudo_password生成 SHA-512 哈希通过usermod --password设置密码使用 secrets 机制避免密码明文出现在命令输出中把 root 的authorized_keys复制给 deployer继承密钥登录能力并为 deployer 生成 ed25519 密钥对设置目录/文件权限chown deployer:deployer、.ssh700、私钥与authorized_keys600 等权限变更的异常会被捕获并降级为 warning将 deployer 追加到www-data与caddy组使其能读写 Web 相关资源。3.9 provision:ssh_copy_id —— 复制公钥到远端源码recipe/provision/user.php独立于主流程的辅助任务不包含在provision编排内可单独运行dep provision:ssh_copy_id。逻辑依次探测本机~/.ssh/id_rsa.pub、id_ed25519.pub、id_ecdsa.pub、id_dsa.pub通过parse_home_dir解析家目录都没找到则提示手动粘贴公钥若仍为空则跳过并提示否则通过环境变量PUBLIC_KEY追加写入/home/deployer/.ssh/authorized_keys避免引号/特殊字符转义问题。3.10 provision:php —— 安装并调优 PHP / PHP-FPM源码recipe/provision/php.php根据php_version如8.4安装 16 个扩展包bcmath、cli、curl、dev、fpm、gd、imap、intl、mbstring、mysql、pgsql、readline、soap、sqlite3、xml、zip一条命令安装完毕。随后通过sed对 CLI 与 FPM 两份php.ini以及 FPM 池配置pool.d/www.conf做调优配置项设置值适用文件error_reportingE_ALLCLI / FPM 的php.inidisplay_errorsOnCLI / FPM 的php.inimemory_limit512MCLI / FPM 的php.iniupload_max_filesize128MCLI / FPM 的php.inidate.timezoneUTCCLI / FPM 的php.inicgi.fix_pathinfo0FPM 的php.inirequest_terminate_timeout60FPM 的www.confcatch_workers_outputyesFPM 的www.confphp_flag[display_errors]yesFPM 的www.confphp_admin_value[error_log]/var/log/fpm-php.www.logFPM 的www.confphp_admin_flag[log_errors]onFPM 的www.conf最后对会话目录/var/lib/php/sessions设置733权限并加上 sticky bitt确保 PHP-FPM 与 CLI 都能写入 session。任务标记-limit(1)限制并发为 1避免多主机并行冲突与 verbose。该子模块还附带两个日志查看任务logs:php-fpmrecipe/provision/php.php自动列出/var/log下含fpm的日志文件并tail -f无匹配时抛出异常。provision:composerrecipe/provision/php.php从 getcomposer.org 下载安装脚本并用 PHP 执行将composer.phar移到/usr/local/bin/composer全局可用oncePerNode。3.11 provision:node —— 通过 fnm 安装 Node.js源码recipe/provision/nodejs.php若检测到旧参数nodejs_version被设置直接抛出异常提示改用node_version。通过uname -m探测 CPU 架构从 fnmFast Node ManagerGitHub Releases 下载对应二进制arm/armv7*→fnm-arm32aarch*/armv8*→fnm-arm64其余 →fnm-linux。解压到/tmp安装到/usr/local/bin/fnm执行fnm install {{node_version}}默认--lts即 LTS 版。将eval fnm env写入/etc/profile.d/fnm.sh使所有登录 shell 自动加载 fnm 环境。3.12 provision:databases —— 安装并初始化数据库源码recipe/provision/databases.php入口任务provision:databasesL27-L37读取db_type若为none直接跳过否则invoke(provision: . $dbType)动态分发到对应子任务并标记-limit(1)。三个数据库子任务细节provision:mysqlL39-L48apt-get install -y mysql-server900 秒超时以 root 免密方式创建用户{{db_user}}同时允许0.0.0.0与%来源密码通过secrets 参数注入%db_password%避免出现在命令回显中授予*.*全部权限含GRANT OPTIONFLUSH PRIVILEGES创建数据库{{db_name}}字符集UTF8mb4、排序规则utf8mb4_bin。provision:mariadbL50-L59与 MySQL 流程完全一致仅安装包改为mariadb-server。provision:postgresqlL61-L66安装postgresql postgresql-contrib以sudo -u postgres psql依次执行CREATE DATABASE {{db_name}};、CREATE USER {{db_user}} WITH ENCRYPTED PASSWORD ...;、GRANT ALL PRIVILEGES ON DATABASE {{db_name}} TO {{db_user}};。3.13 provision:server —— 配置服务器基础目录源码recipe/provision/website.php将caddy用户加入www-data组创建/var/deployer目录并把仓库内置的 404.html 写入其中作为全局 404 兜底页面。3.14 provision:website —— 生成并激活 Caddy 站点源码recipe/provision/website.php这是把应用真正挂上 Web 服务器的步骤通过become(deployer)临时切换到 deployer 用户执行完由$restoreBecome()还原创建部署目录{{deploy_path}}并chown deployer:deployer随后set(deploy_path, realpath(...))归一化路径创建log目录并chgrp caddy log用模板引擎解析内置的 Caddyfile 模板其中的{{domain}}、{{deploy_path}}、{{public_path}}、{{php_version}}会被替换成实际值智能合并策略若站点目录已存在 Caddyfile则生成Caddyfile.new并与旧文件做diff无差异则删除新文件有差异则打印 diff 并让用户选择保留old还是newaskChoice默认保留旧版不存在则直接写入回到 root 身份若/etc/caddy/Caddyfile尚未import {{deploy_path}}/Caddyfile则追加该行随后service caddy reload热加载输出Website {{domain}} configured!。模板 recipe/provision/Caddyfile 的核心内容如下它同时定义了反向代理、FastCGI 与访问日志{{domain}} { root * {{deploy_path}}/current/{{public_path}} encode zstd gzip file_server php_fastcgi * unix//run/php/php{{php_version}}-fpm.sock { resolve_root_symlink } log { output file {{deploy_path}}/log/access.log { mode 0644 } } handle_errors { 404 { expression {http.error.status_code} 404 } rewrite 404 /404.html encode zstd gzip file_server { root /var/deployer } } }要点解读root指向{{deploy_path}}/current/{{public_path}}——这与 Deployer 的符号链接 release 机制天然契合current即当前版本软链接配合resolve_root_symlink让 PHP-FPM 正确解析真实路径encode zstd gzip启用 zstd 与 gzip 双重压缩php_fastcgi直连php{{php_version}}-fpm.sockUnix socket即前面安装的 FPM 版本访问日志写入{{deploy_path}}/log/access.log404 请求被重写到/var/deployer/404.html的统一错误页。3.15 provision:verify —— 验证 provisioning 是否成功源码recipe/provision.php使用fetch({{domain}}, get, [], null, $info, true)对配置好的域名发起 HTTP GET 请求并检查返回的$info[http_code]由于此时尚未部署任何应用current目录还不存在预期返回404命中即输出provisioned successfully!。验证逻辑的合理之处404 说明 Caddy 已正常监听该域名并返回了内置错误页而非连接失败/超时/500恰好证明Web 服务器就绪、只等部署代码这一中间态与部署应用后再验证 200的场景形成闭环。3.16 辅助日志任务除编排任务外Provision 还提供了两个实时日志任务logs:accessrecipe/provision/website.phptail -f {{deploy_path}}/log/access.log跟踪站点访问日志logs:caddyrecipe/provision/website.phpsudo journalctl -u caddy -f跟踪 Caddy 服务日志。四、推荐使用流程把 Provision Recipe 纳入 Deployer 工作流的推荐路径准备一台全新的 Ubuntu 20.04或更新版本服务器确保能从本机免密 SSH 登录 root在部署脚本中引入require recipe/provision.php;并定义 host。预置公钥可选但强烈推荐先执行dep provision:ssh_copy_id把本机公钥写入远端。执行配置dep provision按提示回答 sudo 密码、域名、公开目录、PHP 版本、数据库类型/名称/用户/密码等提问。固化配置把provision:configure回显的host(...)-set(...)代码写入deploy.php此后即可无交互重跑或直接为所有参数提供显式配置例如host(example.com) -set(provision_user, root) -set(domain, example.com) -set(public_path, public) -set(php_version, 8.4) -set(db_type, mysql) -set(db_user, deployer) -set(db_name, prod) -set(db_password, your-strong-password) -set(sudo_password, your-sudo-password) -set(deploy_path, /var/www/example.com);部署应用provision 完成后即可用常规的dep deploy流程发布代码current符号链接由 Caddyfile 的resolve_root_symlink平滑衔接。日常运维使用logs:access、logs:caddy、logs:php-fpm观察运行日志。五、重要限制与注意事项操作系统强约束源码在 provision:check 中明确只支持 Ubuntu且建议 20文档声明 As only Ubuntu 20.04 LTS is supported for provision其他发行版会收到警告并需人工确认才能继续非 Ubuntu 上不建议执行。全程以 root 运行provision_user默认root请保证 root 的 SSH 公钥已部署provision:ssh会禁用 SSH 密码登录务必先确认密钥可用。交互式提问不可避免首次运行时多数参数sudo_password、domain、db_password等通过ask/askHiddenResponse/askChoice收集自动化 CI 场景请务必预先在脚本中-set()全部参数可参考provision:configure的回显代码。敏感信息处理数据库密码与 sudo 密码通过 Deployer 的secrets参数传入远端命令避免明文出现在进程列表中回显的配置代码含明文密码注意保管deploy.php。并发限制provision:php、provision:databases、provision:website标记了-limit(1)多数任务标记-oncePerNode()多主机场景下请理解这些约束以避免资源竞争。不可逆操作provision:upgrade会升级系统全部软件包900 秒超时provision:firewall会立即启用 UFW执行前请评估对现有环境的影响。六、小结Provision Recipe 是 Deployer 体系中从零到可部署的自动化方案provision一个命令即可串起系统检查、软件源、系统升级、基础软件、SSH 加固、防火墙、部署用户、PHP 与 FPM、Node.js、数据库、Caddy 站点直至最终验证的完整链路并且通过与current符号链接机制和resolve_root_symlink的配合与 Deployer 常规部署流程无缝衔接。理解 recipe/provision.php 及其 5 个子模块的实现既能让你安全地把它用在新服务器初始化上也能为你按需裁剪或扩展属于自己的 provisioning 流程提供参考。【免费下载链接】deployerThe PHP deployment tool with support for popular frameworks out of the box项目地址: https://gitcode.com/gh_mirrors/de/deployer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表