Brian Wigginton Lab and Nerdery

Share localhost with SSH & Apache

Posted on October 23, 2012

There's been a lot of services released lately that aim to assist developers share their local development environments over the internet. localtunnel, showoff.io and pagekite come to mind, just to name a few. However, you can roll your own forwarding service if you have SSH access to a server running Apache fairly easily.

The Big Picture

First, setup a webserver to listen for connections to demo.example.com. When a user connects to the webserver, it will attempt to proxy their request to port 1337 (demo.example.com port 1337).

Second, a reverse proxy initiated with SSH on your localhost creates a connection to demo.example.com, and then has all traffic on demo.example.com port 1337 forwarded to localhost port 80.

User => demo.example.com:80 <=> demo.example.com:1337 <=> localhost:80

Requirements

Server

  • Apache Web Server
  • Apache mod_proxy module
  • OpenSSH

Client

  • Local web application
  • SSH client
  • SSH public/private keys to login to the remote server

Server Setup (Ubuntu)

You should be able to login to your server over SSH using public/private key authentication. How to do that is out of scope for this post, however there are plenty of guides available online that explain in detail how to do this.

Apache: Enable mod_proxy

$ sudo a2enmod proxy_http

Apache: Configure VirtualHost

Setup Apache to use a VirtualHost for URL you want to use for sharing your work:

<VirtualHost *:80>
ServerName "demo.example.com"
ProxyPass / http://127.0.0.1:1337/
ProxyPassReverse / http://127.0.0.1:1337/
</VirtualHost>

The ServerName Directive tells Apache to listen for client requests for demo.example.com. ProxyPass and ProxyPassReverse configure Apache to forward all requests to the local port 1337.

Apache: Restart to load VHost

$ sudo apachectl restart

Localhost Setup

Make sure you're running a local web application

This should be pretty obvious :) It doesn't matter what port it's running, you can configure that when you start the SSH reverse proxy.

Create an SSH Reverse Proxy

To actually enable the connection form your public web server to your localhost, you have to create a reverse proxy using SSH. The reverse proxy will create a connection from your localhost to the remote server (demo.example.com), then have all traffic from a designated remote port forwarded to a local port.

$ ssh -fNR 1337:localhost:80 demo.example.com

  • -f puts ssh into the background. If you want to be able to easily kill the Proxy later, omit the -f and use ctrl + c.
  • -N disables all output keeping things clean. If you omit this, you'll see SSH connect to your remote server.
  • -R 1337:localhost:80 Tells SSH to create a reverse proxy and that all traffic on the remote port 1337 should be forwarded to localhost's port 80.
  • demo.example.com is the remote server you want SSH to connect to.

You may need to change your localhost port depending on what port your local environment is running on. For example: if you're developing a rails application using the builtin webserver, you might need to use port 3000 instead of port 80.

You should now be able to hit demo.example.com in your browser, and see your application load.

Filed under: Apache, DevOps, Linux, SSH, Tips No Comments

npm jshint – command not found after install

Posted on October 20, 2012

I was getting a new machine up and running and decided to play with zsh. Later that evening I was going to write some JavaScript and wanted to lint my code with the handy jshint tool. So I installed it with NPM:

$ npm install jshint -g

And was then greeted with a command not found error:

$ jshint
zsh: correct jslint to slit [nyae]? n
zsh: command not found: jslint

Turns out I needed to add the npm bin directory to my PATH, as it didn't get added there automatically since I installed zsh after node/npm.

export PATH="/usr/local/share/npm/bin:${PATH}"
Filed under: Javascript No Comments

Jenkins & JSHint – Integrating with Checkstyles and Violations

Posted on October 4, 2012

Prerequisite

You need to have some form of jshint installed on your server. Instructions of how to do that are out of scope for this post, and should be able to be easily found on the internet. I used the version that installed with npm.

Jenkins Build Tasks

This is a very simple setup that uses 2 Build > Execute Shell tasks. In the first shell task I created the checkstyle output:

jshint --checkstyle-reporter app/webroot/javascripts/mdc/ > build/logs/checkstyle-jshint.xml || exit 0

In the second, I created the jslint output:

jshint --jslint-reporter app/webroot/javascripts/mdc/ > build/logs/jslint.xml || exit 0

Build Task Settings

Checkstyle Plugin

Configure the checkstyles plugin to reference the created checkstyle-jshint.xml file:

Checkstyle Settings

Violations Plugin

Configure the violations plugin to reference the created checkstyle-jshint.xml and the jslint.xml file:

Violations Setup

SVN Remove & Ignore Causing Tree Conflict

Posted on September 10, 2012

We has some files that were being tracked in SVN that we needed to be untracked and ignored, specifically a web.config file, which was being dynamically generated. We removed and ignored the file in a feature branch. We then merged the feature branch into trunk. Then ran svn update on our servers, which caused a tree conflict.

After some googling, the resolution was the following command on the server:

svn resolve --accept working -R .

Thanks to http://www.learnaholic.me/2009/10/04/subversion-resolve-for-tree-conflict/ for the answer.

Filed under: Subversion No Comments

Filename Cache Busting with CakePHP

Posted on July 18, 2012

This assumes you're using CakePHP 2.x

CakePHP let's you use timestamp based cache busting on your assets by enabling Asset.timestamp in your core.php file. By enabling this and using the builtin HtmlHelper::css and HtmlHelper::script methods, your assets will have a timestamp appended to them as a query string. For example:

/app.js?123456789

However, older squid proxies will not cache anything that has a query string, thus preventing your files from being cached. An alternative solution is to move the timestamp into the filename, and then use htaccess or similiar rewrite rule system to map those files back to the actual files on disk. The end output would be something like the following:

/app.123456789.js

To implement this in CakePHP, you need to override the assetTimestamp in AppHelper.php

Use the following in your .htaccess file. If you're not using Apache, see the html5 boilerplate for nginx or web.config files.

Read more about filename cache busting at the Html5 Boilerplate Wiki entry on cache busting.

Filed under: CakePHP, PHP 1 Comment
Google+