如何自动化网站部署到生产环境,包括压缩 CSS/JS?

如何自动化网站部署到生产环境,包括压缩 CSS/JS?

目前,我正在使用以下手动流程将我的 PHP 网站从暂存部署到生产环境:

  • 使用以下方法压缩 CSS 和 JavaScript 文件在线 YUI 压缩工具
  • 将原始 CSS 和 JavaScript 文件移动到另一个目录(以备份它们),然后用最小化的 CSS 和 JavaScript CSS 文件替换它们。
  • 开始将我的暂存服务器中的所有文件复制到我的 Windows PC。
  • 删除暂存的 .htaccess 和索引文件,以便它们不会被复制到生产服务器(这些文件包含暂存环境的特定内容)。
  • 打开 WinSCP 并转到生产服务器上的 Web 根目录,然后将主索引文件切换为“正在更新”文件,这样如果有访问者访问该网站,他们就会收到一条消息,提示该网站暂时关闭。
  • 然后使用 WinSCP 将其从我的电脑复制到生产 Web 服务器(这会覆盖服务器上所有现有文件),大约需要 4 分钟才能看到有很多文件。
  • 使用 SSH 登录生产服务器并运行大约 5 条命令来为各种可写目录设置适当的权限,并确保所有内容仍在 www-root 组下。我认为使用 SSH 的上传过程会更改所有现有权限。
  • 将“正在进行更新”索引文件切换回正常索引。

整个过程相当复杂,大约需要 5-10 分钟,而且每次我对网站进行更改时我都必须这样做,因此这已经成为一件苦差事。

现在有没有办法使用一些脚本工具来自动化这个过程?或者有没有一个好的部署工具可以完成所有这些工作?我的登台和生产机器是基于 Ubuntu 12.04 服务器的,所以我可以使用 bash 脚本来完成一些工作。

我认为目前可以做出的一些改进包括:

  • 在我的网站上添加一些代码,以便它检测网站是处于暂存状态还是生产状态,然后根据环境使用原始或压缩的 CSS/JavaScript 文件。这样我就不用手动切换文件了。
  • 使用命令行 YUI 压缩器并在需要时从脚本文件运行它。
  • 使用类似 rsync 的工具,这样它只会将更改的文件从我的暂存服务器复制到生产服务器,而不会覆盖每个文件

我曾经工作过的一家公司使用Fabric 命令行工具用于自动化部署和执行此类操作。但是这是一个好的选择吗?或者有更好的工具吗?

答案1

Fabric 非常适合这类任务。如果您熟悉 Python,那么您将可以灵活地完成很多任务。

Capistrano 是另一个可能有用的选项,我曾用它进行 Rails 部署,没有遇到任何问题。它允许您轻松地在远程主机上运行 shell 命令。

另一个选择可能是使用 Ant(我认为使用 Fabric 的 Python 方式要好得多)。

您是否在使用 git 之类的源代码管理?当您将其推送到“生产”分支时,您可以将其中一些任务添加为提交后挂钩。

Rsync 是最快、最安全的选择。确保排除所有不应在生产环境中使用的文件(备份文件、vim .swp 文件等)。

答案2

好吧,我最终使用了 Fabric,并想出了一个完全符合我要求的脚本。48 秒内,所有内容都复制到一个临时目录,所有文件都缩小,然后网站显示“正在上传页面”,所有内容都使用 SSH rsync 到服务器,然后再次上线。

from fabric.api import *
import datetime

# Format the current date as string 20120908-221521 (8 Sep 2012, 22:15:21)
# This will be used to append to the folder of the deployment directory so there's a backup of what was deployed
currentDate = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")

# Where the files for this deployment are stored
deploymentDir = "/var/www/deployments/mysite-deployment-" + currentDate

# SSH config for production server
env.use_ssh_config = True
env.hosts = ["mysite.net"]
env.user = "root"
env.port = 44

# Test connection to live server
def test():
  run("ls -al")

#--------------------------------------------------------------------------------------
# Main functions - to run use "fab live" from command line to update production server
#--------------------------------------------------------------------------------------
def live():
  backupToDeploymentDir()
  switchToProductionFiles()
  minifyCssAndJavaScript()
  switchToUpdatesInProgress()
  rsyncToProduction()
  switchToLive()  
  print("Deployment " + currentDate + " complete")

# Alias for the clearCachedFiles method - to run use "fab cc" or "fab live cc"
def cc():
  clearCachedFiles()

#-------------------
# Utility functions
#-------------------

# Backup to deployment directory
def backupToDeploymentDir():
  local("cp -a /var/www/staging/ %s" % deploymentDir)

# Remove development cache and log files, switch into production mode for htaccess and front controller
def switchToProductionFiles():
  local("rm -rf " + deploymentDir + "/temp/cache/*")
  local("rm -rf " + deploymentDir + "/temp/logs/*")
  local("rm -rf " + deploymentDir + "/fabfile.pyc")
  local("rm -rf " + deploymentDir + "/nbproject")
  local("rm " + deploymentDir + "/.htaccess")
  local("rm " + deploymentDir + "/index.php")
  local("mv " + deploymentDir + "/live-.htaccess " + deploymentDir + "/" + ".htaccess")

# Minify CSS and JavaScript files
def minifyCssAndJavaScript():  
  # Compress CSS
  local("sudo yui-compressor --line-break 1 -o " + deploymentDir + "/public/css/main.css " + deploymentDir + "/public/css/main.css --type css")
  local("sudo yui-compressor --line-break 1 -o " + deploymentDir + "/public/css/pdf.css " + deploymentDir + "/public/css/pdf.css --type css")
  local("sudo yui-compressor --line-break 1 -o " + deploymentDir + "/public/css/print.css " + deploymentDir + "/public/css/print.css --type css")
  local("sudo yui-compressor --line-break 1 -o " + deploymentDir + "/public/css/reset.css " + deploymentDir + "/public/css/reset.css --type css")

  # Compress CSS external library files
  local("sudo yui-compressor --line-break 1 -o " + deploymentDir + "/public/css/lib/fullcalendar.css " + deploymentDir + "/public/css/lib/fullcalendar.css --type css")
  local("sudo yui-compressor --line-break 1 -o " + deploymentDir + "/public/css/lib/fullcalendar.print.css " + deploymentDir + "/public/css/lib/fullcalendar.print.css --type css")

  # Compress JavaScript
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/ajax.js " + deploymentDir + "/public/js/ajax.js")
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/common.js " + deploymentDir + "/public/js/common.js")
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/default.js " + deploymentDir + "/public/js/default.js")
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/global.js " + deploymentDir + "/public/js/global.js")
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/organisation.js " + deploymentDir + "/public/js/organisation.js")

  # Compress JavaScript external library files
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/lib/fullcalendar.js " + deploymentDir + "/public/js/lib/fullcalendar.js")
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/lib/head.load.js " + deploymentDir + "/public/js/lib/head.load.js")
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/lib/jquery.js " + deploymentDir + "/public/js/lib/jquery.js")
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/lib/jquery-ui.js " + deploymentDir + "/public/js/lib/jquery-ui.js")
  local("sudo yui-compressor -o " + deploymentDir + "/public/js/lib/sha512.js " + deploymentDir + "/public/js/lib/sha512.js")

# Switch out the main index.php file for updates in progress one, before we rsync
def switchToUpdatesInProgress():
  run("mv /var/www/updates-index.php /var/www/index.php")

# Sync all files from deployment directory to live site then run permissions
def rsyncToProduction():
  local("rsync -azvv -e \"ssh -p 44\" " + deploymentDir + "/ [email protected]:/var/www")
  run("chown -R root:www-data /var/www")
  run("chmod -R 750 /var/www")
  run("chmod -R 770 /var/www/temp/cache")
  run("chmod -R 770 /var/www/temp/logs")
  run("chmod -R 770 /var/www/temp/sessions")
  run("chmod -R 770 /var/www/library/mPDF/ttfontdata")
  run("chmod -R 770 /var/www/library/mPDF/tmp")
  run("chmod -R 770 /var/www/library/mPDF/graph_cache")

# Clear cached files from the production server, useful if the PDF or JSON cache output has changed
def clearCachedFiles():
  run("rm -rf /var/www/temp/cache/*")
  print("Cached files cleared")

# Switch out the updates index.php file for the live one which will put the website live
def switchToLive():
  run("rm /var/www/index.php")
  run("mv /var/www/live-index.php /var/www/index.php")

相关内容