Como automatizar implantações de sites na produção, incluindo a redução de CSS / JS?

5

Atualmente estou implantando meu site PHP de teste para produção usando o seguinte processo manual:

  • Minimize os arquivos CSS e JavaScript usando a ferramenta de compressor YUI on-line .
  • Mova os arquivos CSS e JavaScript originais para outro diretório (para fazer backup deles) e substitua-os pelos arquivos CSS CSS e JavaScript reduzidos.
  • Comece a copiar todos os arquivos do meu servidor de teste para o meu PC Windows.
  • Exclua os arquivos .htaccess e de índice de armazenamento temporário para que eles não sejam copiados para o servidor de produção (esses arquivos possuem material específico para o ambiente de preparação).
  • Abra o WinSCP e vá para a raiz da Web no servidor de produção e, em seguida, desative o arquivo de índice principal para um dos "atualizações em andamento". Se algum visitante acessar o site, receberá uma mensagem dizendo que está inativo temporariamente.
  • Em seguida, copie do meu PC para o servidor da Web de produção usando o WinSCP (isso substitui todos os arquivos existentes no servidor) e leva cerca de quatro minutos para ver que há muitos arquivos.
  • Faça login no servidor de produção com SSH e execute cerca de 5 comandos para definir as permissões adequadas para vários diretórios graváveis e verifique se tudo ainda está no grupo de raiz da Web. Eu acho que o processo de upload com SSH muda todas as permissões existentes.
  • Altere o arquivo de índice "atualizações em andamento" de volta ao índice normal.

Todo esse processo é bastante complicado e leva de 5 a 10 minutos e eu tenho que fazer isso toda vez que faço alterações no site, então isso se tornou uma tarefa árdua.

Agora existe alguma maneira de automatizar esse processo usando alguma ferramenta de script? Ou há uma boa ferramenta de implantação que as pessoas usam que pode fazer tudo isso? Minhas máquinas de teste e produção são baseadas no servidor Ubuntu 12.04, então potencialmente eu poderia usar scripts de bash para fazer parte do trabalho.

Algumas melhorias que posso ver que poderiam ser feitas até agora seriam:

  • Adicione algum código ao meu site para que ele detecte se está em armazenamento temporário ou produção e, em seguida, use os arquivos CSS / JavaScript originais ou reduzidos, dependendo do ambiente. Isso vai me poupar de trocar os arquivos manualmente.
  • Use o compressor YUI de linha de comando e execute-o a partir de um arquivo de script quando necessário.
  • Use algo como rsync para que apenas copie os arquivos alterados do meu servidor de temporariedade para o servidor de produção, não sobrescrevendo todos os arquivos

Uma empresa em que trabalhei usou a ferramenta de linha de comando Fabric para automatizar as implantações e fazer esse tipo de coisa. No entanto, esta é uma boa opção ou existe uma ferramenta melhor lá fora?

    
por zuallauz 06.09.2012 / 00:31

2 respostas

3

O tecido seria ideal para esse tipo de tarefa. Se você estiver familiarizado com python, você tem muita flexibilidade com o que pode fazer.

O Capistrano é outra opção que pode ser útil, eu usei para implementações do Rails e não tive problemas lá. Permite que você execute facilmente os comandos do shell em hosts remotos.

Outra opção pode ser usar o Ant (python way with fabric é muito melhor imo).

Você está usando o controle de origem como o git? Você pode adicionar algumas dessas tarefas como ganchos de pós-commit ao enviá-lo para sua ramificação "produção".

O rsync seria a opção mais rápida e segura. Certifique-se de excluir quaisquer arquivos que não devam estar em produção (arquivos de backup, arquivos .swp do vim, etc.).

    
por 06.09.2012 / 01:11
1

Bem, acabei usando o Fabric e criei um script que faz exatamente o que eu quero. Em 48 segundos, tudo é copiado para um diretório temporário, todos os arquivos são minificados e o site mostra uma 'página de upload em progresso', tudo é rsync'd para o servidor usando SSH, então é colocado novamente em funcionamento.

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")
    
por 09.09.2012 / 13:56