imperialWicket

am i the only croquet-playing computer nerd?

« Quality Assurance should not be entry-level The real anti-Firesheep »

AWS: Building a LAMP instance on Amazon Linux

2010-11-25

[UPDATE] Since I reference this occasionally, and it gets a fair amount activity, I thought I would make a more rudimentary version for anyone wanting easy access to a quick lamp setup on Amazon Linux. You can find the updated version at AWS: Quick and secure LAMP on Amazon Linux. It's a little more in depth of a setup, and there is very little explanation. If you are new to Linux/AWS I recommend you read this first, and head over to the Quick and secure setup after.

So you created an Amazon Web Services account when they announced that you could get services for free. Now what? The most direct transition to the cloud from your current implementation (or a good way to get started for anyone who doesn't have a virtual dedicated server) is to load an EC2 instance and configure it as a standalone LAMP stack. This puts definite ceilings on your scalability, and fails to take advantage of a number of the features available from AWS, but it remains a very practical place to start.

I am assuming that your AWS account is created, and you have already entered a credit card number for billing purposes. I'll try to avoid creating anything that will definitely result in fees, or mention it explicitly if I do something that might require them. Nonetheless, I'm not responsible if Amazon bills you for something - Whether it was in my instructions, or not.

Login to your AWS account. The default entry point is the S3 tab. On the S3 tab, create a bucket with a meaningful, unique name. We won't use this now, but it will be nice to have later.

Switch to the EC2 tab, where there is a prominent "Launch Instance" button, select it. The easiest way to start an instance is by using a Quick Start Amazon Machine Image (AMI). I recommend the Basic 64-bit Amazon Linux AMI 1.0 (ami-2272864b). This is a bare-bones CentOS-based Linux system. It comes backed with an Elastic Block Store (EBS) disk volume for data persistence (EC2 instances alone are non-persistent - if you shut it down, it's gone). The EBS volume also makes custom AMI generation and server snapshots quite simple using the AWS Management Console. After selecting your AMI (again, I will reference the Basic 64-bit Amazon Linux AMI with Id: ami-2272864b), you must choose the details for our instance. Instance details denote the type of instance, number of instances, and location of your instance. For now, we'll ignore spot instances and Private Cloud. The number of instances and the Availability zone are fine using defaults. Note that the default Instance Type is (at time of writing) "Large (m1.large, 7.5 GB)". The Large instance is not a bad server - but it's also not free, switch to Instance Type "Micro (t1.micro, 613 MB)". The micro instance is a pretty weak server, but it's fine for small sites and more than adequate for investigating AWS. Continue to the additional instance options. When your site goes viral, and you are scaling, these might become important. For most implementations, the defaults are adequate. Enable monitoring if you like (it's a nice system), but it costs money. You can leave User Data blank. Continue to the Key Value tags for your instance. Give your instance a tag with key "Name", I used value "Free Usage Instance 101", this helps for identification in the AWS Management Console interface. Continue to the Create Key Pair section.

You will need to create a Key pair to access your instance. The key will be used to connect to your instance, if you lose it, you will need to create a new one and modify your instance to allow connection. Don't lose it. Give the key a reasonable name, and download the file and continue.

Now we must configure Security Levels. These control the firewall that protects your EC2 instance. Make a new Security Group (I called mine "basic"), and add an HTTP rule to the default SSH rule. This allows access to your instance over ports 22 and 80. Continue to the review page, and after confirming that you are only launching 1 instance, and that it is Intance Type Micro, select the Launch button. Close the pop-up message, and proceed to your "Instances" page (available from the left menu area within the EC2 tab of your AWS Management Console. Micro instances take very little time to start, but if you happen to get to the Instances screen before it started, you will see a status "pending". After a minute or two, you can refresh and your status will likely update to "running".

OK, the server is started, now we must connect to it. Select your instance in the AWS Management Console and review the description details. Near the bottom of the page is a Public DNS value, note this value. If you are on Linux (non-Windows, really), launch your terminal application and connect via ssh using the key that you downloaded. The quickest way to accomplish this is something like (the server is the value of your instance's Public DNS):

ssh -i /path/to/my/keyfile.pem ec2-user@ec2-##-##-##-###.compute-#.amazonaws.com

If you are on Windows, the easiest way (I think...) is to use PuTTY and PuTTYGen. You need to import your key file (*.pem) to PuTTYGen to make a *.ppk version that PuTTY can use. Launch PuTTY and configure a new connection using the ec2-user@ec2-##-##-##-###.compute-#.amazonaws.com value as your host. Then go to Connection - SSH - Auth, and use the Browse button to select a private key for authentication, choose the *.ppk file you generated using PuTTYGen. Make sure to save the configuration, and open the connection.

You should see the EC2 ascii art, with the Amazon Linux AMI Beta text. At this point, the LAMP set up should be reasonably familiar, but remember that the Amazon Linux AMI is bare-bones. We need to install Apache, MySQL, and PHP. So, perform the following:

sudo su
yum install httpd
yum install mysql-server mysql 
yum install php php-mysql
service httpd start
service mysqld start
/usr/bin/mysqladmin -u root password 'password'

[UPDATE]
As Edward pointed out in the comments, this is a pretty bare-bones php installation. If you are installing a CMS or using a php framework, chances are high that you will require some or all of the following packages:

sudo yum install php-xml php-pdo php-odbc php-soap php-common \ 
php-cli php-mbstring php-bcmath php-ldap php-imap php-gd

After installing any PHP packages, or making config changes to PHP/Apache, you need to restart Apache before they take effect:

service httpd restart

Create a text file /var/www/html/index.php with the contents of your choice (" ?php phpinfo(); ?>" is usually a good start - just remove the space from the opening php tag), and navigate to ec2-##-##-##-###.compute-#.amazonaws.com in a browser.

That's it. A LAMP stack in the AWS Free Usage Tier. It won't be a speed demon (613 MB of memory...), but it's more than enough to test and practice. I'll post basics for Elastic IPs, generating AMIs and failing over soon.

44 Responses to AWS: Building a LAMP instance on Amazon Linux

Feed for this Entry

40 Comments

  • This command line is incorrect: service mysql start
    It should be: service mysqld start

  • @TP - Thanks for the careful review, I updated the post with your correction.

  • When I start adding data to this instance is it stored in EBS (and persistent) or will it be lost if the instance dies?

    If it dies, would you be willing to do a followup posting that describes how to set things up so that the data in mysql and in /var/www/html/ lives on when the ec2 instance goes down?

    #33 | Comment by Loren on Dec 17, 2010 11:03am
  • @Loren - Great questions, and ones that I probably should have discussed here.

    The data persists such that you can stop the instance (NOT terminate), and restart it with all the same data. If the instance is terminated, the mounted EBS volume will also be removed. An instance 'dying' (while unlikely, it is a claimed possibility with AWS) would be akin to termination, and would lose that data.

    To combat this, and as a good general rule of thumb in AWS, you should assume not that the instance could go down, but that it will. In order to best prepare for an instance/volume going down, you should generate AMIs (representing your EC2 instance), server snapshots (which represent your EBS volume content), and/or copy manual backups (mysql dumps and directory archives) to S3 buckets.

    If your website files and database are relatively small, manually copying (or scripting) backups and database dumps to another location might be a fine solution. However, I do think it is worth considering some of the more cloud-like options. I will post an article covering some basic backup techniques soon.

  • Thanks for this, I got it running but have been hitting my head against the wall all day trying to get mod_rewrite working-- any ideas?

  • @SH - If you installed via "yum install httpd" from the amazon repositories, then mod_rewrite is enabled by default. You can double check this, and add your rewrite rules in the /etc/httpd/conf/httpd.conf file.

    If you want to use a directory-specific .htaccess file, you will need to update the Directory configuration for /var/www/html/ in the httpd.conf. By default .htaccess overrides are disabled, change the httpd.conf file so that "AllowOverride None" becomes "AllowOverride All" within the /var/www/html/ Directory tags.

  • Thx for the great article!

    Managed to get an instance up and running, then tried to install http://www.webmin.com/ as a free alternative to cPanel.

    Problem is, according to their docs, "the administration username set to root and the password to your current root password".

    Any idea what the default root password for Basic 64-bit Amazon Linux AMI 1.0 is?

    #65 | Comment by James on Dec 28, 2010 07:53am
  • Got it!

    Root password can be changed by typing passwd from ssh.

    Sorry about the noob question!

    #66 | Comment by James on Dec 28, 2010 08:07am
  • @James - Glad this helped. Just note Loren's comment above: if you are using this for more than just development/testing, be aware that you will need to come up with a good backup solution. The root EBS volume that is used for your instance will die if your instance dies (through termination or catastrophe).

    I will try to post some additional guides for backup strategies soon.

  • Bless you Nicholas! I got an instance of AWS yesterday to teach myself PHP/MySql and I was really thrashing around a lot to try and get things set up. I spend about four hours before I decided it was time to walk away and try again the next day.

    Thanks to your post I got something up and running in 10 minutes. Thanks for sharing your knowledge with the less experienced!

  • @Daniel - 10 minutes sounds about right. There is a lot to learn about linux basics and yum, but the goal here is to get you up and running as quickly and easily as possible. Good luck with PHP and MySQL!

  • Great, simple to follow post.

    Everything was fine until I attempted to upload a file to /var/www/html/.

    I configured Filezilla and successfully connected to the instance with ec2-user. However, when I attempted to upload the file I received a write permission denied error.

    Any ideas/suggestions?

    Thanks.

    #730 | Comment by bob on Feb 5, 2011 11:33am
  • @bob - glad this worked out well for you. If you want to connect via FTP, you will need to install and configure an ftp-server on the EC2 instance. I would not recommend this.

    Instead, you should connect via SCP, which will be a secure transaction, and use your existing key to validate the session (the SCP connection uses SSH). If you are on Windows, WinSCP is a great utility. CyberDuck or Fugu will work on OS X, and on most Linux distros your native file explorer will support SCP connection.

  • @nicholas,
    Yes, I configured SFTP through filezilla, and using my existing key connected to my instance with the user 'ec2-user'.

    I can upload files into tmp which has 777 permissions, but not html which has 755. When attempting to upload to /var/www/html/ I receive 'write permission denied' so I'm thinking it has something to do with with ec2-user.

    I actually created the instance twice because this seems a bit odd. I also installed SCP and received the same error.

    #732 | Comment by bob on Feb 5, 2011 03:49pm
  • @bob - Sorry, I misunderstood the issue. The /var/www/html does not allow general user access as a security measure (this is consistent with most Linux distros). You should upload an archive to /home/ec2-user/ and then login to the instance via ssh and move the files over. You will need to use sudo (something like: sudo mv /home/ec2-user/myFile /var/www/html/).

  • @nicholas - Thanks, I knew it was something simple since I'm a bit of a noob.

    #734 | Comment by bob on Feb 5, 2011 06:15pm
  • the line:
    service mysqld start

    returns:
    mysqld: unrecognized service

    any advice?

    #747 | Comment by Rip on Feb 9, 2011 10:36am
  • @Rip - Can you confirm that you executed 'sudo yum install mysql-server' ?

    If you only install 'mysql' it will allow you to talk to other database servers, but it does not install a database server on your local instance.

  • i am a pure wamp stack developer and is about to join a company that develops lamp stack projects on the AWS EC2 platform. linux and cloud computing are so totally new to me despite my 4+ years in developing web applications. Thank you so much for sharing your knowledge! You definitely saved me weeks, if not days, just to be able to achieve this. linux world here i come!

    #854 | Comment by ian on Mar 3, 2011 09:19am
  • Hello ;)

    Kind of noob...
    @James -
    I Also installed Webmin for Basic 64-bit Amazon Linux AMI using the repository installation(http://www.webmin.com/rpm.html). I'm using the "Apache In A Sub-Directory" method describe on http://www.webmin.com/apache.html.

    My question is related to the username and password. I reach the webmin login page but I have no clue as to what username and password to use, or how to set it. Could you please explain (commands?) that you used?

    Thanks ;)

    #896 | Comment by Ace on Mar 11, 2011 01:26pm
  • Got it!
    Command line for anybody who's interested..

    /usr/share/webmin/changepass.pl /etc/webmin username password

    Assuming you have installed Webmin in /usr/share/webmin

    Also noticed with the path I went to install and integrate, system reboot also helps ;)

    #897 | Comment by Ace on Mar 11, 2011 03:06pm
  • I have my index.php file in /var/www/html/

    However, when I go to my EC2 AWS public DNS, the browser says it cannot find the right page. I restarted httpd.

    I'm a noob, but any insight would be much appreciated!

    #934 | Comment by Steve on Mar 22, 2011 08:43pm
  • Nevermind... opened port 80 in case anyone else has the same problem. Go to security settings in AWS ec2 console to add ports

    #935 | Comment by Steve on Mar 22, 2011 09:03pm
  • Thank you very much! Your instructions took me about 10 minutes to get the first page up and running.

    #2734 | Comment by Cat on Aug 6, 2011 11:34am
  • Having trouble when I open the connection. Instead of seeing the ascii art i get a prompt "login as" who do i login as?

  • got it! its ec2-user

  • @Edward - Good find, ec2-user is the default user associated with the primary key from your ec2 instance.

    If you include the user in your ssh connection, you will not need to enter it once you connect to the server. That is:

    ssh -i KEYFILE ec2-user@IP

    As opposed to:

    ssh -i KEYFILE IP

    The latter will first assume you want to connect as the current user (on your local machine), and default to asking you if this user is not appropriate for the remote machine.

    Also, if you want to connect via ssh keys with non-ec2-user users, I wrote some instructions particular to scp over here, but scp uses ssh and the plain ssh connection will work with the keys as well.

  • I set this up to test a joomla system on cloud hosting..it wasn't working until:

    yum install php-xml
    service httpd restart

    I figured I would include this here because there is a blog post pointing to this amazing guide on how to set up Joomla on AWS

  • @Edward - thanks for the tip regarding Joomla. I think you'll find there are a couple of other packages that many extensions will also require/desire, including (but not limited to):

    sudo yum install php-xml php-pdo php-odbc php-soap php-common \
    php-cli php-mbstring php-bcmath php-ldap php-imap php-gd
    

    I'm adding this note to the main post, thanks again.

  • Nicholas, you are a savior. I've been looking all over for steps on how to use the instance. I have followed your steps to the T. However when I go to the public DNS url my browser won't load it. It says the connection was reset.

    What do I do?

    #5837 | Comment by Matthew on Jan 6, 2012 05:06pm
  • @Matthew - Usually this is because of a security group (firewall) issue. I suggest double checking that HTTP/port 80 is open to all requests (0.0.0.0/0). If it is already open, try removing the request and adding it again.

    Also, remember that security group updates require a two step process. First you add the rules, then you must confirm the rule change. It's easy to miss the confirmation step and not make any allowances in your security group.

    Hope this helps!

  • Big thanks. Last night I was compiling apache and php from source... I started clean with these simple directions and I'm up and running. Thanks!

    #8105 | Comment by Tom on Feb 1, 2012 06:04pm
  • Hi Nicholas,

    Thanks for a very clear and detailed tutorial. I'm only having trouble with the last part- after I create the index.php file, when I accesses my instance, I seem to get stuck on the "Amazon Linux AMI Test Page". The 80 port is open, and I've changed the permissions of the file. Any idea how to fix it?

    Thanks,
    Lior

    #8657 | Comment by Lior on Jun 16, 2012 03:12pm
  • @Lior - Glad this helped get things moving for you. If you see the Amazon Linux AMI Test Page, then your ports and security groups are fine.

    Since writing this, I believe the default Amazon Linux httpd.conf file has changed slightly. A first test is to try to load http://[your public dns]/index.php , if this loads, it confirms that apache is not configured to serve that file as the default. If that's the case, you can change the DirectoryIndex line in the /etc/httpd/conf/httpd.conf file from:

    DirectoryIndex index.html index.html.var
    

    to:

    DirectoryIndex index.php index.html index.html.var
    

    This change simply tells apache that when a directory is requested, it should look for those files, and serve them (if available).

  • Hi @Nicholas,
    This is not the case. http://[your public dns]/index.php returns 404 (page not found), but I think I might have mistaken creating the "/var/www/html/index.php" inside the
    /home/ec2/ folder. Although when I try to change the root var folder I get permission errors. Any further advice..?

    Thanks,
    Lior

    #8682 | Comment by Lior on Jun 19, 2012 07:36am
  • @Lior - The root issue here is a file system level permissions issue. Apache is not allowed to access the ec2-user's home directory. You have several options here and pros/cons to go with each:
    1. Likely the cleanest, but most technical - Create a VirtualHost and set the DocumentRoot for the VirtualHost to be /home/ec2-user/, then be sure your permissions allow the user 'apache' to read those files.
    2. Middle-ground, just change the default DocumentRoot (in the httpd.conf file I mentioned last time) to be the /home/ec2-user/ directory, and be sure permissions are fine.
    3. Easiest solution (and practical if you are only hosting one site - it gets problematic when you want to host multiple sites): use 'sudo su -' to change to the root user, and create your files in /var/www/html/ as root. You either need to have permissions set to 755, or you'll need use something like 'chown apache:apache /var/www/html/index.php' to be sure that apache can read the files.

  • Thanks for this great writeup. I have been able to get the server up and running and mysql too is working, but it seems that the default password is not "password". I am getting the below

    usr/bin/mysqladmin -u root password 'root'
    /usr/bin/mysqladmin: connect to server at 'localhost' failed
    error: 'Access denied for user 'root'@'localhost' (using password: NO)'

    Any clues?

    #10983 | Comment by Vaibhav on Feb 6, 2013 09:16am
  • @Vaibhav - A couple things:

    1) This isn't a bad quick setup, but for something that's going to persist, you should check out http://imperialwicket.com/aws-quick-and-secure-lamp-on-amazon-linux

    2) If you enter the command:

    /usr/bin/mysqladmin -u root password 'root'

    Then you tell the mysqladmin binary to set the root user's password to 'root'. After executing that, you can connect to mysql at the shell with:

    mysql -u root -proot

    Note there's no space between the -p flag and the password that you set.

    As it's detailed in the linked post above, setting the root password via the mysql_secure_installation script is probably a little more user friendly.

    Hope that helps!

  • I can't actually read your code boxes. Mid brown against slightly darker mid brown is impossible.

    #14828 | Comment by Jools on Apr 29, 2013 11:09am
  • @Jools - Fair enough. I think contrast is a bit of an issue throughout, but code blocks (pre) were probably the worst. I increased the contrast, cheers.


About You

Email address is not published

Add to the Discussion

Search