Desplegando aplicaciones Symfony en Heroku
4 Nov 2015
Alfonso Fernández
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1907747/innolid.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1907751/cyliconvalley.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1907754/PCUVa.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1907762/phpvalladolid.png)
Gracias ;)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1907695/selfie.jpg)
@alfonsofega
About
Alfonso Fernández
Responsable de I+D+i & Desarrollador & cofundador en Cloudman Labs
alfonso.fernandez@cloudmanlabs.com
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1907796/logotipo_sin_nube_medusa_.png)
Desarrollo de software en nube
Parte 2
Desplegando una aplicación Symfony en Heroku
$ git push heroku master
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1907825/tach_n.jpg)
Un poco de teoría...
¿Qué es una aplicacion para Heroku?
Código fuente
Dependencias
Procfile
Variables de entorno
Add-ons
Gestores de dependencias...
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1903782/java.png)
pom.xml
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1903785/nodejs.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1903787/php.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1903788/python.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1903790/ruby.png)
Gemfile
package.json
composer.json
requirements.txt
Procfile
Declara los procesos de nuestra aplicación
Fichero que se crea en la raíz de nuestro proyecto
Tipos de procesos
web
Es un tipo especial
<process type>: <command>
otros tipos
Podemos llamarlos como queramos, pero es común usar worker (para realizar tareas) y clock (para scheduled task) como nombre.
Lo mejor de todo es que los procesos se escalan independientemente
Escalabilidad de procesos
$ heroku ps:scale worker=1
$ heroku ps:resize worker=standard-2x
Escalar dyno del proceso
Escalar proceso
Variables de entorno
Heroku provee un mecanismo de configuración de variables de entorno.
Principal diferencia entre entornos
(dev, staging, prod)
$ heroku config:set NAME=VALUE
Add-ons
Son los servicios que usa la aplicación
Base de datos (MySQL)
Cola de mensajes (RabbitMQ)
Cache (Redis)
...
No estamos limitados a los add-ons
Podemos usar cualquier servicio de terceros como Amazon S3 o Amazon Cloudfront
¡Ya sabemos que es una aplicación para Heroku!
Desplegando en Heroku
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1887803/git.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1908298/reverencia.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1908300/reverencia_inversa.png)
$ git push heroku master
pero hay mas...
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1903873/github-logo.jpg)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1903881/Deploy-to-heroku-logo.png)
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1908315/dropbox.png)
pero...
¿qué hace Heroku para que sea tan fácil desplegar?
¿Es magia?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1908667/magia.png)
Cuando sube el código fuente, heroku detecta el "package manager", lanza un build pack especifico para el lenguaje, obtiene las dependencias, crea los archivos necesarios y ejecuta los procesos definidos en el archivo Procfile
es prestidigitación
¡No!
Mucha teoría pero todavía no hemos visto ninguna aplicación...
¡Vamos a desplegar una aplicación Symfony en Heroku!
Aplicación de ejemplo
Fork de "Cupon"
Es la aplicación que se desarrolla en el libro
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1908395/portada-libro-symfony2.png)
¿Que necesitamos?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1887803/git.png)
Una cuenta en Heroku: https://signup.heroku.com/
Heroku toolbet: https://toolbelt.heroku.com/
$ heroku login
Enter your Heroku credentials.
Email: example@example.com
Password: *******
...
Vamos a desplegar la aplicación de ejemplo
$ git clone https://github.com/afgar/Cupon.git
$ cd Cupon
$ heroku apps:create
$ git push heroku master
$ heroku open
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1909715/captura.png)
$ heroku apps:create
¿Que ha ocurrido?
Crea una aplicación Heroku en la region de USA, le establece un nombre aleatorio y añade el git remote heroku
$ heroku apps:create <nombre app> --remote <nombre git remote> --region <region eu|us>
# Ejemplo para crear una app en produccion en Europa
$ heroku apps:create myapp --remote prod --region eu
# Ejemplo para crear una app staging en Europa
$ heroku apps:create myapp-staging --remote staging --region eu
Tip
# Si quieremos hacer deploy de otra rama
$ git push heroku <branch>:master
Tip
¿Qué le has hecho a la aplicación?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1909811/what_are_you_done.png)
Crear el archivo Procfile
Realmente no es necesario, symfony 2.7 tiene un comando que detecta heroku y autogenera el Profile cuando se esta desplegando la aplicación
# Con apache
web: bin/heroku-php-apache2 web/
# Con nginx
web: bin/heroku-php-nginx -C nginx_app.conf web/
{
# ...
"scripts": {
"post-install-cmd": [
# ...
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget",
# ...
],
"post-update-cmd": [
# ...
"Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::prepareDeploymentTarget",
# ...
]
},
# ...
}
Archivo composer.json
/**
* Sets up deployment target specific features.
* Could be custom web server configs, boot command files etc.
*
* @param $event CommandEvent An instance
*/
public static function prepareDeploymentTarget(CommandEvent $event)
{
static::prepareDeploymentTargetHeroku($event);
}
protected static function prepareDeploymentTargetHeroku(CommandEvent $event)
{
$options = static::getOptions($event);
if (($stack = getenv('STACK')) && ($stack == 'cedar' || $stack == 'cedar-14')) {
$fs = new Filesystem();
if (!$fs->exists('Procfile')) {
$event->getIO()->write('Heroku deploy detected; creating default Procfile for "web" dyno');
$fs->dumpFile(
'Procfile',
sprintf('web: $(composer config bin-dir)/heroku-php-apache2 %s/',
$options['symfony-web-dir'])
);
}
}
}
Sensio\Bundle\DistributionBundle\Composer\ScriptHandler
Cambiar el destino de los log a stderr en producción
# app/config/config_prod.yml
monolog:
# ...
handlers:
# ...
nested:
# ...
path: "php://stderr" # antes "%kernel.logs_dir%/%kernel.environment%.log"
No queremos que nuestros log vayan a un fichero ya que el almacenamiento de las dynos es efímero y no se comparte.
Establecer como dependencia las extensiones PHP necesarias
"require": {
# ...
"ext-intl" : "*",
"ext-mbstring" : "*",
"ext-apcu" : "*", # Para cache de doctrine
# ...
},
Lista completa de extensiones que soporta Heroku
https://devcenter.heroku.com/articles/php-support#extensions
composer.json
$ heroku config:set SYMFONY_ENV=prod
Establecer la variable de entorno SYMFONY_ENV
Si no declaramos explicitamente en entorno en Symfony se ejecuta dev, lo que puede causar problemas. Para ello definimos la variable de entorno SYMFONY_ENV
¡No olvidemos el parámetro secret!
$ heroku config:set SECRET=c3fe8824310c1467432e0636c33b94354c1c91ac
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1909777/no_olvides.png)
Pasos built adiccionales
# composer.json
{
"scripts": {
"compile": [
"rm web/app_dev.php", # Elimina app_dev.php
"php app/console assetic:dump" # Ejecuta assetic:dump
]
}
}
Si queremos ejecutar pasos de compilaccion adiccionales durante la contruccion del programa no debemos utilizar post-install-cmd para ello tenemos el comando compile personalizado que ejecutará heroku
Configuraciones de la aplicación
{
"extra": {
"incenteev-parameters": {
"file": "app/config/parameters.yml",
"env-map": {
"database_url": "CLEARDB_DATABASE_URL",
"secret": "SECRET"
}
}
}
}
Deberemos mapear las variables de entorno a nuestras variables que necesitemos del archivo parameters.yml
Addons utilizados
Papertrail
$ heroku addons:create papertrail:choklad
Gestiona logs del sistema, dado que logplex solo emite un stream de logs.
Para mi es la mas simple
Nos permite:
- Ver los últimos mensajes
- Buscar en el log y guardar búsquedas
- Enviar alertas
- Automáticamente crea archivos de log comprimidos que son descargables o los envia a amazon S3.
ClearDB MySQL
$ heroku addons:create cleardb:ignite
- El servicio de MySQL más económico
- Es gratis hasta 5MB
- Backup diario automatico
Heroku Scheduler
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1909859/heroku_scheduler.png)
Sustituye al cron
Es escalable
"best effort"
$ heroku addons:create scheduler:standard
Mantenimiento y gestión de la aplicación
Logs del sistema
$ heroku logs --tail
¡Ya esta asi de simple! En nuestra console empezamos a ver los logs en streaming
Quiero ejecutar comandos de Symfony
¿Cómo lo hago?
Para eso tenemos las one-off dynos!!
$ heroku run "php app/console doctrine:schema:create"
$ heroku run "php app/console doctrine:fixtures:load"
$ heroku run "php app/check.php"
$ heroku run bash
Rollback!
$ heroku releases
$ heroku rollback vXX
pero...
...queda trabajo pendiente
- Utilizar un servicio para enviar emails: mandrill, sendgrid, etc...
- Utilizar Amazon S3 como sistema de ficheros
TODO LIST
Conclusiones
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1904037/despedida.gif)
¿Preguntas?
![](https://s3.amazonaws.com/media-p.slid.es/uploads/397969/images/1909461/hands.png)
Desplegando aplicaciones Symfony en Heroku
By Alfonso Fernández
Desplegando aplicaciones Symfony en Heroku
Parte 2. ¿Cómo desplegar una aplicación Symfony en Heroku?
- 5,259