Symfony2 deployment checklist

Il componente che genera i log della tua applicazione è essenziale per la gestione della piattaforma web. Symfony2 dedica il componente Monolog alla gestione di questa task.

La configurazione di default va bene per lo sviluppo, ma non è abbastanza per la produzione. I cambiamenti da applicare consigliati sono:

  • Invio di errori all'amministratore del sito web tramite email (log di livello "error");
  • Registrazione di tutte le autenticazioni, dato che questi log sono di livello "info" e quindi non vengono registrati di default.

Configura Monolog all'interno del config_prod.yml:

monolog:
    handlers:
        main:
            type:               fingers_crossed
            action_level:       error
            handler:            grouped
        grouped:
            type:               group
            members:            [streamed, swift]
        streamed:
            type:               stream
            path:               "%kernel.logs_dir%/%kernel.environment%.log"
            level:              debug
        swift:
            type:               swift_mailer
            from_email:         FQN@foo.com
            to_email:           webmaster@company.com
            subject:            "OOps"
            level:              debug
        login:
            type:               stream
            path:               "%kernel.logs_dir%/auth.log"
            level:              info
            channels:           security

Questo è tutto!

Di default, Composer fornisce un autoloader che non è completamente ottimizzato. Per questo, quando hai molte classi, l'autoloader potrebbe prendere del tempo...

Nella modalità di produzione desideri che l'autoloader sia veloce. Composer può estrarre un autoloader ottimizzato che converte le librerie basate su PSR-0 in mappe di classi, che ne migliora le prestazioni.

Per utilizzare l'autoloader ottimizzato, aggiungi semplicemente l'opzione --optimize al comando dump-autoload di Composer:

php composer.phar dump-autoload --optimize

Ovviamente, questa opzione rende il tempo di esecuzione del comando un po' più lunga. Per questo non viene eseguito di default.

Prima di effettuare il deploy della tua applicazione, devi testare che il tuo server di produzione sia pronto per eseguirla.

Per testare il tuo server puoi scegliere tra tre metodi:

  1. Eseguire manualmente php app/check.php e vedere cosa restituisce;
  2. Accedere a config.php, posizionato all'interno della directory web, con il browser;
  3. Se ancora non hai gli accessi al server (o se stati pianificando di comprarlo), puoi ancora andare alla pagina della documentazione sui requisiti

Il componente Form di Symfony2 include e convalida automaticamente i token CSRF per te.

Assicurati di personalizzare la tua chiave segreta, che viene utilizzata per la generazione dei token, nel fileapp/config/parameters.yml:

secret:  please_use_a_real_secret_here

Inoltre, potresti personalizzare il token in base al form, che è ancora meglio. Puoi farlo definendo un'opzione intention nei tuoi form:

namespace Acme\DemoBundle\Form;

use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class TaskType extends AbstractType
{
    // ...

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            // a unique key to help generate the secret token
            'intention'  => 'task_form',
        ));
    }

    // ...
}

Non si vuole mostrare il logo di Symfony nel browser dei visitatori, per questo, prima di effettuare il deploy, dovresti sostituire la favicon di default con la tua.

Sostituisci il file web/favicon.ico.

Per creare delle favicon puoi:

  • Utilizzare dei servizi online come favicon.cc per generare dei file .ico;
  • Utilizzare un'icona PNG. In quel caso bisogna definire un link all'interno dell'HTML: <link rel="icon" type="image/png" href="yourFavIcon.png">

In modalità produzione, si consiglia di utilizzare la cache di Doctrine. Ci sono due tipi di cache.

Cache per query e metadati

  • La cache per le query aiuta a mettere in cache la trasformazione di una query DQL nella corrispondente query SQL. In produzione, le tue richieste non cambieranno quindi perché non metterle in cache?
  • La cache per i metadati aiuta a mettere in cache i metadati estratti da diverse sorgenti quali YAML, XML, Annotazioni, etc...

Il posizionamento in cache queste informazioni viene fatto impostando alcuni parametri nel file di configurazione della modalità di produzione config_prod.yml:

doctrine:
    orm:
        auto_mapping: true
        query_cache_driver:    apc
        metadata_cache_driver: apc

Cache dei risultati

Il risultato delle tue query può essere messo in cache per non inviare continue query al database. Dato che si tratta di un raffinamento, non puoi configurarlo per tutta l'applicazione. Puoi solo impostare il driver come fatto precedentemente:

doctrine:
    orm:
        auto_mapping: true
        result_cache_driver: apc

Ma a questo punto devi esplicitamente utilizzare o non utilizzare questa cache in tutte le grandi query. Questo viene fatto impostando il nome ed il tempo di vita per ogni query in cache. Vedi la documentazione di Doctrine su caching dei risultati.

Assicurati che Doctrine stia utilizzando la cache APC

Hai configurato APC come driver per la cache per Doctrine, questo è grandioso. Ma il problema è che il container della Dependency Injection è generato attraverso l'interfaccia da linea di comando, quando la cache è generata da lì. E se tu non hai apc.enable_cli = 1 nel tuo php.ini, allora il DIC utilizzerà invece il FileCacheReader. E questo non è quello che vogliamo.

Per controllare se stai utilizzando veramente la cache APC, controlla il tuo app/cache/prod/appProdProjectContainer.php. Dovresti vedere:

protected function getDoctrine_Orm_DefaultEntityManagerService()
{
    $a = $this->get('annotation_reader');
    $b = new \Doctrine\Common\Cache\ApcCache();
    $b->setNamespace('sf2orm_default_5cdc3404d84577b226d7772ca9818908');
    $c = new \Doctrine\Common\Cache\ApcCache();
    $c->setNamespace('sf2orm_default_5cdc3404d84577b226d7772ca9818908');

    // ...

    $g = new \Doctrine\ORM\Configuration();
    $g->setMetadataCacheImpl($b);
    $g->setQueryCacheImpl($c);

    // ...
}

Se non riesci a trovare \Doctrine\Common\Cache\ApcCache, allora non stai utilizzando APC.

Assicurati che sul server di produzione si stia utilizzando una chiave segreta personalizzata. Controlla che all'interno del file app/config/parameters.yml ci sia:

secret:  please_use_a_real_secret_here

La chiave segreta di default non è veramente segreta, dovresti cambiarla con una casuale.

Mentre tu potresti essere abituato alle pagine d'errore della modalità sviluppo, non è il caso invece di mostrare gli errori ai futuri visitatori una volta in produzione. Quindi dovresti personalizzare le diverse pagine d'errore, per integrarle nel tuo layout.

Per fortuna, la personalizzazione delle pagine d'errore è veramente semplice. Le viste sono posizionate nel bundle TwigBundle, che ti fornisce la chiave per sovrascrivere con le tue. Le viste che devi creare sono: Exception/errorXXX.html.twig, dove XXX è il numero dell'errore. Si consiglia i personalizzare almeno gli errori 404 e 500.

Per utilizzare le tue viste, ci sono due possibili soluzioni:

  1. Puoi creare un nuovo bundle, che estende TwigBundle, e posizione le tue viste nella directory Resources/views/Exception/errorXXX.html.twig. Questo ti consente di riutilizzarle in diversi progetti come un bundle riutilizzabile;
  2. Puoi semplicemente mettere le tue viste nella directory app/Resources/TwigBundle/views/Exception/errorXXX.html.twig. Se le tue viste sono specifiche per il progetto corrente, questo ti evita di creare un bundle solo per quello.

Symfony2 è un framework flessibile e potente... che sfocia in un tempo di esecuzione lento. Ovviamente, la modalità di produzione è solitamente molto più veloce della modalità di sviluppo, ma non è ancora abbastanza.

Per accelerare la tua applicazione in produzione, si raccomanda di installare un acceleratore PHP come APC.

Su un server dedicato

Su Linux

Per installare APC su una distribuazione debian-like di linux, lanciare semplicemente da terminale il comando:

apt-get install php-apc

Adatta il comando alla tua distribuzione.

Su Windows

Rimuovere il commento dall'inizio della relativa riga nel tuo php.ini:

extension=php_apc.dll

In tutti i casi

Dopo l'installazione, devi attivare l'estensione. Questo viene eseguito aggiungendo questa linea alla fine del tuo php.ini:

[APC]
apc.enabled=1

Su un hosting condiviso

Se sei su un hosting condiviso, non dovresti avere un accesso SSH. In quel caso, la migliore opzione è contattare l'amministratore. Digli che sarebbe meglio per i suoi server avere un acceleratore PHP installato.