How to install FFmpeg on Ubuntu

I had to dig around to find these simple instructions on how to install FFmpeg on Ubuntu. So I decided to write them down for future reference.

1) First, add Jon Severinsson’s official FFmpeg ppa to your sources. More details here:

sudo add-apt-repository ppa:jon-severinsson/ffmpeg

2) Get the latest list of available software from all the sources (including the newly added ppa):

sudo apt-get update

3) Now go ahead and install:

sudo apt-get install ffmpeg

That’s it. You should be all set!

Fixing PostgreSQL locale issues on Ubuntu/Debian

PGError: ERROR: encoding UTF8 does not match locale en_US
DETAIL: The chosen LC_CTYPE setting requires encoding LATIN1.

You are here probably because you encountered an error like the one above. After a bit of searching I found and tried various different methods from random articles and gists. Although none worked for me as well as what I’m about to document. Which is why I’m blogging about this for future reference.

Although before we proceed, a word of caution - Backup your database. This has NOT been tried in production so use at your own risk!

1) Update the default locale on your system

Note: These commands are specific to Debian/Ubuntu.
Source: https://blog.lnx.cx/2009/08/13/fixing-my-missing-locales/

$ locale-gen en_US.UTF-8
$ update-locale LANG=en_US.UTF-8

2) Now let’s recreatetemplate1</source> based on the new locale

First we’ll need to switch to the database user. Typically that’ll be “postgres”

$ sudo su postgres
$ psql

OR

$ psql -U postgres

Next issue the following set of commands in order:

UPDATE pg_database SET datallowconn = TRUE WHERE datname = 'template0';
\c template0
UPDATE pg_database SET datistemplate = FALSE WHERE datname = 'template1';
DROP DATABASE template1;
CREATE DATABASE template1 ENCODING = 'utf8' TEMPLATE = template0 LC_CTYPE = 'en_US.utf8' LC_COLLATE = 'en_US.utf8';
UPDATE pg_database SET datistemplate = TRUE WHERE datname = 'template1';
\c template1
UPDATE pg_database SET datallowconn = FALSE WHERE datname = 'template0';
\q

If you didn’t see any errors, you should now be all set. You can now go ahead and log out of the postgres user account:

$ exit

URL Validation with KnockoutJS

I recently found myself having to implement URL validation in KnockoutJS. Here’s how I went about doing that:

1) Add Knockout-Validation plugin to your project.

2) Create a custom rule to validate URLs based on the RegEx by Diego Perini found here:

ko.validation.rules['url'] = {
  validator: function(val, required) {
    if (!val) {
      return !required
    }
    val = val.replace(/^\s+|\s+$/, ''); //Strip whitespace
    //Regex by Diego Perini from: http://mathiasbynens.be/demo/url-regex
    return val.match(/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.‌​\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[‌​6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1‌​,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00‌​a1-\uffff0-9]+-?)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]+-?)*[a-z\u‌​00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/i);
  },
  message: 'This field has to be a valid URL'
};
ko.validation.registerExtenders();

3) You are all set. You can now use it either one of these ways:

JS:

jsvar someURL = ko.observable().extend({ url: true });

HTML:

html<input type="text" data-bind="value: someURL.extend({ url: true })" />

Ensuring reliable email delivery with DNS records

If your web app is sending emails, you will need to have these three DNS records configured properly to ensure reliable email delivery and avoid ending up in spam/junk folders:

PTR - It’s a pointer to a canonical name. Unlike a CNAME, DNS processing does NOT proceed but it just resolves an IP address to a fully-qualified domain name (FQDN). So just the name is returned. It’s also known as a Reverse DNS Record.

The most common use is for implementing reverse DNS lookups to check if the server name is actually associated with the IP address from where the connection was initiated. Here’s what it would look like:

SPF - Sender Policy Framework (SPF) is an email validation system designed to prevent email spam by detecting email spoofing, a common vulnerability, by verifying sender IP addresses.

Microsoft has a great 4 step wizard to guide you through creating a SPF record.

If you have a Google Apps domain and you are using a 3rd party email delivery service such as SendGrid, here’s what it would typically look like:

"v=spf1 a mx include:_spf.google.com include:sendgrid.net ~all"

without Google Apps:

"v=spf1 a mx include:sendgrid.net ~all"

DKIM - DomainKeys Identified Mail (DKIM) is a method for associating a domain name with an email message, thereby allowing a person, role, or organization to claim some responsibility for the message. The association is set up by means of a digital signature which can be validated by recipients.

This is usually set by the email delivery service you are using. Checkout their account settings to make sure its turned on.

Here’s some more useful links:

How can I check if my DKIM and SPF records are valid? by Postmark
What are SPF and DKIM and do I need to set them up? by Mandrill
How do I add DNS records for my sending domains? by Mandrill
Email Deliverability Guide by SendGrid

How to setup a dev environment using Vagrant & Puppet (Part II)

This is a continuation of my previous post on how to get up and running with Vagrant.

Now let’s get more specific and see how we can install specific modules.

PostgreSQL

To install PostgreSQL I’ve chosen to use this module on GitHub. Let’s go ahead and add that as a submodule. Run this command from the git root folder:

git submodule add https://github.com/akumria/puppet-postgresql.git puppet/modules/postgresql

Also keep in mind, the destination directory should have the same name as the main module’s class. So in this case, postgresql.

You can now add this module into your default.pp in puppet/manifests folder to start using it:

class { 'postgresql': }

That’s the most basic way to get started. Although to make things easier, we should probably also add any databases or users that we will need. And if you plan to access PostgreSQL from your host machine, you will also need to open up the port and allow incoming traffic from the host.

So taking those things into consideration, here’s what it would end up looking like:

class install_postgres {
  class { 'postgresql': }

  class { 'postgresql::server':
    listen => ['*', ],
    port   => 5432,
    acl   => ['host all all 0.0.0.0/0 md5', ],  
  }

  pg_database { ['some-project_database']:
    ensure   => present,
    encoding => 'UTF8',
    require  => Class['postgresql::server']
  }

  pg_user { 'some-project-user':
    ensure  => present,
    require => Class['postgresql::server'],
    superuser => true,
    password => 'some-password'
  }

  pg_user { 'vagrant':
    ensure    => present,
    superuser => true,
    require   => Class['postgresql::server']
  }

  package { 'libpq-dev':
    ensure => installed
  }

  package { 'postgresql-contrib':
    ensure  => installed,
    require => Class['postgresql::server'],
  }
}
class { 'install_postgres': }

Finally in your Vagrantfile, make sure you are forwarding that port to whichever port you want on your host machine:

config.vm.network :forwarded_port, guest: 5432, host: 5433

Ruby

Now let’s take a look at how to go about installing Ruby. Instead of a package, we’ll just do this manually. First let’s defined a variable called $as_vagrant. It’s a reusable command which will let us basically run other commands as the vagrant user:

$as_vagrant = 'sudo -u vagrant -H bash -l -c'

We also need to make sure, curl is installed:

package { 'curl':
  ensure => installed
}

Now we can install RVM (note the dependency on the curl package):

exec { 'gpg_key':
  command => "${as_vagrant} 'gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3'"
}

exec { 'install_rvm':
  command => "${as_vagrant} 'curl -L https://get.rvm.io | bash -s stable'",
  creates => "${home}/.rvm/bin/rvm",
  require => [Package['curl'], Exec['gpg_key']]
}

Next up, install Ruby 2.0.0 (note the dependency on our previous install_rvm command):

exec { 'install_ruby':
  # We run the rvm executable directly because the shell function assumes an
  # interactive environment, in particular to display messages or ask questions.
  # The rvm executable is more suitable for automated installs.
  #
  # Thanks to @mpapis for this tip.
  command => "${as_vagrant} '${home}/.rvm/bin/rvm install 2.0.0 --latest-binary --autolibs=enabled && rvm --fuzzy alias create default 2.0.0'",
  creates => "${home}/.rvm/bin/ruby",
  require => Exec['install_rvm']
}

Finally, install Bundler:

exec { "${as_vagrant} 'gem install bundler --no-rdoc --no-ri'":
  creates => "${home}/.rvm/bin/bundle",
  require => Exec['install_ruby']
}

Python

For python I’ve chosen to use this module which makes it very easy to install.

Let’s add that as a submodule:

git submodule add https://github.com/stankevich/puppet-python.git puppet/modules/python

Now all you have to do is add this declaration:

class { 'python':
  version => 'system',
  virtualenv => true,
  pip => true,
  dev => true
}

You can checkout more params/arguments on their GitHub page.

If you’d like to learn more about creating and consuming modules, I would also recommend checking out Erika Heidi’s site for in-depth blog posts and talks.

Deploy

Finally you are now ready to fire up your new Vagrant machine. Just run the following commands:

$ vagrant up
$ vagrant provision
$ vagrant ssh

You can now just go to the /vagrant folder where you should see the project folder that you just cloned. This folder is shared with your host so you can open your favorite editor on the host and start hacking away.

Share

New version of Vagrant also includes the ability to Share, Distribute and Discover your Vagrant boxes. I have been sharing my Vagrant machine using ngrok, a utility that I mentioned in my previous post about useful web development tools. With the release of vagrant share, you could skip that and just do:

vagrant share --ssh

That will create a random shareable web URL such as http://hulking-chameleon-3934.vagrantshare.com which would point to your Vagrant instance.

This is very handy for sharing results with co-workers or remote debugging. On the flip side, you can also SSH into other Vagrant machines :

vagrant connect --ssh hulking-chameleon-3934

More details on how this works on their site.

That’s it, I think I’ve covered the basics. Let me know if you’d like to me cover anything else.