imperialWicket

am i the only croquet-playing computer nerd?

AWS: Install Nginx and PHP-FPM on Amazon Linux

2012-05-10

First launch an Amazon Linux EC2 instance, and I'll add the usual caveat that much of this technique works on all Red Hat derivative distributions, though the package names and versions may be unique.

I am going to do this as the root user, and first start with a system update from the default repositories (always a good practice).

sudo su -
yum update

Installing Packages

After security updates and standard patches are applied to the server, install Nginx, PHP-FPM, and the PHP packages that many frameworks and CMS use.

yum install nginx php-fpm php-xml php-pdo php-odbc \
  php-soap php-common php-cli php-mbstring php-bcmath php-ldap \ 
  php-imap php-gd php-pecl-apc 

You likely require only one of the following commands, depending on your preference between MySQL and PostgreSQL. Amazon Linux (at time of writing) is offering MySQL 5.5 and PostgreSQL 9.1. I will reference MySQL as the database server in the remainder of this article.

yum install mysql-server mysql php-mysql 
yum install postgresql-server postgresql php-pgsql

Chkconfig and primary configuration

Use chkconfig so that when your server reboots your web server, php, and mysql start automatically.

chkconfig nginx on
chkconfig mysqld on
chkconfig php-fpm on

After starting the MySQL server, run the "mysql_secure_installation" script. Set the root password, remove anonymous users, limit root to local access, remove test db and access, update privs.

service mysqld start
mysql_secure_installation

Nginx and PHP-FPM configuration for EC2 Micro instance

I set this up predominantly on micro instances, so my config is going to be conservative in terms of memory usage. I will aim to keep the web server around 500MB, which does not leave a lot of memory for the kernel and mysql, but I have reasonable success with this configuration.

We want to throttle PHP-FPM a bit, add some failure handling mechanisms, and configure it to use a socket connection.

vim /etc/php-fpm.conf

A lot of this is directly inspired by articles from if-not-true-then-false. Update the following values in the php-fpm.conf file:

emergency_restart_threshold 10
emergency_restart_interval 1m
process_control_timeout 15s

Amazon Linux ships fpm with a default 'www.conf' php-fpm pool configuration file in the /etc/php-fpm.d/ directory. If you are planning to configure VirtualHost like behavior, it probably makes sense to distribute your different VirtualHosts to unique pools (vhost1.conf, vhost2.conf, etc. - conventionally). This allows you to configure PHP-FPM options particular to each VirtualHost.

We are going to use the default pool for this configuration, so open the www.conf file in your favorite text editor:

vim /etc/php-fpm.d/www.conf

Now we must make the following changes to accommodate socket usage and allow socket access to the nginx user. We also must change the default Unix user/group for the PHP-FPM processes, which defaults to apache on the current Amazon Linux PHP-FPM package:

;listen = 127.0.0.1:9000
listen = /var/run/php-fpm/php-fpm.sock
;listen.owner = nobody
listen.owner = nginx
;listen.group = nobody
listen.group = nginx
;listen.mode = 0666
listen.mode = 0664

user = nginx
group = nginx

Our final updates to the PHP-FPM pool configuration limit memory that we want PHP-FPM to use. This is achieved by limiting the memory per process (php_admin_value[memory_limit]) and by limiting the number of processes PHP-FPM may spawn.

Still in the /etc/php-fpm.d/www.conf file:

pm.max_children = 8
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 6
pm.max_requests = 200

php_admin_value[memory_limit] = 64M

Now for the Nginx configuration. We need to be sure that Nginx can talk to PHP-FPM, and that it knows how to pass php scripts to the server.

The core configuration for Nginx is available in the /etc/nginx/nginx.conf file, and contains sensible defaults in the Amazon Linux repositories. The Nginx VirtualHost configuration files are available in the /etc/nginx/conf.d/ directory, where a default, ssl, and virtual configuration are available with the Nginx installation.

A proper configuration would setup default.conf to perform the appropriate actions, and likely create a unique file (i.e., vhost1.conf) to control each domain. For simplicity, we will edit the existing default.conf file in this configuration.

vim /etc/nginx/conf.d/default.conf

Most of the default configuration is perfectly appropriate, and we simply need to configure the socket connection, and ensure proper handling of *.php files. Add the 'index.php' reference the the root location block, so that the php file is loaded by default. Also add the block for directing *.php files to php-fpm.

Note that this *.php redirect is not suitable for production use, as it directs any url ending in ".php" to PHP-FPM (that is, this allows a user to upload a file like "myRootKit.jpg", then execute its php code by loading: http://yourDomain.com/uploads/myRootKit.jpg.php). This is not a major concern for development usage or testing, but use caution and investigate more complex regex if you are planning to deploy this for production usage.

location / {
    root   /usr/share/nginx/html;
    index  index.php index.html index.htm;
}

location ~ \.php$ {
      fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
      fastcgi_index  index.php;
      fastcgi_param  SCRIPT_FILENAME  /usr/share/nginx/html$fastcgi_script_name;
      include        fastcgi_params;
  }

We are using the default Nginx document root in the /usr/share/nginx/html/ directory. In most cases you will want to configure your locations to use more unique root directories, but this corresponds to configuring multiple VirtualHost type configs, which we avoided.

With our configuration in place:

service php-fpm start
service nginx start

Create a test index.php file in /usr/share/nginx/html/ and then test the config by loading the root level of your domain/ip/public dns in your web browser.

Notes

This is a basic implementation that should get you up and running with Nginx and PHP-FPM on Amazon Linux. There is a lot of information about virtual host configurations, security best practices, and Apache to Nginx transition that are worth further investigation.

Msikivu 0.8.3: A responsive, configurable theme for Habari

2012-05-3

Get Msikivu (zip) Get Msikivu (tar.gz)

After some prodding from GitHub user jniggemann (thanks!), I finally got around to addressing some of my Msikivu todo list. For those interested in more details on Msikivu, check out my earlier post. In short, the following enhancements are present in the 0.8.3 release:

  1. Habari 0.8.x compatibility (Sorry this took so long...)
  2. Two additional stylesheets added. There is a 'blue' (which is oddly Drupal-ish and doesn't quite support IE - though to be honest I haven't really tested Msikivu's general IE support...) and a 'custom' (which is pretty devoid of non-positional styling, and ideal for creating your own custom Msikivu look and feel).
  3. Adds a 1200px wide grid to Skeleton for nicer presentation on widescreens (IMO).

There are still a couple issues with the comments interface on the iPhone, and I plan to make some cosmetic updates to the admin area as well. Note that if you want a lighter weight and less configurability-focused responsive base template, I also put together iwBase as a responsive starter theme for Habari 0.8 and greater.

Feel free to post requests for either theme in the comments here at imperialwicket.com or log an issue in the appropriate GitHub repository, and I'll try to make updates.

Disable system beeps in CrunchBang (Debain) with Intel sound card

2012-04-22

I will probably write about this in greater detail another time, but I finally updated my primary laptop from Fedora 14 to the latest CrunchBang Statler release.

My biggest frustrations had to do with driver issues, which is strange, as I have not experienced hardware compatibility issues in Linux since installing Dapper on an old Dell laptop. These issues were: broadcom wireless driver support (which is an issue with the 2.6.32 kernel release, not a distro-specific issue), and our title issue with system beeps when running with an Intel sound card.

If you are having issues with system beeps in CrunchBang (with a non-intel card), you should check framling's recommendations in the crunchbang forums. Those instructions removed some of my system beep issues, and in fact they work well for a most non-intel cards. You can also try nmk's simpler recommendation in that same thread, and it will likely resolve the issue for non-intel cards as well.

Still beeping at startup and shutdown after these configuration changes? My Dell (with the Intel sound card) was. Until I found these intel-specific notes in the Debian user forums. It seems that the intel drivers have a setting that overrides the pcspkr module, and the default is enabled/on. As enok notes in that thread:

# echo "options snd_hda_intel beep_mode=0" >> /etc/modprobe.d/alsa-base.conf
# echo "blacklist pcspkr" >> /etc/modprobe.d/blacklist.conf

Those two options are all you need on Intel cards. Note that if you attempted any of the techniques in the other posts, you likely already added the "blacklist pcspkr" line to your blacklist.conf file.

You will probably still get a system beep at the next shutdown, since the new beep_mode configuration won't be loaded. But the next time you boot the machine, you should enter a sweet, blissful, and beep-free environment.

AWS: Install Chicago Boss on Amazon Linux

2012-03-1

Something of an aside: I am finally making some time for Erlang, and have a couple neat projects in the pipeline for which I think it will prove appropriate. I want to focus these projects around server APIs with thick client-side code. I am leaning toward Chicago Boss with Spine. Before I commit to that, I want to spend a little more time with Zotonic and I would like to get to know Nitrogen. On the front-end, Backbone is a possible alternative, and I may avoid the client-side focus altogether and use the templating available in the Erlang framework.

I am going to skip the instance launching steps; you can find those spattered about the web. I put a LAMP targeting AWS EC2 instance article together that would do nicely, and you don't need to run any of the installations, just launch the instance and make an ssh connection. You might want to run a yum update.

The Chicago Boss installation turned out to be relatively straight-forward, but like installing Erlang, there were a few time-consuming parts that I wanted to document. The basic steps are:

  1. Install a reverse proxy server (Nginx)
  2. Install Erlang
  3. Install Chicago Boss
  4. Create a test project in Chicago Boss

Install Nginx

If you are only testing Chicago Boss, and do not plan on immediate use in a production environment, there is no necessity for a proxy server. The proxy server just gives you easy access to Chicago Boss over port 80. If you skip that step, just be sure that you add port 8001 to your security group.

As long as you are ok with an older Nginx release (in this case, I am), you can install Nginx from the Amazon repositories.

sudo yum install nginx

The download, configure, make, make install procedure for a more recent Nginx version does not seem difficult, but I did not run through it and it is outside the scope of this effort. I will note that if you are using setting the IP explicitly in your Nginx configuration files, be sure to use the Private IP and NOT an Elastic IP. You will encounter bind errors like the following if you use an Elastic IP:

[emerg]: bind() to 11.22.33.44:80 failed (99: Cannot assign requested address)

As I said, just replace the Elastic IP with the Private IP, and Nginx will start properly.

You will want to configure Nginx to relay requests to port 8001, there are instructions available from the Chicago Boss wiki for this redirection. That's not a great production config, but it is more than adequate for getting started.

Install Erlang

Get the latest download path here, and these Erlang installation instructions still work. Blogs are handy sometimes.

Install Chicago Boss

Download the latest release, and make it.

wget https://github.com/downloads/evanmiller/ChicagoBoss/ChicagoBoss-0.7.2.tar.gz
tar xzf ChicagoBoss-0.7.2.tar.gz
cd ChicagoBoss-0.7.2
make

I wanted to install the admin interface, for which there are instructions in the cb_admin repo and also in the Chicago Boss GH wiki. However, I had issues getting either to work, so I will follow up with a cb_admin post.

Create a project with Chicago Boss

We are up and running now, and the next step is definitely to create a project and start pushing Chicago Boss to meet your needs. Rather than copying the existing docs or paraphrasing, I will redirect everyone to the Quickstart wiki page and the more verbose Tutorial pdf. I recommend both.

If you encounter issues or have questions, the mailing list seems to be the way to go.

Increase PHP memory_limit on GoDaddy shared Linux hosting

2012-02-9

I have to look this up everytime, and for some reason it is really difficult to find a good resource. So after wasting another hour of my life searching random forums, here is what worked for me.

Using an FTP connection (it worked for me through a local FTP client or through the godaddy Hosting Control Center -> Content -> FTP File Manager), edit the php5.ini in your html directory. The full path is something like '/home/content/12/34567890/html/php5.ini' with different numerical values. Open that file. GoDaddy creates it for you when the account is created, if php5.ini is missing, someone probably deleted it, and you just need to make a new one.

In the php5.ini file, add the line:

memory_limit = 128M

The default is 64MB, which is enough for a lot of sites. Usually this needs to increase for the purpose of using particular extensions/plugins/modules in a CMS. Often image-handling extensions strongly encourage or even require 96M or 128M. I have not tested to see what the max is, but 128M is a good first step when 64M is no longer cutting it.

Now add a php file to that same 'html' directory. We need to use this for executing phpinfo(), and validating the change. Create a 'temp.php' file and add the line (be sure to add the open less than symbol, I don't have time to wrestle with its display at the moment):

?php phpinfo(); ?>

If you load your new temp.php page in a browser (yourPrimaryDomain.com/temp.php), you should see the PHP version you are using and all the PHP info details. A couple of these are of primary interest:

  • Loaded Configuration File
  • memory_limit

Unless you got really lucky, "Loaded Configuration File" is probably "(none)" at this point. If so, then your memory_limit value is still "64M". The problem is that your server has a fastcgi process running, and hence the php5.ini contents were loaded before you made the change. In order to reload the new php5.ini file, you need to kill off the existent web processes. Go to your hosting control center, then Content -> System Processes, now use the 'End Web' button to kill the running processes. This does not impede your site loading, it just forces the server to spawn a new process for the next request.

If you refresh the phpinfo page, you should see updated values for Loaded Configuration File and memory_limit. The server should have loaded your php5.ini file, and the memory_limit now reflects the updated value.

A couple other notes:

  • Be sure you edit the php5.ini file in your root 'html' directory. If you have subdomains or addon domains with their own directories, you still want to edit the file in your root 'html' directory.
  • Lots of places have data about php.ini affecting PHP 4 and php5.ini affecting PHP 5. One would think that since GoDaddy is no longer offering PHP 4, you could use either php.ini or php5.ini. Nope. Stick to php5.ini.
  • Don't try to use the php_value_memory_limit directive in your .htaccess file, this causes the server to throw errors.
  • I see lots of accounts that indicate you must use GoDaddy's FTP File Manager to edit the php5.ini file in order for it to work properly. I can't confirm this, and I can only assume that this direction was coincidentally related to running processes for the users that reported the behavior.

Now delete the phpinfo() file; I called it 'temp.php'. You do not want to leave these laying about your server. While I'm offering suggestions, you should also consider transferring to another hosting provider.