Dynamically uploading files to Rails with jQuery File Upload

Say we want …

  • to create a Gallery that has a name and has_many :images, which in turn have a caption
  • to offer the user a single form to create a gallery with any number of images
  • immediate uploads with a progress bar per image
  • a snappy UI

Enter jQuery File Upload. It's a mature library that can do the job frontend-wise. On the server, we'll use Carrierwave, because it's capable of caching images.

(FYI, [here's how to do the u...

Show details of TLS/SSL connections of remote hosts

sslscan is a nice tool to show details about TLS/SSL connections:

~> sslscan some-host-at.makandra.de

Testing SSL server some-host-at.makandra.de on port 443

  Supported Server Cipher(s):
    Failed    SSLv3  256 bits  ECDHE-RSA-AES256-GCM-SHA384
    Failed    SSLv3  256 bits  ECDHE-ECDSA-AES256-GCM-SHA384
    Failed    SSLv3  256 bits  ECDHE-RSA-AES256-SHA384
    Failed    SSLv3  256 bits  ECDHE-ECDSA-AES256-SHA384
    Rejected  SSLv3  256 bits  ECDHE-RSA-AES256-SHA
...

  Prefered Server Cipher(s):
    TLSv1  128 bits  ECDHE-RSA-A...

jQuery promises: done() and then() are not the same

jQuery's deferred objects behave somewhat like standard promises, but not really.

One of many subtle differences is that there are two ways to chain callbacks to an async functions.

The first one is done, which only exists in jQuery:

$.ajax('/foo').done(function(html) {
  console.debug("The server responded with %s", html);
});

There is also then, which all promise libraries have:

$.ajax('/foo').then(function(html) {
  console.debug("The server resp...

vagrant < 2.2.9: handle conflicting host only adapter

I sometimes had the issue that I received an error when starting an existing vagrant box with vagrant up:

A host only network interface you're attempting to configure via DHCP
already has a conflicting host only adapter with DHCP enabled. The
DHCP on this adapter is incompatible with the DHCP settings. Two
host only network interfaces are not allowed to overlap, and each
host only network interface can have only one DHCP server. Please
reconfigure your host only network or remove the virtual machine
using the other host only networ...

Linux Performance Analysis in 60,000 Milliseconds

You login to a Linux server with a performance issue: what do you check in the first minute?

uptime
dmesg | tail
vmstat 1
mpstat -P ALL 1
pidstat 1
iostat -xz 1
free -m
sar -n DEV 1
sar -n TCP,ETCP 1
top

Also see:

Customize your Bash prompt

The shell variable PS1 holds your bash prompt. You might want to change it to serve your needs best. Here is how to:

General

  • non-printing escape sequences in your prompt have to be inclosed in \[\e[ and \] so your shell can correctly count its prompt's length
  • we recommend to highlight your prompt on production machines
  • you can also [show different root prompts for each user](https://makandracards.com/makandra/9569-get-the-username-w...

Using Solr with Sunspot

This describes all the steps you'll need to get Solr up and running for your project using the Sunspot gem.

Prepare Sunspot on your development machine

What you want in your Gemfile:

gem 'sunspot_rails'
gem 'sunspot_solr'
gem 'progress_bar' # for sunspot:solr:reindex

Now define what should be indexed within Solr from your ActiveRecord models, e.g.,

class Article << ActiveRecord::Base

  searchable do
    text :title
 ...

Exploring the disk usage with ncdu

Ncdu is a disk usage analyzer with an ncurses interface. It is designed to find space hogs on a remote server where you don’t have an entire graphical setup available, but it is a useful tool even on regular desktop systems. Ncdu aims to be fast, simple and easy to use, and should be able to run in any minimal POSIX-like environment with ncurses installed.

Image

Alternatives

Geordi 1.3 released

Changes:

  • Geordi is now (partially) tested with Cucumber. Yay!
  • geordi cucumber supports a new @solo tag. Scenarios tagged with @solo will be excluded from parallel runs, and run sequentially in a second run
  • Support for Capistrano 2 AND 3 (will deploy without :migrations on Capistrano 3)
  • Now requires a .firefox-version file to set up a test firefox. By default now uses the system Firefox/a test Chrome/whatever and doesn't print warnings any more.
  • geordi deploy --no-migrations (aliased -M): Deploy with `cap ...

Terminator: do not broadcast to other windows

Terminator has a cool feature that allows you to split your terminal into many panels and type in all of them at the same time. It's called broadcasting and can be enabled by pressing Alt+a (and disabled by Alt+o).

However, in some circumstances it will also be broadcasted to other running instances of Terminator. This probably is not what you want and could be very dangerous (e.g. if you're logged in to a production server in a terminal that is on another workspace).

To prevent the broadcast from affecting other windows, go to `Prefer...

Geocoding Strategies - Google Maps API

The attached article outlines considerations when choosing client-side vs. server-side implementations of the Google Geocoding APIs (geocoder, directions, not maps drawing). The main points are:

  • On the server side you only get a fixed daily request quota
  • On the client side the quota is per-client, so basically unlimited
  • When implementing APIs on the server-side, be aware that quota is measured by IP. When hosting in the cloud **you don't always know which other services might...

How to fix "Too many authentic authentication failures" with SSH and/or Capistrano

You are getting when connecting via SSH or deploying with Capistrano (which uses SSH):

Too many authentication failures for username

This is caused by having too many SSH keys added to your keyring or ssh-agent. Your ssh-agent will throw all keys against a server until one matches. Most servers will deny access after 5 attempts.

This issue might come and go as the order of the active SSH keys in your ssh-agent changes.

Quick fix

Have less keys. Up to 5 keys are fine when the SSHD you're connecting to is using the default ...

Geordi 1.5.1 released

  • Improve geordi cucumber: Only attempt @solo run when the specified files contain the @solo tag, skip @solo run if any filename is passed with a line number (e.g. features/example.feature:3)
  • Improve geordi deploy: Find stages by their prefix (e.g. s -> staging, m -> makandra), bundle if needed, check the selected stage exists
  • Improve geordi server: Takes port as argument (e.g. geordi ser 3001), option --public (-P) starts the server with -b 0.0.0.0 to make it accessible from other machines in the local network, e.g. ...

When the iPad won't play an MP4 video

I had trouble serving an MP4 video to my iPad. Although the video complied with all the specs (H.264 codec, up to 1080p, 30 FPS) I always got this error:

This video could not be loaded, either because the server or network failed or because the format is not supported: http://10.40.0.177:3000/video.mp4

After spending a lot of time fighting this issue, I tried to upload the same unchanged video file to a production server (Apache / Passenger). It worked immediately. I guess iOS is picky about some HTTP header that my local HTTP server (Th...

Howto: Require a gem that is not in Gemfile

In case you want to require a gem, that is not in the Gemfile of you bundle and therefore not in your loadpath, you need to add the path manually and require the gem afterwards.

Expected error

Requiring a gem, that is not in the Gemfile or .gemspec, will cause an LoadError exception:

require 'example_gem' => LoadError: cannot load such file -- example_gem

Adding a gem to the loadpath temporary

  1. You need to install the gem

gem install 'example_gem'

  1. Then you need to require the path where the gem was install...

Freeze (vendor, unpack) a single Ruby gem with and without Bundler

When you need to patch an existing gem, one way is to "vendor" the gem by copying it into the vendor/gems directory of your Rails project. You can then make any changes you require and Rails will use the vendored version of the gem after a server restart. Unfortunately you need to perform some additional steps to marry Rails and the copied gem. This notes describes what to do.

With Bundler

This is super-painful. If you just copy the gem to vendor/gems, Rails will complain:

Unpacked gem foolib in vendor/gems has no s...

Testing HTTPS with badssl.com

Website that offers lots of different kinds of HTTPS configurations, bad or good or complicated.

They also offer a dashboard to check if your browser's HTTPS handling works as expected (which might be compromised e.g. due to security products or enterprise proxy servers).

Getting started with Puppet

When you simply want to get to know Puppet, follow puppetlabs’ Learning Puppet Docs. They give you a handy introduction inside a virtual machine they provide. You can watch the talk by Garrett Honeycutt 'Expanded Introduction to Puppet'.

Do not miss their cheatsheat and their [learn-puppet virtual machine](http://info.puppetl...

no passenger served applications running error when deploying via capistrano

When deploying with capistrano it's possible you get this "error" message:

*** [err :: example.com] There are no Phusion Passenger-served applications running whose paths begin with '/var/www/example.com'.
*** [err :: example.com] 

This is just because there were no running passenger process for this application on the server which could be restarted. It's not a real error. The application process will start if the first request for this app hits the appserver.

The output appears as err because it's printed to stderr.

Dep...

Unpoly 2: Don't try to download files through AJAX requests

Rails has the handy controller method send_file which lets us download files easily. We can decide whether the file should be downloaded (disposition: 'attachment') or shown in the browser (disposition: 'inline'). The default is disposition: 'attachment'.

Downloading files will not work when you are calling the controller action from an AJAX request. The browser will try to render the file and insert it in the DOM, which is never what you want.

Unpoly 2

Unpoly (sin...

Middleman: Use pretty URLs without doubling requests

By default Middleman generates files with a .html extension. Because of this all your URLs end in /foo.html instead of /foo, which looks a bit old school.

To get prettier URLs, Middleman lets you activate :directory_indexes in config.rb. This makes a directory for each of your pages and puts a single file index.html into it, e.g. /foo/index.html. This lets you access pages with http://domain/foo.

Don't double your requests!

Unfortunately you are now forcing every br...

SSL: Build a Certificate signing request (CSR)

In order to request a SSL certificate from any dealer, you usually need a CSR certificate. As both the CSR as well as key are created in this step, make sure you save this certificate on a trusted, secure machine only. Usually this is your production environment.

Run this on the server (not on your machine) as root.\
Replace your-domain.tld with the domain you request the certificate for and YYYY with the current year so you will not have any conflicts when requesting a certificate next year.

openssl req -new -sha256 -out www.your-dom...

Test downstream bandwidth of Internet connection

You want to test your 1GE or 10GE internet uplink? We needed to ensure we have full 10GE to the backbone for a customer project.

Using netcat

To test whether we can achieve the bandwidth internally, you can use netcat and dd like this:

On your first server: nc -v -l 55333 > /dev/null
On your second server: dd if=/dev/zero bs=1024K count=5000 | nc -v $remote_ip 55333

You should see some output like this:

user@xxx:~ % dd if=/dev/zero bs=1024K count=5000 | nc -v removed 55333
Connection to 91.250.95.249 55333 port [...

MySql lost connection trouble

Directly from the MySql docs:

There are three likely causes for this error message.

Usually it indicates network connectivity trouble and you should check the condition of your network if this error occurs frequently. If the error message includes during query, this is probably the case you are experiencing.

Sometimes the during query form happens when millions of rows are being sent as part of one or more queries. If you know that this is happening, you should try increasing net_read_timeout from its default of 30 seconds to 60 s...