This document will walk you through the installation of what is known as a "LAMP" system:
Linux, Apache, MySQL and PHP.
Depending on who you talk to, the P also stands for Perl or
Python, but in general, it is assumed to be PHP. I run CentOS
on my servers; these directions were written for CentOS/Red Hat/Fedora. I have had requests
for SuSE (another RPM-based distribution) as well as Debian-based systems, so I will work on
variants of these directions for those distributions in the future (donations might help speed
that process up!). The main difference between the distributions is in the paths to the startup scripts. Red Hat
systems used
If you need an SSL-enabled server, I have a LAMP with SSL howto as well.
I designed this document so you can just copy/paste each line or block of commands into your shell session and it will "just work" for you. This avoids tedious typing, and the inevitable typos or missed steps that result. These commands work properly via copy/paste. If you are having problems and you are not using copy/paste, please re-check your typing before sending me an email saying "It doesn't work."
If you have not yet installed your Linux OS, or just for future reference, do not choose to install Apache, PHP, or MySQL during the system installation. Then you can immediately proceed with the source-based install listed here.
Note: to install applications from source code, you will need a C++ compiler (gcc++) installed. This is generally taken care of, but I've had enough queries about it that I've added this note to avoid getting more! You can use your distribution's install CDs to get the proper version of the compiler. Or, if you are using an RPM based distro, you can use a site like http://www.rpmfind.net/ to locate the correct RPM version for your system. (You will obviously not be able to use/rebuild a source RPM to get the compiler installed, as you need the compiler to build the final binary RPM!) On a Fedora system, you can do this command:
If you do not have direct access (via keyboard) to the server, PLEASE use Secure Shell (SSH) to access the server and not
At the time of updating this, the current versions of all the components we'll use are:
For MySQL, go to http://www.mysql.com/ and choose an appropriate mirror to get the newest MySQL version (v4.1.22).
What the
Now we'll change to the "working" directory where the source code is, change the file 'ownership' for the source tree (this prevents build issues in reported in some cases where the packager's username was included on the source and you aren't using the exact same name to compile with!) and start building.
The
Edit
For more security info, check out this MySQL security tutorial.
Now we'll set a password for the MySQL
The downside to dynamic modules is a slight performance hit compared to having the modules compiled in.
Recommended reading on securing your PHP installation is this article at SecurityFocus.com.
Also recommended is the article on securing Apache.
To ensure your PHP files are properly interpreted, and not just downloaded as text files, remove the
If you wish to use other/additional extensions/filetypes for your PHP scripts instead of just
Add
/etc/rc.d/init.d
and SuSE uses /etc/init.d
.If you need an SSL-enabled server, I have a LAMP with SSL howto as well.
I designed this document so you can just copy/paste each line or block of commands into your shell session and it will "just work" for you. This avoids tedious typing, and the inevitable typos or missed steps that result. These commands work properly via copy/paste. If you are having problems and you are not using copy/paste, please re-check your typing before sending me an email saying "It doesn't work."
Text in a "command" box like this one is a literal Linux commandline,
and should be typed or pasted exactly as written.
One note: many many people have followed these directions as written,
and have not had any problems.
If you are having a problem, chances are it's something you are doing (or not doing), something different
about your computer, etc.
It is probably NOT this procedure. :)
If you are having a problem, chances are it's something you are doing (or not doing), something different
about your computer, etc.
It is probably NOT this procedure. :)
Initial Steps
PLEASE BE AWARE THAT A SOURCE-BASED INSTALLATION LIKE THIS
ONE IS NOT NEEDED FOR A BASIC LAMP SERVER! You should only be doing a source-based
installation if you need to alter settings in one or more components of the
LAMP stack (e.g., you need a feature in PHP that isn't in the default RPM).
If you are just getting started with LAMP, use the binaries provided by your
distribution - it is much simpler, and a lot easier to upgrade later.
Most out-of-the-box Red Hat Linux installations will have one or more of the LAMP
components installed via RPM files. I personally believe in installing things like this from
source, so I get the most control over what's compiled in, what's left out, etc. But
source code installs can wreak havoc if overlaid on top of RPM installs, as the two most
likely won't share the same directories, etc.If you have not yet installed your Linux OS, or just for future reference, do not choose to install Apache, PHP, or MySQL during the system installation. Then you can immediately proceed with the source-based install listed here.
Note: to install applications from source code, you will need a C++ compiler (gcc++) installed. This is generally taken care of, but I've had enough queries about it that I've added this note to avoid getting more! You can use your distribution's install CDs to get the proper version of the compiler. Or, if you are using an RPM based distro, you can use a site like http://www.rpmfind.net/ to locate the correct RPM version for your system. (You will obviously not be able to use/rebuild a source RPM to get the compiler installed, as you need the compiler to build the final binary RPM!) On a Fedora system, you can do this command:
su - root
yum install gcc gcc-c++
yum install gcc gcc-c++
Log in as
Because we will be installing software to directories that "regular" users don't have
write access to, and also possibly uninstalling RPM versions of some applications, we'll
log in as root
root
. The only steps that need root
access are the actual
installation steps, but by doing the configure
and make
steps as root
,
the source code will also be inaccessible to "regular" users.If you do not have direct access (via keyboard) to the server, PLEASE use Secure Shell (SSH) to access the server and not
telnet
!!
Whenever you use telnet
(or plain FTP for that matter), you are transmitting your username,
password, and all session information in "plain text". This means that anyone who can access
a machine someplace between your PC and your server can snoop your session and get your info.
Use encryption wherever possible!
su - root
Remove RPM Versions of the Applications
Before we start with our source code install, we need to remove all the existing RPM files
for these products. To find out what RPMs are already installed, use the RPM query command:
rpm -qa
in conjunction with grep
to filter your results:
rpm -qa | grep -i apache
rpm -qa | grep -i httpd
rpm -qa | grep -i php
rpm -qa | grep -i mysql
rpm -qa | grep -i httpd
rpm -qa | grep -i php
rpm -qa | grep -i mysql
The 'httpd' search is in case you have Apache2 installed via RPM.
To remove the RPMs generated by these commands, do
rpm -e filename
for each RPM you found in the query. If you have any content in your MySQL database
already, the RPM removal step should not delete the database files. When you reinstall
MySQL, you should be able to move all those files to your new MySQL data directory and
have access to them all again.
Get the Source Code for all Applications
We want to put all our source code someplace central, so it's not getting mixed up in someone's
home directory, etc.
cd /usr/local/src
One way application source code is distributed is in what are known as "tarballs." The tar
command
is usually associated with making tape backups - tar
stands for Tape ARchive.
It's also a handy way to pack up multiple files for easy distribution. Use the man tar
command to
learn more about how to use this very flexible tool.At the time of updating this, the current versions of all the components we'll use are:
MySQL - 4.1.22
Apache - 1.3.37
PHP - 4.4.6
Apache - 1.3.37
PHP - 4.4.6
Please note: these are the only versions of these that I have
set up myself, and verified these steps against. If you use another version of
any component, especially a newer version, this HOWTO may not be accurate, and I
won't be able to provide free support under those circumstances. Paid support and
assistance is always available however.
wget http://www.php.net/distributions/php-4.4.6.tar.gz
wget http://apache.oregonstate.edu/httpd/apache_1.3.37.tar.gz
There may be an Apache mirror closer to you - check their mirror
page for other sources. Then insert the URL you get in place of the above for the wget http://apache.oregonstate.edu/httpd/apache_1.3.37.tar.gz
wget
command.For MySQL, go to http://www.mysql.com/ and choose an appropriate mirror to get the newest MySQL version (v4.1.22).
Unpack the Source Code
tar zxf php-4.4.6.tar.gz
tar zxf apache_1.3.37.tar.gz
tar zxf mysql-4.1.22.tar.gz
This should leave you with the following directories:tar zxf apache_1.3.37.tar.gz
tar zxf mysql-4.1.22.tar.gz
/usr/local/src/php-4.4.6
/usr/local/src/apache_1.3.37
/usr/local/src/mysql-4.1.22
/usr/local/src/apache_1.3.37
/usr/local/src/mysql-4.1.22
Build and Install MySQL
First, we create the group and user that "owns" MySQL. For security purposes,
we don't want MySQL running as root
on the system. To be able to easily
identify MySQL processes in top
or a ps
list, we'll make a user
and group named mysql
:
groupadd mysql
useradd -g mysql -c "MySQL Server" mysql
If you get any messages about the group or user already existing, that's fine.
The goal is just to make sure we have them on the system.useradd -g mysql -c "MySQL Server" mysql
What the
useradd
command is doing is creating a user mysql
in the group mysql
with the "name" of MySQL Server. This way when it's
showed in various user and process watching apps, you'll be able to tell what it is right
away.Now we'll change to the "working" directory where the source code is, change the file 'ownership' for the source tree (this prevents build issues in reported in some cases where the packager's username was included on the source and you aren't using the exact same name to compile with!) and start building.
The
configure
command has many options you can specify.
I have listed some fairly common ones; if you'd like to see others, do:
./configure --help | less
to see them all. Read the documentation
on the MySQL website for a more detailed explanation of each option.
cd /usr/local/src/mysql-4.1.22
chown -R root.root *
make clean
./configure \
--prefix=/usr/local/mysql \
--localstatedir=/usr/local/mysql/data \
--disable-maintainer-mode \
--with-mysqld-user=mysql \
--with-unix-socket-path=/tmp/mysql.sock \
--without-comment \
--without-debug \
--without-bench
chown -R root.root *
make clean
./configure \
--prefix=/usr/local/mysql \
--localstatedir=/usr/local/mysql/data \
--disable-maintainer-mode \
--with-mysqld-user=mysql \
--with-unix-socket-path=/tmp/mysql.sock \
--without-comment \
--without-debug \
--without-bench
18-Jul-2005: If you are installing MySQL 4.0.x on Fedora Core 4, there is a
problem with LinuxThreads that prevents MySQL from compiling properly.
Installing on Fedora Core 3 works fine though. Thanks to Kevin Spencer for bringing
this to my attention. There is a workaround listed at
http://bugs.mysql.com/bug.php?id=9497.
Thanks to Collin Campbell for that link. Another solution can be
found at http://bugs.mysql.com/bug.php?id=2173.
Thanks to Kaloyan Raev for that one.
Now comes the long part, where the source code is actually compiled and then installed.
Plan to get some coffee or take a break while this step runs. It could be 10-15 minutes or
more, depending on your system's free memory, load average, etc.
make && make install
Configure MySQL
MySQL is "installed" but we have a few more steps until it's actually "done"
and ready to start. First run the script which actually sets up MySQL's
internal database (named, oddly enough, mysql
).
./scripts/mysql_install_db
Then we want to set the proper ownership for the MySQL directories and data files, so that
only MySQL (and root
) can do anything with them.
chown -R root:mysql /usr/local/mysql
chown -R mysql:mysql /usr/local/mysql/data
Copy the default configuration file for the expected size of the database (small, medium, large, huge)chown -R mysql:mysql /usr/local/mysql/data
cp support-files/my-medium.cnf /etc/my.cnf
chown root:sys /etc/my.cnf
chmod 644 /etc/my.cnf
chown root:sys /etc/my.cnf
chmod 644 /etc/my.cnf
If you get an error message about the
Now we have to tell the system where to find some of the dynamic libraries that
MySQL will need to run. We use dynamic libraries instead of static to keep the memory
usage of the MySQL program itself to a minimum.data
directory not existing, etc., something went
wrong in the mysql_install_db
step above. Go back and review that; make sure you didn't
get some sort of error message when you ran it, etc.
echo "/usr/local/mysql/lib/mysql" >> /etc/ld.so.conf
ldconfig
Now create a startup script, which enables MySQL auto-start each
time your server is restarted.ldconfig
cp ./support-files/mysql.server /etc/rc.d/init.d/mysql
chmod +x /etc/rc.d/init.d/mysql
/sbin/chkconfig --level 3 mysql on
Then set up symlinks for all the MySQL binaries, so they can be run
from anyplace without having to include/specify long paths, etc.chmod +x /etc/rc.d/init.d/mysql
/sbin/chkconfig --level 3 mysql on
cd /usr/local/mysql/bin
for file in *; do ln -s /usr/local/mysql/bin/$file /usr/bin/$file; done
for file in *; do ln -s /usr/local/mysql/bin/$file /usr/bin/$file; done
MySQL Security Issues
First, we will assume that only applications on the same server
will be allowed to access the database (i.e., not a program running
on a physically separate server). So we'll tell MySQL not to even
listen on port 3306 for TCP connections like it does by default.Edit
/etc/my.cnf
and uncomment the
skip-networking
line (delete the leading #
).For more security info, check out this MySQL security tutorial.
Start MySQL
First, test the linked copy of the startup script in the normal server runlevel
start directory, to make sure the symlink was properly set up:
cd ~
/etc/rc.d/rc3.d/S90mysql start
If you ever want to manually start or stop the MySQL server, use these commands:/etc/rc.d/rc3.d/S90mysql start
/etc/rc.d/init.d/mysql start
/etc/rc.d/init.d/mysql stop
Let's "test" the install to see what version of MySQL we're running now:/etc/rc.d/init.d/mysql stop
mysqladmin version
It should answer back with the version we've just installed...Now we'll set a password for the MySQL
root
user (note that the
MySQL root
user is not the same as the system
root
user, and definitely should not have the same
password as the system root
user!).
mysqladmin -u root password new-password
(obviously, insert your own password in the above command instead of the "new-password" string!)
You're done! MySQL is now installed and running on your server. It is highly recommended
that you read about MySQL security and lock down your server as much as possible. The MySQL
site has info at http://www.mysql.com/doc/en/Privilege_system.html.
Test MySQL
To run a quick test, use the command line program mysql
:
mysql -u root -p
and enter your new root
user password when prompted. You will then
see the MySQL prompt:
mysql>
First, while we're in here, we'll take care of another security
issue and delete the sample database test
and all default
accounts except for the MySQL root user. Enter each of these lines
at the mysql>
prompt:
drop database test;
use mysql;
delete from db;
delete from user where not (host="localhost" and user="root");
flush privileges;
As another security measure, I like to change the MySQL administrator account
name from use mysql;
delete from db;
delete from user where not (host="localhost" and user="root");
flush privileges;
root
to something harder to guess. This will make it that
much harder for someone who gains shell access to your server to take control of
MySQL.
MAKE SURE YOU REMEMBER THIS NEW NAME, AND USE IT WHEREVER
YOU SEE "root" IN OTHER DIRECTIONS, WEBSITES, ETC.
ONCE YOU DO THIS STEP, THE USERNAME "root" WILL CEASE TO
EXIST IN YOUR MYSQL CONFIGURATION!
YOU SEE "root" IN OTHER DIRECTIONS, WEBSITES, ETC.
ONCE YOU DO THIS STEP, THE USERNAME "root" WILL CEASE TO
EXIST IN YOUR MYSQL CONFIGURATION!
update user set user="sqladmin" where user="root";
flush privileges;
Now, on with the "standard" testing... First, create a new database:flush privileges;
create database foo;
You should see the result:
Query OK, 1 row affected (0.04 sec)
mysql>
Delete the database:mysql>
drop database foo;
You should see the result:
Query OK, 0 rows affected (0.06 sec)
mysql>
To exit from mysql>
mysql
enter \q
:
\q
Build and Install Apache (with DSO support)
The advantage to building Apache with support for dynamically loaded modules is
that in the future, you can add functionality to your webserver by just compiling
and installing modules, and restarting the webserver. If the features were compiled
into Apache, you would need to rebuild Apache from scratch every time you wanted
to add or update a module (like PHP). Your Apache binary is also smaller, which
means more efficient memory usage.The downside to dynamic modules is a slight performance hit compared to having the modules compiled in.
cd /usr/local/src/apache_1.3.37
make clean
./configure \
--prefix=/usr/local/apache \
--enable-shared=max \
--enable-module=rewrite \
--enable-module=so
make && make install
make clean
./configure \
--prefix=/usr/local/apache \
--enable-shared=max \
--enable-module=rewrite \
--enable-module=so
make && make install
Build and Install PHP
This section has only been tested with PHP v4.x. If you are trying to build
PHP 5.x, I do not have experience with this yet, and do not provide free support
for you to get it working. Please note that there are many options which
can be selected when compiling PHP. Some will have library dependencies, meaning
certain software may need to be already installed on your server before you start
building PHP. You can use the command
./configure --help | less
once you change into the PHP source directory. This will show you a list of all possible
configuration switches. For more information on what these switches are, please
check the PHP website documentation.
cd /usr/local/src/php-4.4.6
./configure \
--with-apxs=/usr/local/apache/bin/apxs \
--disable-debug \
--enable-ftp \
--enable-inline-optimization \
--enable-magic-quotes \
--enable-mbstring \
--enable-mm=shared \
--enable-safe-mode \
--enable-track-vars \
--enable-trans-sid \
--enable-wddx=shared \
--enable-xml \
--with-dom \
--with-gd \
--with-gettext \
--with-mysql=/usr/local/mysql \
--with-regex=system \
--with-xml \
--with-zlib-dir=/usr/lib
make && make install
cp php.ini-dist /usr/local/lib/php.ini
I like to keep my config files all together in ./configure \
--with-apxs=/usr/local/apache/bin/apxs \
--disable-debug \
--enable-ftp \
--enable-inline-optimization \
--enable-magic-quotes \
--enable-mbstring \
--enable-mm=shared \
--enable-safe-mode \
--enable-track-vars \
--enable-trans-sid \
--enable-wddx=shared \
--enable-xml \
--with-dom \
--with-gd \
--with-gettext \
--with-mysql=/usr/local/mysql \
--with-regex=system \
--with-xml \
--with-zlib-dir=/usr/lib
make && make install
cp php.ini-dist /usr/local/lib/php.ini
/etc
. I set up
a symbolic link like this:
ln -s /usr/local/lib/php.ini /etc/php.ini
Then I can just open /etc/php.ini
in my editor to make changes.Recommended reading on securing your PHP installation is this article at SecurityFocus.com.
Edit the Apache Configuration File (
I like to keep all my configuration files together in httpd.conf
)/etc
, so I
set up a symbolic link from the actual location to /etc
:
ln -s /usr/local/apache/conf/httpd.conf /etc/httpd.conf
Now open /etc/httpd.conf
in your favorite text editor, and set all
the basic Apache options in accordance with
the official Apache instructions
(beyond the scope of this HOWTO).Also recommended is the article on securing Apache.
To ensure your PHP files are properly interpreted, and not just downloaded as text files, remove the
#
at the beginning of the lines which read:
#AddType application/x-httpd-php .php
#AddType application/x-httpd-php-source .phps
If the AddType lines above don't exist, manually enter them (without the leading #AddType application/x-httpd-php-source .phps
#
of course) after the line
AddType application/x-tar .tgz
or anyplace within the <IfModule mod_mime.c>
section of httpd.conf
.If you wish to use other/additional extensions/filetypes for your PHP scripts instead of just
.php
, add them to the AddType
directive:
AddType application/x-httpd-php .php .foo
AddType application/x-httpd-php-source .phps .phtmls
An example: if you wanted every single HTML page to be parsed and processed like a PHP
script, just add AddType application/x-httpd-php-source .phps .phtmls
.htm
and .html
:
AddType application/x-httpd-php .php .htm .html
There will be a bit of a performance loss if every single HTML page is being checked for PHP code
even if it doesn't contain any. But if you want to use PHP but be "stealthy" about it, you can
use this trick.Add
index.php
to the list of valid Directory Index files so that your "default page"
in a directory can be named index.php
.
<IfModule mod_dir.c>
DirectoryIndex index.php index.htm index.html
</IfModule>
You can add anything else you want here too. If you want DirectoryIndex index.php index.htm index.html
</IfModule>
foobar.baz
to be
a valid directory index page, just add the .baz
filetype to the AddType
line, and add foobar.baz
to the DirectoryIndex
line.
Start Apache
We want to set Apache up with a normal start/stop script in /etc/rc.d/init.d
so it
can be auto-started and controlled like other system daemons. Set up a symbolic link for the
apachectl
utility (installed automatically as part of Apache):
ln -s /usr/local/apache/bin/apachectl /etc/rc.d/init.d/apache
Then set up auto-start for runlevel 3 (where the server will go by default):
ln -s /etc/rc.d/init.d/apache /etc/rc.d/rc3.d/S90apache
Then start the daemon:
/etc/rc.d/init.d/apache start
You can check that it's running properly by doing:
ps -ef
and look for the httpd
processes.