A Portable Web Server on a USB Stick

While doing some recent work on developing a WordPress theme for a friend, I found myself in need of a portable web server; something I could plug into a computer, start up, and continue my development work. Since this was for WordPress I needed PHP and a database. With no sense of whether or not this would be possible. I charged in.

I began by collecting the components.

I chose PostgreSQL simply because it was a 50mb download while MySQL was some 300mb. Also, I’d never used PostgreSQL so, why not? Then I found out WordPress doesn’t support PostgreSQL out of the box, but quickly found PostgreSQL for WordPress.

I avoided installers and took the appropriate ZIP file for my distribution so I could simply unzip it to my thumb drive. I unzipped each in turn into it’s own directory off the root of the thumb drive giving me the following directories:

  • Apache24
  • pgsql
  • php
  • wordpress

Apache

First up, getting Apache up and running. This is pretty straightforward except that I would need to use relative paths instead of absolute paths if this was going to be a truly portable solution. I didn’t find much online in the way of what relative paths in httpd.conf would be relative to, so trial-and-error it was. The answer: it depends. Some of the paths are relative to the directory where httpd.exe lives while others are relative to whatever ServerRoot is set to in httpd.conf. ServerRoot itself is relative to httpd.exe’s location and this is typically set to one directory up from the Apache bin directory.

ServerRoot "../"

Next is setting DocumentRoot. I stayed with the default htdocs directory under ServerRoot and the DocumentRoot directive is relative to ServerRoot. However the Directory directive is relative to httpd.exe. Don’t forget this one.

DocumentRoot "htdocs"
<Directory "../htdocs">

And with those changes in place, Apache started right up!

PHP

PHP probably presented the biggest challenge as I started to get buried under DLL dependencies because PHP’s directory was not in the PATH environment variable. I could append that path on-the-fly using a batch script, but I wanted to avoid that if possible and, with some jumping through hoops, it is possible. First is what I added to the end of my httpd.conf to get PHP loaded.

LoadFile "../php/libpq.dll"
LoadModule php5_module "../php/php5apache2_4.dll"
<IfModule php5_module>
    PHPIniDir "../php"
    AddHandler php5-script .php
    DirectoryIndex index.php index.htm index.html
    Alias /wp "../wordpress"
    <Directory "../../wordpress">
        AllowOverride All
        Require all granted
    </Directory>
</IfModule>

Using Apache’s LoadFile directive helps solve any missing DLL errors from PHP when starting up Apache. I’ve included the one DLL I got a missing DLL error for. Should you encounter others make similar use of the LoadFile directory to fix things up. All the relative paths here are relative to DocumentRoot except for the Directory directive as seen previously.

On the PHP side of things I made a copy of the supplied php.ini-development file and renamed it php.ini. I uncommented extension_dir and the two extensions for PostgreSQL.

extension_dir = "ext"
.
.
.
extension=php_pdo_pgsql.dll
extension=php_pgsql.dll

But then I ran into some problems. PHP wasn’t finding those pgsql DLL files. I used Process Monitor to see exactly what paths were being looked at and found there were all relative to httpd.exe. I modified extension_dir to be relative to httpd.exe, but I was still receiving the same DLL errors. I second check of ProcessMonitor confirmed not only was the right path being accessed, but the file was actually being opened. What gives?!

Out of frustration, I eventually created an “ext” directory in the same directory as httpd.exe and copied the DLLs over into that directory and, for reasons I’m not entirely sure of, Apache started up without a problem and PHP was working. If you have any idea why this is and what I can do to make it so I don’t have to create this ext directory, please let me know. For now all I care about is that it worked.

DLL Hell

The first time I booted up Apache with PHP on my portable server I got an error about a missing DLL, msvcr110.dll. This is part of the Visual C++ Redistributable for Visual Studio 2012 which can only be downloaded as an installable, not a ZIP. To get this missing DLL I installed the runtime and then copied the DLL from my C:\Windows\System32 directory over to my Apache24\bin directory.

That fixed the issue, eventually…

Because if you’re mixing 32 and 64 bits then the location of this DLL after install might be different. If you’re running the 64-bit version of Apache and PHP, then you need the 64-bit DLL which, on a 64-bit Windows system, is located in C:\Windows\System32. If you’re running the 32-bit version of Apache and PHP on a 64-bit system, the 32-bit version of this DLL is in C:\Windows\SysWOW64. On 32-bit system it’s in C:\Windows\System32.

Good luck with that one.

PostgreSQL

I hadn’t worked with PostgreSQL before and had no clue how to create a database let alone start and stop it. I’m still not sure I do, but here’s what I did. First I needed to create a database. I opened up a command prompt and positioned myself inside pgsql directory and ran this command:

bin\initdb.exe --username <username> --pwprompt -A md5 -D data

This creates a data directory where all information and data about your database server will be stored. You could also think of it as initializing a database server instance. <username> will the the username of the superuser for the database. This can be anything you want. I used “postgres”. During the creation process you will be prompted to provide a password for the superuser account. Note: if you do not provide the username PostgreSQL will use the username of the account you’re logged into Windows under.

When the initialization completes you’ll be told exactly how to start the server.

"bin\pg_ctl" -D "data" -l pgsql.log start

This will start PostgreSQL as a background process. To stop it, use the same command, but change “start” to “stop”. With the database up and running, create a user for WordPress. This can also be done from the command line as follows:

bin\createuser.exe -U <superuser> -W -P wordpress

This creates a user called “wordpress”. You will be prompted to enter the password for the account. Don’t forget it.

Next you need to create the database that will store the data for WordPress. Again, from the command line:

bin\createdb.exe -O wordpress -U <superuser> -W wordpress

This creates a database called “wordpress” and assigns the user “wordpress” as the database’s owner.

We’re nearly there. Just one more step to go.

WordPress

With Apache and PostgreSQL running (start up Apache just by running httpd.exe from the Apache bin directory) it’s time to get WordPress running. In the configuration for Apache I gave above I alised my WordPress directory to “/wp” so open up a browser and go to http://localhost/wp. If you haven’t already installed PosgreSQL for WordPress you should see an error message that PHP is missing the MySQL extensions. No problem!

PostgreSQL for WordPress

You’ll find a readme.txt file inside the PG4WP ZIP file which will walk you through the process. Basically take the pg4wp directory that’s in the ZIP file and copy it into the wp-content directory of your WordPress install. Then make a copy of the db.php file located in the pg4wp directory and place it one level up, inside the wp-content folder. Your folder structure will look something like this:

  • wordpress
    • wp-admin
    • wp-content
      • pg4wp
      • plugins
      • themes
      • db.php
      • index.php
    • wp-includes

With that taken care of, go back to your web browser and go to http://localhost/wp. You’ll now be warned about a missing wp-config.php file. You can try the web interface or just make a copy of the wp-config-sample.php file and name it wp-config.php. You’ll need to then edit your newly created wp-config.php file to define the database name (wordpress), the database user (wordpress), and the password. Save the file and reload http://localhost/wp.

If all goes well you’ll finally see the WordPress install page. You will also (most likely) see a PHP warning message at the top about pg_query having failed. Ignore it. Fill out the form and press that install button. With luck you’ll get a success message. You’ll also get yet more PHP warnings. Again, ignore them, it’s okay. Login to your new, minty-fresh, WordPress site.

Starting and Stopping With Ease

At this point everything is up and running and everything is portable! All that’s really left is to find some way to easily start and stop the server with the click of a button. To do that I use a batch script.

@echo off
pgsql\bin\pg_ctl.exe start -D pgsql\data -l pgsql\pgsql.log
cd Apache24\bin
httpd.exe
cd ..\..
pgsql\bin\pg_ctl.exe stop -D pgsql\data

This will open a command prompt window and start PostreSQL first, followed by Apache. The window will remain open while the server is running. When I’m finished bring the command window up and press CTRL-C to tell Apache to shut down. I’m then prompted whether or not I want to terminate the batch job. I say NO which lets the script continue and shut down the PostgreSQL database.

A couple things to note. I found that I needed to be within the Apache24\bin directory before running httpd.exe to get around some missing DLL errors. I also have found that PostgreSQL seems to shut down some times for reasons I don’t know. When this happens I just stop and restart the server and everything is back up and running.

Finale

Congratulations, you have a portable web server. Go forth and develop!

Offset Column Chaos

I’m tired of confusing myself trying to write up a description of the layout. Here it is, make of it whatever you will.

Offset Column Chaos (Download)

The primary design idea was two columns where the widths of the columns had a maximum width, but the background color for each column would extend beyond the content to the edges of the viewport while the content, as a whole, remains centered to the viewport.

I took a few different approaches and eventually landed on using media queries to apply different approaches to the same problem depending on the situation with the viewport (are we at max-width yet, or not?) It works. I perhaps made it more complicated than most people really need it to be, but you can pick out the bits you don’t need to keep things simpler.

The CSS is heavily commented with variables and formulas to help keep everything pixel-perfect. It’s a layout like this one that makes me wish CSS had some kind of built-in support for variables. It’d make creating these kinds of layouts a lot easier.

Work is In Progress

I was asked to create a WordPress theme for a friend’s web site. I’ve since created the layout and theme and intend to release a stripped-down version of this layout sometime soon. In preparation for this I dusted off the blog and even found a new template that is more to my liking.

I also started doing what was never intended to be, but has since become an exhaustive write-up about what this new layout does and how it works. This has been a great exercise because it forced me to revisit certain design choices and I’ve discovered new ways to approach certain issues with the mechanics of the layout. I’ve found new solutions to problems whose original fix I wasn’t quite pleased with and also solved some minor bugs that I was initially willing to ignore.

I think I’m at the point where I started, which is cleaning up the CSS, adding comments, and writing about how it all works.

So I’ve got a new layout to give you soon. It’s not terribly complex, it has just two columns, but how those two columns function is something I think will interest others than just myself.

From the depths comes an update.

I’ve moved my Ruthsarian web site to a new server. The new URL is http://s8.org/ruthsarian/. The migration was essentially five minutes of me doing search and replaces. If something isn’t linking right let me know. The new server is case-sensitive where the old one was not so I’m expecting a few problems to crop up.

The reason for the move is I’m changing jobs and I won’t have that web space available to me once I leave my current employer. On the bright side, my new job will take me back towards web development, meaning I’ll have time and motivation to continue my work here. There might even be some worthwhile content being posted here within the next year.

For now I’ve nothing new to offer. Sorry.

ORA-26704

In my professional life I find myself drifting towards the role of DBA rather than web developer. And to that end I am creating this little blog post about Oracle error ORA-26704.

Recently I was working with a database that was replicating itself, via Oracle Streams, to a second database where the data is then processed to produce report-friendly data that others could report on.

There’s a development version of this setup for, well, development and test purposes. Except the streams components weren’t working quite right.

Oracle Streams has three processes. On the source database you have the capture process picks up the redo logs which store changes to the database. There is also a propagation process which takes these changes picked up by the capture process and ships them out to wherever you tell it. On the destination database you have an apply process which, guess what, applies the changes it receives.

The problem I was encountering was that whenever I tried to start the capture process I’d get this ORA-26704 error. Google was near useless. I couldn’t find anything. Just lists of ORA errors with no explanation as to what they actually mean.

Well I’ve finally solved this one, and it’s quite a simple one. So if you, dear reader, have found your way here from your search engine of choice in search of a solution to your ORA-26704 error, fear not, I am here to share my solution.

The initialization parameter aq_tm_processes is probably set to 0. This is bad. This tells Oracle how many processes it should create for the purpose of monitoring streams. If it’s set to 0, then streams won’t work. Either set this to 1 or set it to nothing and let Oracle tune the value for you.

And then you too will have working streams.

More on Amazon Silk

A small Amazon Silk FAQ is now available on Amazon’s web site. Questions regarding privacy are at the bottom so hopefully you won’t read far enough down to see them.

There you will find Amazon taking the opportunity to tell you how awesome Silk is and then direct you to the Amazon Silk Terms and Conditions if you’re still interested in this silly privacy nonsense. However there is one small, but important piece before we move on to the ToC:

What about handling secure (https) connections?

We will establish a secure connection from the cloud to the site owner on your behalf for page requests of sites using SSL (e.g. https://siteaddress.com).

Amazon Silk will facilitate a direct connection between your device and that site. Any security provided by these particular sites to their users would still exist.

If you use Amazon Silk then Amazon will be able to see everything you do over HTTPS. This is bad. Very, horribly, bad. And should be a red flag for anyone considering purchasing a Kindle Fire. Now about that ToC document.

Straight away they give you the section on privacy and tell you that the Silk ToC includes the Amazon Privacy Notice. They’ve even gone and underlined it for you to make sure you see it. Curiously they don’t actually link to the document. Isn’t that a bit odd? I’ll help you out in a way Amazon.com won’t and point you to the Amazon.com Privacy Notice here.

The basic idea of the Silk ToC is that they keep your information for “generally” no longer than 30 days and that everything you do over the web using Silk Amazon.com sees. Couple that with the privacy notice and Amazon has given themselves the right to look at and analyze everything you do over the web with Silk.

However, there is one piece of news in the ToC:

You can also choose to operate Amazon Silk in basic or “off-cloud” mode. Off-cloud mode allows web pages generally to go directly to your computer rather than pass through our servers. As such, it does not take advantage of Amazon’s cloud computing services to speed-up web content delivery.

So it will be possible to use Silk without putting Amazon between you and the web. It’s unfortunate this option is buried in Amazon’s documentation and I suspect this option will be just as buried in Silk, but it is there. And that’s good, because the Kindle Fire does not support Android Market which makes installing an alternative browser a bit problematic.

If I were in the market for an Android tablet I don’t think Silk would turn me off the Kindle Fire, however I am the type who likes to have as much control over my own hardware as possible and I don’t feel I would have complete control over a Kindle Fire in much the same way I don’t feel I’d have complete control over an iPad. Therefore I would probably look elsewhere.

Amazon Silk

Today Amazon.com launched three new versions of their Kindle e-reader including a color tablet called Kindle Fire. In terms of hardware it’s about what you’d expect to see from something competing with the Barnes & Noble NookColor that’s launched a year later; it’s slightly better, but nothing that stands out as revolutionary.

But included with the Fire is a new web browser called Amazon Silk. And Amazon would like you to know this is a new and different browser from anything you’ve seen before.

So what’s the big deal about Silk? All you web requests go through Amazon’s servers which will handle retrieving all the content for you and optimize it wherever possible (e.g. a 3mb jpeg that’s sized to 300×200 pixels will be resized by Amazon before being sent to you as a 50k jpg). Because Amazon’s servers are sitting on some of the fattest pipes on the interwebs, it’ll be able to pull down and deliver all this content to your Kindle significantly faster and more efficiently than if your browser was doing the work all by itself.

Sounds pretty nice, but I’m a bit of a pessimist.

I wonder if the image resize example given in the above video might have unexpected consequences. For example there may be web applications that purposely load a large image into your browser and allow you to zoom in and out and move around the image. Will Amazon’s services understand that scenario and know to not shrink the image? I can think of a few examples that use image clipping and revealing the full image when hovering over the clipped area using CSS. Will Amazon know that the clipped area is not the only part of the image being displayed? Perhaps only known situations are optimized rather than Amazon using software to guess.

My biggest worry, however, is that all your web browsing is now going through a third-party. If Amazon is making requests on your behalf it will need to preset session cookies to those sites your browsing. What happens when you need to log into a system over SSL? Does Silk make the HTTPS request through Amazon’s? Does that mean all your passwords will be, at some point, on Amazon’s servers? What happens if they’re ever compromised? Does Amazon log and can they track your browsing history? What happens when I try to go to Barnes & Noble to buy something online through Amazon’s servers? Some web sites use session-hijacking prevention by comparing looking at things like your IP address. Amazon’s servers, as they point out in the video, are all over the world. Will my IP address stay the same throughout a session or will it change as requests are routed through different Amazon servers? Some web applications might break because of that.

Amazon must be logging your browsing with Silk. Imagine a scenario where someone posts some illegal material through Amazon Silk. Authorities will track down the IP which will lead them back to Amazon. Amazon must then have some mechanism to identify the user who posted the illegal material otherwise Silk becomes a giant anonymous proxy machine.

I’m very wary of Amazon Silk. I do not think I would never use it unless forced into a situation where no alternative was available. I don’t want some third-party sitting between me and the web sites I interact with, watching and recording everything I do.