Pow config.ru for serving static files outside of the public directory? - rack

How do you setup a config.ru file to have Pow serve html/css/js files outside of the public directory? Let's say I wanted to serve them out of the html folder instead.

You could use TryStatic from rack-contrib:
require 'rack/contrib/try_static'
use Rack::TryStatic,
:root => "html",
:urls => %w[/]
You might want to add if ENV['RACK_ENV'] == 'development' if you only want this during development (e.g. if your web server is configured to serve from html/)
.

Related

How do I make a golem app appear at a specific URL route

We let the golem package automatically create a Dockerfile for us and can run the docker image and see the app at the root directory: http://localhost:3838/?...
But we would like the app to appear in a subdirectory like http://localhost:3838/myApp/v1/?... so that we can set up the necessary proxying for Apache and have this and other apps all available from a single server.
We can manually edit the Dockerfile to copy a shiny-server.conf file with the following information:
# Define a server that listens on port 3838
server {
listen 3838;
# Define a location at the base URL
location /myApp/v1/ {
# Host the directory of Shiny Apps stored in this directory
site_dir /srv/shiny-server;
# Log all Shiny output to files in this directory
log_dir /var/log/shiny-server;
}
}
The above solution feels like a hack and we are hoping there is functionality inside of golem that will allow us to set the subdirectory at which the app will appear.
Unfortunately there is no way to include an nginx configuration inside the Dockerfile programmatically: {golem} tries to help with the creation of the file, but some things still need to be done manually.
Also, note that {golem} doesn't create a Dockerfile with a shiny server in it, it creates a standalone docker image that launches the app, so there is no shiny server running, just an R process. {shiny} being what it is, there is no way to natively run it on a given path, it's always at the root, on a port.
That being said, what you can do is either edit the dockerfile so that it also bundle nginx (or any other load balancer), so that you can serve the app on a path, or serve your application on another port, using the port argument of add_dockerfile(): that might be easier to configure it with you Apache proxy.
Colin

Sinatra - how to match production urls with the app's urls

Consider the following simple Sinatra application:
require 'sinatra'
post '/user/login' do
# login logic...
end
When deploying the application to a production environment, the url /user/login is usually changed to something else, i.e., /nitro/nutcracker/v1/user/login. And of course, the Sinatra app will not serve this url.
To cut the unwanted prefix, I've considered using a filter (i.e., before block), and routes with regex (i.e., get /*/user/login), but surely there are better solutions?
What say you?
You can mount it with rack. On the production server, create a config.ru file, and put this inside:
require_relative 'my_app.rb'
map('/nitro/nutcracker/v1/') { run Sinatra::Application } # Or your class, if it's modular
This will prefix the entire app with /nitro/nutcracker/v1/.
Then you run the server with rackup, or your application server might have a command line argument to pass a rack config file.

Caching external resources with sw-precache

I'm trying to get sw-precache to pre-cache external CDN resources, but the generated service-worker.js doesn't contain the CDN url's in the precacheConfig array.
This is what I have in my gulpfile:
staticFileGlobs: [
'http://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css',
'client/assets/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff,ico}'
]
The files inside my local client/assets folder are added to the precacheConfig array, but the external font-awesome css isn't. Is there a way to achieve this?
sw-precache can only precache and keep up to date local assets, like those that match the client/assets/**/*... pattern you're using. It's not meant to work with remote assets that are accessed via CDN.
You have a couple of approaches:
Use npm (or the package manager or your choice) to download a local copy of the resource (i.e. font-awesome) and then deploy that third party resource alongside your first-party assets. If the third-party code is picked up by a pattern you pass to staticFileGlobs then it can be precached and versioned just like anything else local.
Use runtime caching to handle the resource on the CDN. Since the URL for your specific asset includes a 4.0.3 versioning string, it's safe to assume that the underlying contents will never change, and a cacheFirst strategy is probably safe.
You can modify your sw-precache configuration to look like the following:
{
staticFileGlobs: [
'client/assets/**/*.{js,html,css,png,jpg,gif,svg,eot,ttf,woff,ico}'
],
runtimeCaching: [{
urlPattern: /^https:\/\/netdna\.bootstrapcdn\.com\//,
handler: 'cacheFirst'
}],
// ...any other config options...
}
That configuration is broad enough to pick up anything served off that CDN, cache it, and then serve it cache-first once in subsequent visits.
Please note that your example used an http: protocol for your CDN's URL, and you'll need to use https: to obtain a response that plays nicely with service worker caching.

phalcon include modules in rest

I am trying to include a module in Phalcon Micro Application. Is that possible?
I have a structure like this
common/
components/
...
modules/
system
components
...
controllers
...
rest
components
...
controllers
...
www
controllers
...
www/
index.php -> Loads /Phalcon/Mvc/Application($di);
api/
index.php -> Loads /Phalcon/Mvc/Micro($di);
The www registers the modules from config
I want the api to register the rest module from config and include the controllers and the components of that module. Is that possible?
Thanks,
Gasim
Obviously all is possible !
If you want to keep your structure with application+micro I think the best way is to create 3 configs.
A first config that is common with both of api and www
A second one which is loaded only by your www with its one router
A thirds one which is loaded only by your api with its one microrouter and which redefines the different paths to the rest module.
If you want just to use a multi module application with a single config file, then I can advice you to use the domain recognition in your router thanks to the setHostName() method.
Then in your config file you define an api hostname and a www hostname that you use everytime. You may also put them in global constant for more convenience.
// an api get route
$router->add("/getsomething",...)
->via("GET")
->setHostname(MyApp::HOSTNAME_API);
// an api post route
$router->add("/postsomething",...)
->via("POST")
->setHostname(MyApp::HOSTNAME_API);
// a www route
$router->add("/",...)->setHostname(MyApp::HOSTNAME_WEB);
I am trying to include a module in Phalcon Micro Application. Is that possible?
Yes, no problem!
I want the api to register the rest module from config and include the controllers and the components of that module. Is that possible?
Looking at your description and structure I understand it as you would like to separate the configuration of the www module and api module. This will work fine and you only need to include your api configuration in www/index.php (since that is where you start your application and where all your requests will go). Good luck!

Use multiple public directories in Sinatra

My sinatra application is contained in a gem. This means that the assets (css/js) live in the gem. This application writes on the fly generated images and serves them; currently writing into and serving from the public dir.
I prefer to not write the generated images in the gem dir but to a "cache" dir of some sorts under the web-application implementing this gem.
Gem is installed at /var/www/TE/shared/gems/ruby/1.8/gems/tubemp-0.6.0, so assets are at e.g. /var/www/TE/shared/gems/ruby/1.8/gems/tubemp-0.6.0/lib/public/css/.
Gem is deployed in a simple rack-app at /var/www/TE/current/, so I would prefer to write and serve the thumbnails from /var/www/TE/current/public.
However, the setting for a custom public-dir allows only one dir to be set:
set :public_folder, File.join(Dir.pwd, "public")
Breaks the serving of assets; Dir.pwd being the directory of the Rack app. Public is now the dir under the Rack-app, but that is not where the assets are found: they live under the "public" in the gem.
set :public_folder, File.join(gemdir, "public")
Breaks serving of the generated thumbnails.
I could rewrite the application so it serves either the assets or the thumbnails trough Sinatra, but that seems quite some overhead.
Is that the only way? Or is there a way to give Sinatra two or more public dirs to serve its static items from?
I think there's probably a few options, but here's how I got a little app to serve static files from two places, an extension and the main app's public folder:
Directory layout
root/
app.rb
public/images/foo.jpg
lib/sinatra/
gemapp.rb
gemapp/public/images/bar.jpg
The extension 
# lib/sinatra/gemapp.rb
module Sinatra
module GemApp
def self.registered(app)
app.set :gem_images, File.expand_path( "gemapp/public/images", File.dirname(__FILE__))
app.get "/images/:file" do |file|
send_file File.join( settings.gem_images, file)
end
app.get "/gemapp" do
"running"
end
end
end
register GemApp
end
The main app
require 'sinatra'
require_relative "./lib/sinatra/gemapp.rb"
get "/" do
"home"
end
It served files fine for me.