Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1575668
  • 博文数量: 317
  • 博客积分: 10283
  • 博客等级: 上将
  • 技术积分: 3566
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-04 11:38
个人简介

哥使用Linux

文章分类

全部博文(317)

分类: LINUX

2007-10-14 11:46:41

Original Link:
 
 

System Administration Tips and Resources

[ | | | | | | |

LAMP on Sarge (Apache2, PHP5, MySQL5, phpMyAdmin, Smarty, ADODB)

Posted by on Wed 22 Feb 2006 at 09:10

Tags: , , , , , ,

This documents my adventure setting up a LAMP server on Sarge with Apache2, PHP5, MySQL5, phpMyAdmin, Smarty, and ADODB. It covers installation and just enough sample code to test everything. It turned out to be pretty long. I should point out that I have deviated from the "Debian Way" by downloading phpMyAdmin, Smarty, and ADODB directly from their respective websites and installing them in /usr/local. I could find no backports for these, and kept running into dependecies on PHP4 which I did not want to install.

Contents

What I Installed and Where I Got It.

Apache 2.0.54
The webserver we know and love. This is the apache2-mpm-prefork package from Sarge (see note below)
PHP 5.1.2-1
The scripting language we know an love. This is the backported libapache2-mod-php5 package from dotdeb.org
PHP5 MySQL 5.1.2-1
The MySql extensions for PHP. This is the backported php-mysql-5.1.2-1 package from dotdeb.org
MySQL 5.0.18
This is the backported mysql-server package from dotdeb.org
phpMyAdmin 2.7.0-pl2
Web interface for managing databases. Downloaded from the site.
Smarty 2.6.12
Template engine for PHP. Downloaded from the site.
ADODB 4.7.1-1
Database extraction class for PHP. Downloaded from the site.

Note: The PHP folks say it's a bad idea to use the threading Apache2, so I used the MPM prefork version from Sarge. For more info read the FAQ . Also there is the MPM prefork info .

Before You Start

  • Firewall:. This is a must If you are going to put your box out on the web. Good candidates are and .
  • DNS: If you want your box available on the web, you need to configure DNS to point to your web server's IP address for whatever domain(s) you are going to host.

Installing Apache

As noted above, this is the MPM prefork version available in Sarge. I'm also installing some of the packages it recommends. No changes are required to /etc/apt/sources.list for this.

$> apt-get update
$> apt-get upgrade
$> apt-get install apache2-mpm-prefork apache2-doc lynx ca-certificates.

Testing Apache

Before we start messing with it, you might as well check that Apache is working. Point a browser at and verify that you see the installed default Apache site. If you don't, check your DNS and firewall. Fix whatever the problem is before you go on.

Security Tweaks for Apache

I decided on these security tweaks from reading the security tips on the Apache site. You can add these to the main config file, but I opted to keep my own config changes separate by putting them in a file in the /etc/apache2/conf.d/ directory. I created a file there named local_configs.conf and put the following in it.

# Tighten access to the file system.

        # Forbid default access to file system locations
        Order Deny,Allow
        Deny from all
        # prevent use of .htaccess files in all directories
        # apart from those specifically enabled.
        AllowOverride None


# Limit available info about this server.
ServerSignature Off
ServerTokens production

Don't forget to reload Apache after changing the config.

Virtual Hosting Refresher

The Debian installation of Apache2 comes all set up do "name-based" virtual hosting right out of the box. This is perfect if you have more than one domain to host on your server, or plan to in the future. For the uninitiated, here's a quick rundown on virtual hosting.

Virtual hosting refers to the practice of running more than one web site (domains) on a single server. The fact that they are running on the same physical server is not apparent to the end user. There are two types of virtual hosting, IP-based and name-based.

IP-based virtual hosting is when you have a different IP address for every domain. We'll not be doing it in this HOWTO.

Name-based virtual hosting is when you have multiple domains running from one IP address, and is what we will be using here. This means that the DNS A records (or CNAME records) for and can both point to the one IP address of your server, and Apache will sort out which site to serve up based on the domain that was requested. If someone points their browser at the IP address of your server, e.g. they will be served the first site that you have configured. Unless you change it, this will be the Apache default site as it is installed by Debian's Apache2 package.

For more info on virtual hosting, .

Getting Familiar With Apache

Setting up a name-based virtual site is easy once you understand the layout a bit. I suggest you scan the file /etc/apache2/README. It's pretty short and clear. For the impatient, here are just the things we are going to touch to get one name-based virtual site up. I'll use "mydomain.com" as the virtual domain in all the examples.

/var/www/
This directory is the document root for the web server. This is where your web sites go.
/var/www/mydomain.com/
A directory you create to contain all files related to the site mydomain.com. This directory is not publicly accessible.
/var/www/mydomain.com/docs/
A directory you create to contain the publicly accessible files for mydomain.com.
/var/www/mydomain.com/docs/index.html
An html file you create to test your configuration.
/etc/apache2/sites-available/mydomain.com
This file you create containing the Apache configuration directives to define the virtual domain mydomain.com. Each file in the sites-available directory defines a different virtual domain.
/etc/apache2/sites-enabled/mydomain.com
This is a symlink you create with the handy little command a2ensite mydomain.com. The presence of a symlink in the sites-enabled directory has the effect of "enabling" a site defined in the sites-available directory.

Setting Up a Web Site

First, create a subdirectory of /var/www/ to contain the site. It makes sense to name this directory after the domain that will live there.

$> mkdir /var/www/mydomain.com

Now create the subdirectory /var/www/mydomain.com/docs/. This will be the only directory that is publicly accessible.

$> mkdir /var/www/mydomain.com/docs

Now create /var/www/mydomain.com/docs/index.html, something simple like the following:



   Mydomain.com test index page


   

Hello World!

Now create /etc/apache2/sites-available/mydomain.com. We use the directive to define the virtual site, and the directive to define the ...xxx/docs/ directory as publicly accessible (Allow from all). Like so:


        #Basic setup
        ServerAdmin webmaster@mydomain.com
        ServerName 
        DocumentRoot /var/www/mydomain.com/docs

        
                Order Deny,Allow
                Allow from all
                # Don't show indexes for directories
                Options -Indexes
        

Now, to enable the site you use the a2ensite command (Note:use a2dissite to disable). The following creates a symlink /etc/apache2/sites-enabled/mydomain.com, which enables the site.

$> a2ensite mydomain.com

You need to reload Apache to see the site...

$> /etc/init.d/apache2 reload

If DNS is working, you should now be able to point your browser at see the index.html page you created above.

Miscellaneous Apache Stuff

There are a few other things I noticed that might be useful to someone. Here they are in no particular order.

  • If you remove or disable the default Apache site, you may find you can only see one virtual site, even though more are enabled. If so, add a line containing NameVirtualHost * to /etc/apache2/conf.d/local_configs.conf, in the main apache config file, or in the /etc/apache2/sites-available/mydomain.com file.
  • Enabling and disabling mods works the same way as enabling and disabling sites. Use the a2enmod and a2dismod utilities to manage the symlinks in the mods-enabled directory that toggle mods on and off. For example, to enable ssl, use the command a2enmod ssl.
  • If you want to enable ssl add the line Listen 443 to /etc/apache2/ports.conf.
  • To create a self-signed cert for use with ssl, you can use the apache2-ssl-certificate command. For example, apache2-ssl-certificate -days 3650 will generate a cert that is good for 10 years.

Installing PHP 5

We need to add one the dotdeb.org mirrors to sources.list for this. The mirrors are listed at . I chose one from Germany by adding the following to /etc/apt/sources.list

# Use dotdeb.org for LAMP related packages not available in Sarge
deb  stable all
deb-src  stable all

Now, thanks to Guillaume Plessis of dotdeb.org, installing PHP5 on Sarge is easy.

$> apt-get update
$> apt-get install libapache2-mod-php5

Security Tweaks for PHP 5

There is a sample php config provided in /usr/share/doc/php5-common/examples/php.ini-recommended. It contains the "warmly recommended" php.ini settings for production servers. I chose to use this config file instead of the installed default. This is a very well commented file and worth the time to read. If you want to use this recommended config instead of the default, first save a copy of the original php.ini file, like so ..

$> mv /etc/php5/apache2/php.ini /etc/php5/apache2/php.ini.original

... and then put the recommended file in place of the original file.

$> cp /usr/share/doc/php5-common/examples/php.ini-recommended \
   /etc/php5/apache2/php.ini

Now, like we did with Apache, let's hide info about our php config by telling PHP to hide itself. Open up php.ini in your favorite editor and set expose_php to off.

expose_php = off

Also, I plan to follow the convention of naming all php include files with the .inc extension. For good measure, I want Apache to hide these by default, so I add this to the /etc/apache2/conf.d/local_configs.conf file I created earlier (this is the same way .htaccess files are protected in the main Apache config file).

# Hide all files with the .inc extension.

    Order allow,deny
    Deny from all

Installing MySQL

Thanks (again) to the dotdeb.org mirror we have already added, this is easy. apt-get will find the latest version there.

$> apt-get install mysql-server

Don't forget to set a password for the MySQL root user. Do the following, replacing "secret" with your chosen password, and make it a good one.

$> /usr/bin/mysqladmin -u root password 'secret'

Note: It would be wise to create a non-root user for MySQL having just the MySQL permissions absolutely necessary to the PHP applications you are going to write. I'm using the root user for the purposes of this howto.

Also grab the php5 mysql extensions from dotdeb.org:

$> apt-get install php5-mysql

Testing MySQL

Let's create a quick database and table to both verify that MySQL is working, and give us something to test ADODB with later. At a command line, login to MySQL.

$> mysql -u root -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1920 to server version: 5.0.18-Debian_3.dotdeb.1-log

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

Now we will, 1) create a database 2) tell MySQL to "use" the database 3) create a table, and 4) insert a couple of records into the table. You should be able to copy and paste these commands at the mysql prompt. BTW, I stole this example out the MySQL Reference Manual.

mysql> CREATE DATABASE mydomain;
Query OK, 1 row affected (0.00 sec)

mysql> USE mydomain;
Database changed

mysql> CREATE TABLE pet (name VARCHAR(20), owner VARCHAR(20), species VARCHAR(20), sex CHAR(1), birth DATE, death DATE);
Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO pet VALUES ('Puffball','Diane','hamster','f','1999-03-30',NULL);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO pet VALUES ('Libby','Diane','dog','f','2001-04-15',NULL);
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM pet;
+----------+-------+---------+------+------------+-------+
| name     | owner | species | sex  | birth      | death |
+----------+-------+---------+------+------------+-------+
| Puffball | Diane | hamster | f    | 1999-03-30 | NULL  |
| Libby    | Diane | dog     | f    | 2001-04-15 | NULL  |
+----------+-------+---------+------+------------+-------+
2 rows in set (0.00 sec)

mysql> quit
Bye

I find the MySQL command line painful. phpMyAdmin makes it a lot easier, so let's install it.

.

First we'll create a directory that's out of the way of Debian's package management system in /usr/local. We'll call it php5 since we'll be putting Smarty and ADODB files here as well.

$> mkdir /usr/local/php5

Now we untar phpMyAdmin in this directory (creates /usr/local/php5/phpMyAdmin-2.7.0-pl2), and remove the tar.gz file.

$> cp phpMyAdmin-2.7.0-pl2.tar.gz /usr/local/php5/
$> cd /usr/local/php5/
$> tar -zxvf phpMyAdmin-2.7.0-pl2.tar.gz
$> rm phpMyAdmin-2.7.0-pl2.tar.gz

Note: I opt to leave the version info in the phpMyAdmin directory name so I can easily untar a new version right next it without blowing anything away.

Configuring phpMyAdmin

The sample config file provided is config.default.php. We need to copy it to config.inc.php.

$> cd /usr/local/php5/phpMyAdmin-2.7.0-pl2/
$> cp config.default.php config.inc.php

Now we need to make a couple of changes to config.inc.php. First, let's define the URI we'll be using to access PhpMyAdmin (this is not the path to the phpMyAdmin directory, but rather the alias we will use for it in the Apache config). Find the following line,

$cfg['PmaAbsoluteUri'] = '';

and change it to something like this.

$cfg['http:///phpmyadmin'] = '';

Next we need to choose an auth type. The three options are 'config', 'http', and 'cookie'. The 'config' option is the default, and requires you to keep your MySQL password right here in this file, which I don't like. The 'http' option prompts you for the password when you access PhpMyAdmin, but will send the password in clear text, which I also don't like. The 'cookie' option is the best I think, and allows you to define a passphrase with the [blowfish_secret] parameter, which phpMyAdmin will use to encrypt the password in a cookie when you log in. To use the 'cookie' auth type, we need to make two changes. First, find the section of the file that looks like this:

/**
 * The 'cookie' auth_type uses blowfish algorithm to encrypt the password. If
 * at least one server configuration uses 'cookie' auth_type, enter here a
 * passphrase that will be used by blowfish. The maximum length seems to be 46
 * characters.
 */
$cfg[''] = '';

You need to change this line ..

$cfg[''] = '';

.. to something like the following. Note that you have to add the "blowfish_secret" part within the brackets (I don't know why). Note also that you will not be prompted for the passphrase you enter here, so feel free to make it a real ugly one.

$cfg['blowfish_secret'] = 'some_passphrase_under_46_characters_long';

Then find this line ..

$cfg['Servers'][$i]['auth_type']     = 'config';

... and change the auth type from 'config' to 'cookie', like so ..

$cfg['Servers'][$i]['auth_type']     = 'cookie';

That's it. Save the file.

Configuring Apache to Display phpMyAdmin

Now we need to tell Apache where phpMyAdmin lives, and also create an Apache alias for the phpMyAdmin directory (so we don't have to remember to type "phpMyAdmin-2.7.0-pl2" into the browser all the time). Also, since I don't want anyone else to even try logging in to phpMyAdmin, I will restrict access to just the IP address of my own workstation. To do all this we just need to add a small section to the file /etc/apache2/sites-available/mydomain.com that we created earlier. Add a section like the following, remebering to change the IP address to something appropriate.

# Provide an alias to phpmyadmin
Alias /phpmyadmin /usr/local/php5/phpMyAdmin-2.7.0-pl2

        # Restrict phpmyadmin access to just my worksation
        Order Deny,Allow
        Deny from all
        Allow from 192.168.1.2

Reload Apache, and you should be able to point your browser at /phpmyadmin and login as the MySQL root user.

About Smarty

Smarty is a template engine for PHP. It allows you to separate your presentation code (html) from the logic (php) in your web applications. If you don't know why this is important to do, then develop a great big web site with a whole bunch of PHP applications, wait long enough to forget how you did everything, and then try to redesign the site. Or, just read Smarty's . They explain it better than I can.

Installing Smarty

As previously noted I could not find a backport for Smarty, so I just downloaded the latest version from . Once you have the tar.gz let's untar it in the /usr/local/php5 directory we created earlier.

$> cp Smarty-2.6.12.tar.gz /usr/local/php5/
$> cd /usr/local/php5/
$> tar -zxvf Smarty-2.6.12.tar.gz
$> rm Smarty-2.6.12.tar.gz

Now edit /etc/php5/apache2/php.ini and add the Smarty /libs subdirectory to the php_include_path, like so:

include_path = ".:/usr/local/php5/Smarty-2.6.12/libs"

Remember, whenever you make a change to php.ini you need to reload Apache.

Now we will create the four directories that Smarty needs to function and set the permissions on them. This is basically right out of the Smarty site's .

cd /var/www/mydomain.com
$> mkdir smarty
$> mkdir smarty/templates
$> mkdir smarty/templates_c
$> mkdir smarty/cache
$> mkdir smarty/configs
$> chown www-data:www-data smarty/templates_c
$> chown www-data:www-data smarty/cache
$> chmod 775 smarty/templates_c
$> chmod 775 smarty/cache

Note: The Smarty documentation says to keep these directories out of the doc root. These are not in our doc root because we defined the doc root for mydomain.com as /var/www/mydomain.com/docs/. It is therefore important to remember not to change the doc root to /var/www/mydomain.com/, which would expose these directories to the world. You can of course put these directories anywhere else you want. My reason for placing them here is that I find it convenient to have just one directory (/var/www/mydomain.com/) containing everything related to the content of a domain.

Testing Smarty

Now let's make a test PHP app. First make a directory for it to live in.

$> mkdir /var/www/mydomain.com/docs/myapp/

Then create a file named index.php in that directory containing the following:

template_dir = '/var/www/mydomain.com/smarty/templates/';
        $smarty->compile_dir = '/var/www//mydomain.com/smarty/templates_c/';
        $smarty->config_dir = '/var/www/mydomain.com/smarty/configs/';
        $smarty->cache_dir = '/var/www/mydomain.com/smarty/cache/';

// Set a smarty variable
$smarty->assign('name', 'Johnny');

// Display the smarty template
$smarty->display('myapp_index.tpl');

?>

Now we need to make a template, called myapp_index.tpl, in the directory /var/www/mydomain.com/templates/. Something like the following:



   Smarty


   Hello, {$name}!


Now you should be able to display this template by pointing your browser at /myapp/ and see Hello, Johnny!

A Smarter Smarty Setup

Now that we know it works, let's make our Smarty setup more flexible. We don't really want to define the smarty directory paths in every PHP script when we could just define them once in an include file. First let's make a new directory for it.

$> mkdir /var/www/mydomain.com/includes/

We also want to add this directory to the include_path in php.ini. Don't forget to reload Apache afterwards.

include_path = ".:/usr/local/php5/Smarty-2.6.12/libs:/var/www/mydomain.com/includes"

Now create the file /var/www/mydomain.com/includes/smarty_setup.inc and define the smarty directories in it.

template_dir = '/var/www/mydomain.com/smarty/templates/';
        $smarty->compile_dir = '/var/www//mydomain.com/smarty/templates_c/';
        $smarty->config_dir = '/var/www/mydomain.com/smarty/configs/';
        $smarty->cache_dir = '/var/www/mydomain.com/smarty/cache/';

?>

With this done, you can simplify /var/www/mydomain.com/myapp/index.php to look like this.

assign('name', 'Johnny');

// Display the smarty template
$smarty->display('myapp_index.tpl');

?>

This is much cleaner looking. More importantly, if there is ever a need to redefine the location of the smarty directories, the only file that will need editing is smarty_setup.inc, not every script ever written. We'll take the same approach with ADODB.

About ADODB

ADODB is a database abstraction class for PHP. It allows you to write PHP scripts that can easily be modified to work with several databases. Using it also has the effect of streamlining your PHP code for databases queries.

Installing ADODB

Installation is straightforward. Just , and untar it in /usr/local/php5 just as we did with Smarty and phpMyAdmin.

$> cp adodb471-1.tgz /usr/local/php5/
$> cd /usr/local/php5/
$> tar -zxvf adodb471-1.tgz
$> rm adodb471-1.tgz

Add the adodb directory to php.ini's include_path, and remember to reload apache when you're done.

include_path = ".:/usr/local/php5/Smarty-2.6.12/libs:/usr/local/php5/adodb:/var/www/mydomain.com/includes"

Like we did for Smarty, we're going to make a setup file for ADODB that we can just include in the PHP scripts that will access the database. We'll call it adodb_setup.inc, and put it in the directory /var/www/mydomain/includes. Make it look like the following, changing "secret" to your MySQL root password, and "mydomain" to the name of your database:


Note: Your MySQL password is right here in this file. Keep this file and the directory it lives in out of the doc root.

All Together Now

Now let's pull all this together. We'll go back to our myapp application and have it use ADODB syntax to make a database query. Then we'll display the results using a Smarty template.

First edit /var/www/mydomain.com/myapp/index.php to look like the following. Note that we are including the file adodb_setup.inc that we just created.

SetFetchMode(ADODB_FETCH_ASSOC);

// Query the pet table and assign the
// result set to the $rs variable
$rs = $db->Execute('select * from pet');

// Pass the result set to smarty
$smarty->assign('rs', $rs);

// Other vars for smarty
$smarty->assign('pg_title', 'MyApp');
$smarty->assign('name', 'Johnny');

// Display the smarty template
$smarty->display('myapp_index.tpl');

?>

Finally, edit the file /var/www/domain.com/smarty/templates/myapp_index.tpl to look something like the following, in which Smarty displays the $pg_title and $name variables passed from the PHP script, and also iterates through the database result set (the $rs variable), drawing an html table along the way.




   {$pg_title}




{$pg_title}

Hello, {$name}.

Results of pet query

{foreach from=$rs item=pet} {if !$pet.death} {else} {/if} {/foreach}
Pet Name Owner Species Gender Birth Death
{$pet.name} {$pet.owner} {$pet.species} {$pet.sex} {$pet.birth}Still kicking{$pet.death}

The resulting html from this should look something like the following:


   MyApp




MyApp

Hello, Johnny.

Results of pet query

Pet Name Owner Species Gender Birth Death
Puffball Dianne hamster f 1999-03-30 Still kicking
Libby Dianne dog f 2001-04-15 Still kicking

Pretty cool eh? Well whether you think that's cool or not, pat yourself on the back for getting this far. My next howto is going to be shorter for sure.

阅读(1239) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~