Implementación de archivos estáticos en Heroku

Si usa los marcos Ruby on Rails, Django o NodeJS en los mismos dominios, tienen carpetas especiales, generalmente llamadas static , público o activos . Pero, ¿qué sucede si implementa solo un archivo "estático" que, por cierto, generalmente no es tan estático?

Heroku utiliza la pila Cedar como herramienta de creación de aplicaciones y no admite la implementación completa de archivos estáticos como HTML, CSS o JavaScript, a menos que vengan con algún lenguaje del lado del servidor, por ejemplo, PHP, Ruby, Python. Esto puede ser útil si está utilizando aplicaciones front-end creadas con jQuery o BackboneJS framework y servicios como Parse.com o Firebase.com o consume su propio back-end implementado como una aplicación diferente en una instancia y/o dominio diferente.

Hay varias formas de engañar a Heroku y Cedar para que piensen que sus archivos HTML, CSS y JavaScript son PHP o Ruby on Rails, o cualquier otra aplicación legítima de Cedar. Esta es la forma más sencilla de crear index.php archivo en la carpeta de su proyecto, en el mismo nivel que su .git carpeta. Puedes hacer esto en la terminal con este comando:

$ touch index.php

Luego apagamos PHP con .htaccess directiva. Puede agregar una línea a .htaccess y créelo con este comando de terminal:

$ echo 'php_flag engine off' > .htaccess

Este comando de dos terminales creará un index.php vacío archivo y .htaccess archivo que desactiva PHP. Esta solución fue descubierta por Kenneth Reitz.

Otro enfoque es menos elegante pero también implica PHP. Cree el archivo index.php en el mismo nivel que index.html en la carpeta del proyecto que le gustaría publicar/implementar en Heroku con el siguiente contenido:

<?php echo file_get_contents('index.html'); ?>

La tercera forma es usar la pila Ruby y Ruby Bamboo. En este caso, necesitaríamos la siguiente estructura:

 -project folder
    config.ru
   /public
      index.html
      /css
      app.js
      ...

La ruta en index.html a CSS y otros activos debe ser relativa. es decir, 'css/style.css'. El archivo config.ru debe contener el siguiente código:

use Rack::Static, 
  :urls => ["/stylesheets", "/images"],
  :root => "public"

run lambda { |env|
  [
    200, 
    {
      'Content-Type'  => 'text/html', 
      'Cache-Control' => 'public, max-age=86400' 
    },
    File.open('public/index.html', File::RDONLY)
  ]
}

Para obtener más detalles, puede consultar la documentación oficial de Bamboo Heroku.

Por último, pero no menos importante, para los desarrolladores de Python y Django, puede agregar lo siguiente a su urls.py :

urlpatterns += patterns(”, (r’^static/(?P.*)$’, ‘django.views.static.serve’, {‘document_root’: settings.STATIC_ROOT}),)

O con esta línea Procfile:

web: python my_django_app/manage.py collectstatic --noinput; bin/gunicorn_django --workers=4 --bind=0.0.0.0:$PORT my_django_app/settings.py 

La publicación completa de Django está en Administrar archivos estáticos de Django en Heroku.

Si usa NodeJS, aquí le mostramos cómo escribir su propio servidor:

var http = require("http"),
url = require("url"),
path = require("path"),
fs = require("fs")
port = process.argv[2] || 8888;

http.createServer(function(request, response) {

  var uri = url.parse(request.url).pathname
    , filename = path.join(process.cwd(), uri);

  path.exists(filename, function(exists) {
    if(!exists) {
      response.writeHead(404, {"Content-Type": "text/plain"});
      response.write("404 Not Found\n");
      response.end();
      return;
    }

    if (fs.statSync(filename).isDirectory()) filename += '/index.html';

    fs.readFile(filename, "binary", function(err, file) {
      if(err) {        
        response.writeHead(500, {"Content-Type": "text/plain"});
        response.write(err + "\n");
        response.end();
        return;
      }

      response.writeHead(200);
      response.write(file, "binary");
      response.end();
    });
  });
}).listen(parseInt(port, 10));

console.log("Static file server running at\n  => http://localhost:" + port + "/\nCTRL + C to shutdown");