Come iniziare a distribuire applicazioni PHP da un repository di subversion?

Ho sentito la frase "distribuire applicazioni" che suona molto meglio / più facile / più affidabile del caricamento di singoli file modificati su un server, ma non so da where cominciare.

Ho un'applicazione Zend Framework sotto controllo di versione (in un repository Subversion). Come faccio a "distribuire" la mia applicazione? Cosa devo fare se ho una directory "uploads" che non voglio sovrascrivere?

Ospito la mia applicazione tramite una terza parte, quindi non conosco molto altro che FTP. Se tutto ciò comport l'accesso al mio server, spiegare la procedura.

L'implementazione automatica + l'esecuzione di test su un server di staging è nota come integrazione continua. L'idea è che se controlli qualcosa che rompe i test, verrai immediatamente informato. Per PHP, potresti voler controllare Xinc o phpUnderControl

Generalmente non si desidera distribuire automaticamente in produzione. La cosa normale da fare è scrivere degli script che automatizzano l'attività, ma che è comunque necessario avviare manualmente. Puoi usare framework come Phing o altri strumenti di costruzione per questo (una scelta popolare è Capistrano ), ma puoi anche solo mescolare insieme alcuni script di shell. Personalmente preferisco quest'ultimo.

Gli script stessi potrebbero fare cose diverse, a seconda dell'applicazione e dell'installazione, ma un process tipico potrebbe essere:

  • ssh al server di produzione. Il resto dei comandi viene eseguito sul server di produzione, tramite ssh.
  • eseguire svn export svn://path/to/repository/tags/RELEASE_VERSION /usr/local/application/releases/TIMESTAMP
  • interrompere i servizi (Apache, demoni)
  • eseguire lo unlink /usr/local/application/current && ln -s /usr/local/application/releases/TIMESTAMP /usr/local/application/current
  • eseguire ln -s /usr/local/application/var /usr/local/application/releases/TIMESTAMP/var
  • lanciare /usr/local/application/current/scripts/migrate.php
  • avviare i servizi

(Supponendo che tu abbia la tua applicazione in /usr/local/application/current )

Non consiglierei l'aggiornamento automatico. Solo perché i tuoi test unitari passano non significa che la tua applicazione funzioni al 100%. Cosa succede se qualcuno controlla una nuova funzionalità random senza nuovi test di unità e la funzionalità non funziona? I test delle unità esistenti potrebbero passare, ma la funzionalità potrebbe essere comunque interrotta. I tuoi utenti potrebbero vedere qualcosa che è a metà. Con la distribuzione automatica da un check-in, potreste non notare per alcune ore se qualcosa lo ha reso live che non dovrebbe avere.

Ad each modo, non sarebbe così difficile get un deployment automatico se lo volessi davvero. Avresti bisogno di un hook post-check-in, e in realtà i passaggi sarebbero:

1) Esport dall'ultimo check-in 2) Carica esportzione sul server di produzione 3) Decomprimi / config l'esportzione appena caricata

Ho sempre eseguito gli ultimi passaggi manualmente. In genere è semplice come esportre SVN, zip, caricare, decomprimere, configurare e gli ultimi due passaggi ho appena creato un paio di comandi bash insieme. Poi cambio la directory dell'app root con quella nuova, assicurandomi di conservare quella vecchia come backup, ed è bello andare.

Se sei sicuro della tua capacità di rilevare gli errori prima che diventino automaticamente attivi, allora potresti provare ad automatizzare quella procedura. Comunque mi dà i jibbly-jibblies.

Ecco un eccellente articolo sull'utilizzo di Subversion per l'implementazione di progetti Web: risponde a molte delle tue domande.

http://athleticsnyc.com/blog/entry/on-using-subversion-for-web-projects

Alla mia società di webdev abbiamo recentemente iniziato a utilizzare Webistrano , che è una GUI Web per il famoso strumento Capistrano.

Volevamo uno strumento di distribuzione rapido e di facile utilizzo con un'interface centralizzata, la responsabilità (chi ha implementato la versione), il rollback delle versioni precedenti e preferibilmente gratuito. Capistrano è noto come strumento di implementazione per le applicazioni Ruby on Rails, ma non centralizzato e indirizzato principalmente alle app Rails. Webistrano lo migliora con una GUI, la responsabilità e aggiunge il supporto di base per l'implementazione di PHP (usa il tipo di progetto 'pure file').

Webistrano è a sua volta un'app Ruby on Rails installata su un server di sviluppo o di gestione temporanea. Aggiungi un progetto per ciascuno dei tuoi siti web. Ad each progetto aggiungi fasi, come Prod e Dev.

Ogni fase può avere diversi server su cui eseguire l'implementazione e diverse impostazioni. Scrivi (o modifica) una "ricetta", che è uno script ruby che dice a capistrano cosa fare. Nel nostro caso ho appena usato la ricetta fornita e ho aggiunto un command per creare un link simbolico a una directory di upload condivisa, proprio come hai detto tu.

Quando fai clic su Distribuisci, SSH di Webistrano nei tuoi server remoti, esegui un controllo svn del codice e qualsiasi altra attività richiesta come migrazioni di database, collegamenti simbolici o ripulitura delle versioni precedenti. Tutto questo può essere ottimizzato, dopo tutto, è semplicemente sceneggiato.

Siamo molto soddisfatti, ma mi ci sono voluti alcuni giorni per imparare e impostare, soprattutto perché non conoscevo Ruby e Rails. Tuttavia, lo consiglio vivamente per l'uso in produzione in aziende di piccole e medie size, poiché si è dimostrato molto affidabile, flessibile e ci ha risparmiato molte volte l'investimento iniziale. Non solo accelerando gli schieramenti, ma anche riducendo gli errori / gli incidenti.

Questo genere di cose è ciò che chiamereste "integrazione continua". Atlassian Bamboo (costo), Sun Hudson (gratuito) e Cruise Control (gratuito) sono tutte opzioni popolari (secondo le mie preferenze) e hanno il supporto per gestire l'output di PHPUnit (perché PHPUnit support l'output JUnit).

La distribuzione può essere eseguita con un trigger post-build. Come alcune altre persone su questa discussione, farei molta attenzione prima di eseguire distribuzioni automatizzate al check-in (e al test del passaggio).

controlla fredistrano, è un clone capistrano che funziona alla grande (un po 'di confusione nell'installazione ma dopo tutto funziona alla grande)

http://code.google.com/p/fredistrano/

Per gestire i caricamenti, la soluzione classica è spostare la vera directory fuori dallo spazio web principale, lasciandola solo per una nuova versione da verificare (come faccio nello script qui sotto) e quindi usando Apache in "Alias" di nuovo in inserire come parte del sito Web.

 Alias /uploads /home/user/uploads/ 

Ci sono less scelte per te se non hai così tanto controllo del server.

Ho uno script che uso per distribuire un determinato script ai siti dev / live (entrambi girano sullo stesso server).

 #!/bin/sh REV=2410 REVDIR=$REV.20090602-1027 REPOSITORY=svn+ssh://[email protected]vn.example.com/var/svn/website.com/trunk IMAGES=$REVDIR/php/i STATIC1=$REVDIR/anothersite.co.uk svn export --revision $REV $REPOSITORY $REVDIR mkdir -p $REVDIR/tmp/templates_c chown -R username: $REVDIR chmod -R 777 $REVDIR/tmp $REVDIR/php/cache/ chown -R nobody: $REVDIR/tmp $REVDIR/php/cache/ $IMAGES dos2unix $REVDIR/bin/*sh $REVDIR/bin/*php chmod 755 $REVDIR/bin/*sh $REVDIR/bin/*php # chmod -x all the non-directories in images find $IMAGES -type f -perm -a+x | xargs -r chmod --quiet -x find $STATIC1 -type f -perm -a+x | xargs -r chmod --quiet -x ls -l $IMAGES/* | grep -- "-x" rm dev && ln -s $REVDIR dev 

Inserisco il numero di revisione e la data / ora che viene utilizzata per il nome della directory ritirata. Anche i chmod nel mezzo fanno sì che i permessi sulle immagini siano corretti poiché sono anche collegati simbolicamente al nostro server di immagini dedicato.

L'ultima cosa che succede è un vecchio link simbolico … / website / dev / è ricollegato alla directory appena ritirata. La configuration di Apache ha quindi una radice doc di … / website / dev / htdocs /

C'è anche un matching … / website / live / htdocs / docroot, e ancora, 'live' è un altro link simbolico. Questo è il mio altro script che rimuoverà il collegamento simbolico dal vivo e lo sostituirà con qualsiasi punto di sviluppo.

 #!/bin/sh # remove live, and copy the dir pointed to by dev, to be the live symlink rm live && cp -d dev live 

Sto solo spingendo una nuova versione del sito each pochi dats, quindi potresti non volerlo usare più volte al giorno (la mia cache APC non vorrebbe più di alcune versioni del sito in giro), ma per me , Trovo che questo sia molto privo di problemi per la mia implementazione.

Dopo 3 anni, ho imparato un po 'sulle migliori pratiche di implementazione. Al momento utilizzo uno strumento chiamato Capistrano perché è facile da configurare e utilizzare e gestisce bene molte impostazioni predefinite.

Le basi di un process di distribuzione automatizzato sono le seguenti:

  1. Il tuo codice è pronto per la produzione, quindi è contrassegnato con la versione della versione: v1.0.0
  2. Supponendo che tu abbia già configurato il tuo script di distribuzione, esegui il tuo script, specificando il tag appena creato.
  3. Lo script SSH è indirizzato al tuo server di produzione che ha la seguente struttura di directory:

     /your-application /shared/ /logs /uploads /releases/ /20120917120000 /20120918120000 <-- latest release of your app /app /config /public ...etc /current --> symlink to latest release Your Apache document root should be set to /your-application/current/public 
  4. Lo script crea una nuova directory nella directory releases con il datetime corrente. All'interno di questa directory, il tuo codice viene aggiornato al tag specificato.

  5. Quindi il collegamento simbolico originale viene rimosso e viene creato un nuovo collegamento simbolico, che punta all'ultima versione.

Le cose che devono essere mantenute tra le pubblicazioni vanno nella directory condivisa e i collegamenti simbolici vengono creati in quelle directory condivise.

Dipende dalla tua applicazione e quanto sono solidi i test.

Dove lavoro tutto viene controllato nel repository per la revisione e quindi rilasciato.

L'aggiornamento automatico da un repository non sarebbe intelligente per noi, perché a volte ci limitiamo a fare il check in in modo che altri sviluppatori possano eseguire una versione successiva e unire le modifiche in.

Per fare ciò di cui si parla sarebbe necessaria una sorta di check in e out secondario per consentire la collaborazione tra gli sviluppatori nell'area di check in principale. Anche se non ne so nulla o se è persino ansible.

Ci sono anche problemi con la ramificazione e altre funzionalità simili che dovrebbero essere gestite.