Ravindra BagaleCourses & study guides मराठी Track your progress

How to Install LAMP Stack on Amazon Linux (EC2)

So far our servers have only sent static files: HTML, CSS and images that look the same for everyone. Most real websites are dynamic: code runs on the server and builds a page for each visitor from a database. In this chapter we install the classic stack for that, LAMP (Linux, Apache, MariaDB, PHP), on an Amazon Linux EC2 server. We see why the browser can't run PHP and how Apache hands it to php-fpm, test the stack with a phpinfo page, turn every command into one automation script, and fix the errors you will meet on the way.

What you'll learn in this class

  • Static vs dynamic websites, with a real example
  • What LAMP and LEMP stand for, and why MariaDB stands in for MySQL
  • Why the browser can't run PHP, and how Apache, php-fpm and MariaDB work together
  • Install httpd, mariadb105-server and php on Amazon Linux, and find package names yourself
  • Start the services, and why you restart them after installing everything
  • Test pages in /var/www/html, with phpinfo() as the baseline
  • Install everything in one line, then automate it with a lamp.sh script (sudo tee, -y, chmod +x)
  • Test from the server itself with curl localhost and service ... status
  • Fix three common problems: port 80 taken, a blank PHP page, PHP shown as text

1. Why: static sites vs dynamic sites

Why. So far every site sent the same files to everyone. Apps like Instagram build a different page for each visitor, and that needs more software on the server.

Classroom line

Let's see how we came here step by step.

Until now we hosted static websites on Apache and Nginx, connected a domain, kept the IP fixed with an Elastic IP and backed the server up with an AMI. The next step is a dynamic website.

What is static? A static site is made only of files the browser understands: HTML, CSS, JavaScript and images. The server just sends the files, and every visitor gets the same page. A web server such as Apache or Nginx is all you need.

What is dynamic? A dynamic site runs server-side code (PHP, Python, Java, Node.js) and reads a database, so it can build a different page for each visitor.

Example 1, step by step. Suppose we are Instagram.

  1. You log in. The server checks your user name and password against the database.
  2. The server-side code looks up who you follow and what you like.
  3. It builds your feed: cricket and food posts for you, travel and music posts for your friend.
  4. Both of you open the same address, but each gets a page that was made just now, just for you.

None of that is possible with fixed HTML files. You need a language that runs on the server, plus a database.

Static site vs dynamic site Static site HTML, CSS, JavaScript and images. The same page for every visitor. The server only sends the files; the browser shows them. Apache or Nginx alone is enough. index.html Dynamic site Server-side code (PHP, Python, Java, Node.js) plus a database. The page is built for each visitor, like your Instagram feed. User A cricket, food posts User B travel, music posts

Figure 1. A static site sends the same files to everyone. A dynamic site runs server-side code and a database to build each visitor's page, like an Instagram feed.

2. What: LAMP and LEMP

Why. Job posts and tutorials say LAMP and LEMP without explaining them. Knowing the four letters tells you exactly what to install.

A stack is a set of software that works together to run a website. Two classic stacks for PHP websites:

  1. LAMP = Linux + Apache + MySQL or MariaDB + PHP.
  2. LEMP = Linux + Nginx (said "Engine-x", hence the E) + MySQL or MariaDB + PHP.

The only difference is the web server. In this chapter we build LAMP on Amazon Linux; Ubuntu and LEMP come next.

Why MariaDB? MariaDB is a community fork of MySQL, started by MySQL's original developers. It works as a drop-in replacement: the same commands and the same SQL, so a PHP app written for MySQL runs on it. Amazon Linux offers MariaDB in its own repositories, so that's what we install.

Why PHP? It's open source and runs a large share of the web, including WordPress sites. The same idea works with Python, Java or Node.js; only the "P" changes.

Classroom line

Always work on open-source languages and databases.

LAMP vs LEMP LAMP (this chapter) LEMP L Linux: the operating system L Linux: the operating system A Apache (package httpd) E Nginx, said "engine-x" M MySQL or MariaDB: the database M MySQL or MariaDB: the database P PHP, run by php-fpm P PHP, run by php-fpm Only the web server changes. MariaDB is a communityfork of MySQL and a drop-in replacement.

Figure 2. LAMP and LEMP differ only in the web server: Apache or Nginx. MariaDB is a drop-in replacement for MySQL.

3. Why the browser can't run PHP

Why. A browser understands only HTML, CSS and JavaScript. If a web server sends a .php file as it is, the browser doesn't know what to do with it: it shows the code as text or simply downloads the file. Your PHP never runs.

Classroom line

The page will just download here; it won't run.

What fixes it: php-fpm. php-fpm (PHP FastCGI Process Manager) is a service that runs PHP code for the web server. Apache doesn't run PHP itself; it passes .php requests to php-fpm and sends back what php-fpm returns.

Example 2, step by step: opening http://PUBLIC_IP/index.php

  1. The browser sends a request to the server on port 80.
  2. Apache receives it and sees the file ends in .php.
  3. Apache hands the request to php-fpm.
  4. php-fpm runs the PHP code. If the code needs data (a login, a feed), it asks MariaDB.
  5. The output of the code is plain HTML. php-fpm gives it back to Apache.
  6. Apache sends that HTML to the browser. The browser never sees a line of PHP.

For index.html the path is shorter: Apache sends the file itself, and php-fpm isn't involved.

What happens when you open index.php Browser understands HTML, CSS, JS; not PHP 1. The browser asks for /index.php on port 80. GET Apache (httpd) port 80 serves the files 2. Apache sees .php and hands the request to php-fpm. .php php-fpm runs the PHP code 3. php-fpm runs the PHP code, which can ask MariaDB for data. MariaDB the data HTML Apache (httpd) 4. php-fpm gives the output, plain HTML, back to Apache. HTML Browser 5. Apache sends the HTML to the browser. The browser neversees PHP. index.html is different: Apache sends the file itself, php-fpm is not needed.

Figure 3. Animation: the browser asks for index.php, Apache hands it to php-fpm, php-fpm runs the code (with MariaDB if needed) and returns HTML, and Apache sends the HTML to the browser.

Classroom line

Why php-fpm? We use it to run PHP and give back HTML.

4. How: install Apache, MariaDB and PHP

Why. A dynamic site needs all three pieces: a web server, a database and a language runtime. Missing one gives a blank page or a downloaded .php file.

Launch an Amazon Linux EC2 server with a security group that allows SSH (22) from your IP and HTTP (80). Connect with SSH, then install the three packages one by one.

Step 1. Apache. On Amazon Linux the Apache package is called httpd.

sudo yum install httpd -y

Step 2. MariaDB.

sudo yum install mariadb105-server -y

Why -server? The package mariadb105 alone gives you only the client, the mysql command that connects to a database somewhere else. The -server package installs the database server itself, the service that stores the data. A website needs the server. (105 is the MariaDB version, 10.5.)

Step 3. PHP.

sudo yum install php -y

This installs the PHP version Amazon Linux currently offers, together with php-fpm.

How do I find a package name? You don't have to remember them.

  1. Guess first. The package usually has the same name as the software, for example php.
  2. Tab completion. Type sudo yum install mariadb and press Tab twice. The shell lists the matching packages, such as mariadb105 and mariadb105-server.
  3. Search. Run sudo yum search php (or sudo yum search mariadb) to list every package with that word.

Classroom line

Just guess; usually the package has the same name as the software.

5. Start the services, then restart once everything is installed

Why. Installed software does nothing until it runs. The restart at the end makes Apache pick up PHP, which was installed after Apache started.

Step 1. Start each service.

sudo service httpd start
sudo service mariadb start
sudo service php-fpm start

On Amazon Linux, service passes the job to systemctl; you'll see a line like Redirecting to /bin/systemctl start httpd.service.

Step 2. Restart after everything is installed.

sudo service php-fpm restart
sudo service mariadb restart
sudo service httpd restart

Why restart? If you installed and started Apache before PHP, Apache read its configuration at a time when PHP's settings file (/etc/httpd/conf.d/php.conf, the rule that sends .php to php-fpm) didn't exist yet. Apache reads that folder only when it starts. A restart makes it load the PHP rule. Restart php-fpm first, then Apache last.

Install, start, then restart 1. Install sudo yum install httpd -y sudo yum install mariadb105-server -y sudo yum install php -y httpd is the Apache package. -server: the database server itself, not only the client. 2. Start sudo service httpd start sudo service mariadb start sudo service php-fpm start Start each service. On Amazon Linux, service passes the job tosystemctl. 3. Restart after everything is installed sudo service php-fpm restart sudo service mariadb restart sudo service httpd restart Apache read its config when it started, before PHP's config fileexisted. A restart makes it load it.

Figure 4. Install the three packages, start the three services, then restart them once everything is installed so Apache loads PHP's config.

Ravindra Bagale's Tip

service ... start starts a service only now. To have the stack come back after a reboot (or on a server launched from your AMI), also run sudo systemctl enable httpd mariadb php-fpm.

6. Test pages: index.html and a phpinfo() page

Why. Two tiny pages separate the problems: if index.html works and index.php doesn't, Apache is fine and PHP is the issue.

Apache's web root on Amazon Linux is /var/www/html. Create one HTML page and one PHP page there.

Step 1. Go to the web root:

cd /var/www/html

Step 2. Create an HTML test page (the folder belongs to root, so use sudo):

sudo nano index.html

Type html page, save with Ctrl+O, Enter, and exit with Ctrl+X.

Step 3. Create a PHP test page:

sudo nano index.php

Type exactly this line, with a space after <?php:

<?php phpinfo(); ?>

Step 4. In the browser, open http://PUBLIC_IP/index.html. You see html page. Apache works.

Step 5. Open http://PUBLIC_IP/index.php. You see the PHP information page: the PHP version, and Server API: FPM/FastCGI, which proves Apache is handing PHP to php-fpm.

Browser showing the PHP information page: a blue header PHP Version 8.5.9 with the PHP logo, then a table with System (host name hidden), Build Date (hidden), Build System Linux, Build Provider Amazon Linux, Compiler gcc, Architecture x86_64 and Server API FPM/FastCGI.

Whiteboard: The phpinfo() page: the PHP version at the top, and Server API FPM/FastCGI, so Apache is handing PHP to php-fpm.

Why phpinfo first? It's the baseline test. If phpinfo() works, Linux, Apache, php-fpm and PHP are all fine. When a real application fails after that, the problem is in the application (for example, it was written for an older PHP version), not in the server. Without this test, everyone blames the server.

Classroom line

"My project worked on my laptop... your server has a problem." (That's what you'll hear, so test with phpinfo first.)

7. Install everything in one line

Why. Fewer commands means fewer chances to forget one, and it is the first step towards the script in the next section.

yum install takes several package names at once, so steps 1 to 3 of section 4 become one command:

sudo yum install httpd mariadb105-server php -y

The start commands can share a line too, separated by ;:

sudo service mariadb start; sudo service php-fpm start; sudo service httpd start

8. Automate it: the lamp.sh script

Why. You will build this stack again and again: for practice, for every new project, for every new server. Typing ten commands each time is slow and easy to get wrong. Put them in a shell script and run one file.

8.1 A script can't use nano: write files with sudo tee

In section 6 we typed the test pages in nano. A script can't type into nano; it needs commands that write files by themselves. The first idea is a redirect:

sudo echo "html page" > index.html

This fails with Permission denied. Why? sudo runs only echo as root. The > redirect is done by your own shell, as ec2-user, before sudo even starts, and ec2-user can't write in /var/www/html.

The fix is tee. tee reads text from a pipe and writes it to a file, and it can run as root:

echo "html page" | sudo tee index.html
  1. echo prints the text.
  2. The pipe | hands it to tee.
  3. sudo tee index.html runs as root and writes the file. (It also prints the text on screen; add > /dev/null at the end if you want it quiet.)

tee overwrites the file. To add a line at the end instead, use tee -a:

echo "second line" | sudo tee -a index.html

Classroom line

Add -a and it appends to the file.

Writing a root-owned file from a script sudo echo "hi" > index.html Permission denied sudo runs only echo as root. The redirect is done by your own shell, as ec2-user, and ec2-user cannot write in /var/www/html. echo "hi" | sudo tee index.html Works echo prints the text; the pipe | gives it to tee, which runs as root and writes the file. sudo tee -a file appends instead of overwriting.

Figure 5. sudo echo with > fails because your own shell does the redirect; echo piped to sudo tee works because tee runs as root. tee -a appends.

8.2 Write the script

Step 1. Go to your home folder and open a new file:

cd ~
nano lamp.sh

Step 2. Type the script:

#!/bin/bash
sudo yum update -y
sudo yum install httpd mariadb105-server php -y
sudo service mariadb start
sudo service php-fpm start
sudo service httpd restart
cd /var/www/html
sudo touch index.html index.php
echo "html page" | sudo tee index.html
echo "<?php phpinfo(); ?>" | sudo tee index.php

Save and exit (Ctrl+O, Enter, Ctrl+X).

What each part does:

  1. #!/bin/bash says which program runs the script.
  2. sudo yum update -y updates all installed packages first. Start every automation script this way, so you build on current software. (On Ubuntu the pair is sudo apt-get update, which refreshes the package list, then sudo apt-get upgrade -y.)
  3. The one-line install from section 7.
  4. MariaDB and php-fpm start first, and Apache is restarted last, so it always loads PHP's config. restart also starts a service that isn't running, so the script is safe to run again.
  5. cd /var/www/html moves into the web root.
  6. sudo touch creates two empty files (tee would create them anyway).
  7. The two tee lines write the test pages as root, with the correct <?php phpinfo(); ?>.

Why -y everywhere? Without -y, yum stops and asks Is this ok [y/N]:. Nobody is there to answer, so the script waits forever.

Classroom line

At the start of any automation, update the packages first.

Classroom line

If you don't add -y, the script gets stuck in the middle.

Why the home folder, not /var/www/html? Everything in the web root can be opened from a browser. If lamp.sh sat there, anyone could type http://PUBLIC_IP/lamp.sh and read your script. Keep scripts in ~ (here /home/ec2-user).

Classroom line

Don't keep lamp.sh in the html folder; anyone typing its URL could see it.

Inside lamp.sh #!/bin/bash Run it with bash. sudo yum update -y Update first; -y on every install. sudo yum install httpd mariadb105-server php -y All three packages in one line. sudo service mariadb start sudo service php-fpm start sudo service httpd restart Start the database and php-fpm, then (re)start Apache last. cd /var/www/html Go to the web root. sudo touch index.html index.php Create two empty files. echo "html page" | sudo tee index.html echo "<?php phpinfo(); ?>" | sudo tee index.php Write them as root with tee. Save it as ~/lamp.sh, not in /var/www/html. Then: chmod +x lamp.shand ./lamp.sh

Figure 6. Inside lamp.sh: update first, install in one line with -y, start the database and php-fpm, restart Apache last, then write the test pages with sudo tee. Keep it in your home folder.

8.3 Make it executable and run it

Step 1. Give the file execute permission:

chmod +x lamp.sh

Step 2. Run it from the home folder:

./lamp.sh

(bash lamp.sh also works, even without chmod +x.)

Step 3. Watch the output. The packages install, the services start, and the two tee lines echo your page contents. If it stops with an error, the usual causes are a missing sudo, a typo in a package name, or running it from the wrong folder.

Example 3: the whole thing on a fresh server.

  1. Launch a new Amazon Linux server (HTTP and SSH allowed) and connect.
  2. nano lamp.sh, paste the script, save.
  3. chmod +x lamp.sh, then ./lamp.sh.
  4. Open http://PUBLIC_IP/index.php. The phpinfo page appears. A full LAMP server in a few minutes, with no typing mistakes.

9. Test from the server itself: curl and status

Why. You can't always open a browser, for example inside a script or when the security group isn't ready. curl and status check the stack from inside.

You don't always need a browser. From the SSH session:

Step 1. Ask Apache for the HTML page:

curl http://localhost/index.html

It prints html page.

Step 2. Ask for the PHP page:

curl http://localhost/index.php

It prints a long HTML page that contains PHP Version. If you see the raw <?php phpinfo(); ?> line instead, PHP isn't running (section 10.3).

Step 3. Check each service:

sudo service httpd status
sudo service mariadb status
sudo service php-fpm status

Look for active (running) in green. Press q to leave the status screen.

localhost tests the server from the inside. If curl localhost works but the browser doesn't, check the security group allows HTTP (80) and that you used http://, not https://.

10. Troubleshooting: three problems you will meet

Three common LAMP problems Symptom httpd will not start: "Job for httpd.service failed" Cause Port 80 is already taken, e.g. Nginx is still running. Fix sudo service nginx stop   sudo service httpd start Symptom index.html works, index.php is blank. Cause Typo: no space after the tag.   <?phpphpinfo(); ?> Fix View Source, then fix:   <?php phpinfo(); ?> Symptom The PHP code shows as text or downloads. Cause Apache is not handing .php files to php-fpm. Fix sudo service php-fpm restart   sudo service httpd restart

Figure 7. Three common problems: port 80 taken, a blank PHP page from a typo, and PHP shown as text because Apache isn't handing it to php-fpm.

10.1 Apache won't start: port 80 is already taken

Symptom. sudo service httpd start prints in red: Job for httpd.service failed because the control process exited with error code.

Terminal: httpd, mariadb105-server and php8.5 are already installed; Redirecting to /bin/systemctl start httpd.service, then in red Job for httpd.service failed because the control process exited with error code, see systemctl status httpd.service and journalctl -xeu httpd.service for details; then mariadb.service and php-fpm.service start.

Whiteboard: Apache fails to start because another web server already holds port 80; MariaDB and php-fpm start fine.

Cause. Only one program can listen on port 80. On this server, Nginx from an earlier lab was still running and held the port.

Fix, step by step:

  1. Read the details: sudo systemctl status httpd. Look for Address already in use.
  2. See who holds port 80: sudo ss -tlnp | grep :80. It shows nginx.
  3. Stop the other web server: sudo service nginx stop.
  4. Start Apache again: sudo service httpd start.
  5. To keep Nginx from taking the port at the next boot: sudo systemctl disable nginx.

10.2 index.php shows a blank page

Symptom. index.html works, but index.php shows an empty white page.

Fix, step by step:

  1. Right-click the page, View Page Source.
  2. The source shows the PHP line itself, for example <?phpphpinfo(); ?>. PHP code reached the browser, so it was never run.
  3. Spot the typo: there is no space after <?php. PHP only recognises its opening tag <?php when a space or a new line follows it, so it treated the whole line as plain text, and the browser hid it as an unknown tag.
  4. Fix the file: echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/index.php
  5. Refresh. The phpinfo page appears.

Lesson: when a page is blank, View Source first. It shows what the server really sent.

10.3 The PHP code is shown as text (or downloads)

Symptom. http://PUBLIC_IP/index.php shows <?php phpinfo(); ?> on the screen, or the browser downloads the file. curl localhost/index.php prints the same raw line.

Cause. Apache is sending the .php file as it is, instead of handing it to php-fpm. Usually php-fpm isn't running, or Apache was started before PHP was installed and never loaded PHP's config.

Fix on Amazon Linux:

  1. Check php-fpm: sudo service php-fpm status. If it isn't installed, sudo yum install php -y.
  2. Restart php-fpm, then Apache, in that order:

    sudo service php-fpm restart
    sudo service httpd restart
    
  3. Refresh with Ctrl+F5 (the browser may have cached the old answer).

On Ubuntu (a different OS)

On Ubuntu, Apache is the apache2 package, and the PHP hand-off must be switched on with Ubuntu's own tools. These commands are Ubuntu only; they don't exist on Amazon Linux.

sudo a2enmod proxy_fcgi setenvif
sudo a2enconf php8.x-fpm
sudo service apache2 restart

Replace php8.x-fpm with your installed version (for example php8.3-fpm; ls /etc/apache2/conf-available shows it). We set up Ubuntu LAMP and LEMP in the next chapter.

Tip: if you are stuck, describe the exact symptom ("index.html works, index.php shows the code") and paste your script into a search engine or an AI assistant. A precise symptom gets a precise answer.

11. Clean up: stop what you don't use

Why. A LAMP server runs a database and three services all day. Stopping it when you finish saves free-tier hours.

A running instance costs money every hour, even if nobody visits it.

  1. In the EC2 console, check the region selector at the top. A server you launched in another region doesn't show in this list; switch regions to find it.
  2. Select every test server you no longer need, Instance state > Stop instance.
  3. Terminate servers you'll never use again (after making an AMI if you want to keep the set-up).

12. The whole flow on one page

  1. Static = same files for everyone; dynamic = server-side code + database, a page per visitor.
  2. LAMP = Linux, Apache, MySQL/MariaDB, PHP. LEMP swaps Apache for Nginx.
  3. The browser can't run PHP: Apache hands .php to php-fpm, which returns HTML.
  4. sudo yum install httpd mariadb105-server php -y (-server = the database server itself).
  5. Start httpd, mariadb, php-fpm; restart after installing everything (php-fpm first, Apache last).
  6. Test with index.html and <?php phpinfo(); ?> in /var/www/html.
  7. Automate in ~/lamp.sh: update first, -y everywhere, write files with echo ... | sudo tee.
  8. chmod +x lamp.sh, ./lamp.sh, then curl localhost and service ... status.
  9. Port 80 taken: stop Nginx. Blank page: View Source, fix the typo. PHP as text: restart php-fpm, then httpd.
  10. Stop servers you don't use.

13. Hands-on lab: build and test a LAMP server

Why this lab. A dynamic site breaks in more places than a static one. This lab installs the stack, starts each service, and tests HTML and PHP separately, so you know which piece to blame when something fails.

  1. Install all three in one line
    • Command: sudo yum install httpd mariadb105-server php -y
    • You should see: Download lines, then Complete!.
    • Check: httpd -v, mysql --version and php -v each print a version.
    • Why: yum takes several packages at once. mariadb105-server is the MariaDB server package on Amazon Linux 2023; php brings php-fpm with it.
  2. Start the services
    • Command: sudo service mariadb start; sudo service php-fpm start; sudo service httpd restart
    • You should see: Three Redirecting to /bin/systemctl ... lines.
    • Check: sudo service httpd status shows active (running); the same for mariadb and php-fpm.
    • Why: Database and PHP first, Apache last, so Apache connects to a PHP that is already running.
  3. Make them start at boot
    • Command: sudo systemctl enable httpd mariadb php-fpm
    • You should see: Three Created symlink ... lines.
    • Check: systemctl is-enabled httpd mariadb php-fpm prints enabled three times.
    • Why: start lasts until the next reboot. Without enable, the site is down after every stop and start.
  4. Write an HTML test page
    • Command: echo "<h1>HTML works</h1>" | sudo tee /var/www/html/index.html
    • You should see: <h1>HTML works</h1>
    • Check: curl http://localhost → <h1>HTML works</h1>
    • Why: sudo echo ... > file fails, because the redirect runs as ec2-user. Piping into sudo tee writes as root.
  5. Write a PHP test page
    • Command: echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/index.php
    • You should see: <?php phpinfo(); ?>
    • Check: curl -s http://localhost/index.php | grep -m1 "PHP Version" prints a line with the PHP version.
    • Why: If you get the raw <?php text back instead, PHP isn't running: start php-fpm and restart Apache.
  6. Open both pages in the browser
    • Do: Allow HTTP (80) in the security group, then open http://PUBLIC_IP/ and http://PUBLIC_IP/index.php.
    • You should see: HTML works, then the purple-and-grey PHP information page.
    • Check: The PHP page lists Server API: FPM/FastCGI.
    • Why: The browser test proves the outside path works too. FPM/FastCGI shows Apache hands PHP to php-fpm, as in the diagram above.
  7. Remove phpinfo and stop
    • Command: sudo rm /var/www/html/index.php
    • You should see: Nothing.
    • Check: http://PUBLIC_IP/index.php now gives 404. Stop the instance.
    • Why: phpinfo() shows your server's versions and paths to anyone, which helps attackers. Delete it once the test passes.

14. Try at home

Try at home

Task 1: LAMP by hand

  1. Launch an Amazon Linux server with SSH and HTTP allowed.
  2. Install httpd, mariadb105-server and php one by one, and start the three services.
  3. Restart them (php-fpm first, httpd last).
  4. Create index.html and index.php with <?php phpinfo(); ?>, and open both in the browser. Find Server API on the phpinfo page.

Task 2: LAMP with one script

  1. Launch a fresh server. In your home folder, write lamp.sh from section 8.2.
  2. chmod +x lamp.sh, run ./lamp.sh, and test with curl http://localhost/index.php.
  3. Add a line to index.html with tee -a, and check it with curl.
  4. Break it on purpose: remove the space in <?php phpinfo(); ?>, see the blank page, use View Source, and fix it.
  5. Bonus: install and start Nginx, then try sudo service httpd restart. Read the error, and fix it.
  6. Stop or terminate both servers when you're done.

Recap

In short

  1. A static site sends the same files to everyone; a dynamic site runs server-side code and a database to build each visitor's page.
  2. LAMP = Linux, Apache, MySQL or MariaDB, PHP; LEMP uses Nginx ("engine-x") instead of Apache. MariaDB is a drop-in fork of MySQL.
  3. Browsers can't run PHP. Apache hands .php to php-fpm, which runs it and returns HTML.
  4. On Amazon Linux: sudo yum install httpd mariadb105-server php -y; -server installs the database server, not only the client. Find names by guessing, Tab, or yum search.
  5. Start the services with sudo service ... start, and restart once everything is installed so Apache loads PHP's config.
  6. phpinfo() in /var/www/html is the baseline test; Server API FPM/FastCGI means PHP works.
  7. Automate in ~/lamp.sh: yum update -y first, -y everywhere, echo ... | sudo tee (a > redirect after sudo runs as you), tee -a to append; chmod +x, then ./lamp.sh.
  8. Port 80 taken: stop the other server. Blank page: View Source for typos. PHP shown as text: restart php-fpm, then httpd. On Ubuntu: a2enmod proxy_fcgi setenvif and a2enconf php8.x-fpm.

Practice Tasks

About this scenario

Zurich Insurance Partners is a insurance business in Zurich. Anna Müller looks after its IT and cloud work. They count money in CHF and run their AWS resources in the eu-central-2 Region. In the tasks below you do real jobs for them using what this lesson teaches. All names, account IDs, IP addresses and numbers are made up for practice.

0 / 12

Easy Install a package on Ubuntu

Why: Ubuntu uses apt. Package names differ: on Ubuntu Apache is apache2.

What to do: Install the apache2 package on Ubuntu without being asked to confirm.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Install a package on Amazon Linux

Why: dnf is the package manager on Amazon Linux 2023. -y answers yes for you.

What to do: Install the httpd package on Amazon Linux 2023 without being asked to confirm.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Restart a service after a change

Why: Config changes only apply after the service restarts or reloads.

What to do: Restart the nginx service.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Check if a service is running

Why: When a site is down, first check whether the web server process is running.

What to do: Show the status of the httpd service.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Log in to MariaDB

Why: The mysql client lets you run SQL on the database server.

What to do: Open the MariaDB client as user root and ask for the password.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Easy Biggest orders first

Why: Querying the database is daily work after you set up RDS.

What to do: Show order id and amount, biggest amount first.

Tables: customers(id, name, city) and orders(id, customer_id, amount, odate).

How:
  1. Find the table the task is about (see the table list above the box).
  2. Write the SQL statement step by step: what, from where, which rows.
  3. End the statement with ;
  4. Click Check answer. Your query runs on a practice copy of the table.

Easy Filter customers by city

Why: Querying the database is daily work after you set up RDS.

What to do: List the names of customers in Pune.

Tables: customers(id, name, city) and orders(id, customer_id, amount, odate).

How:
  1. Find the table the task is about (see the table list above the box).
  2. Write the SQL statement step by step: what, from where, which rows.
  3. End the statement with ;
  4. Click Check answer. Your query runs on a practice copy of the table.

Medium Start a service now and at boot

Why: enable makes it start after reboot; --now also starts it right away.

What to do: Enable the nginx service and start it immediately, in one command.

How:
  1. Find the Linux command that does this job.
  2. Add the options (like -r or -h) the task needs.
  3. Add the file names, folders or users in the right order.
  4. Use sudo if the job changes system files or users. Click Check answer.

Medium Remove small orders

Why: Querying the database is daily work after you set up RDS.

What to do: Delete orders with amount below 200.

Tables: customers(id, name, city) and orders(id, customer_id, amount, odate).

How:
  1. Find the table the task is about (see the table list above the box).
  2. Write the SQL statement step by step: what, from where, which rows.
  3. End the statement with ;
  4. Click Check answer. Your query runs on a practice copy of the table.

Medium Orders with customer names

Why: Querying the database is daily work after you set up RDS.

What to do: Show each customer name with each order amount.

Tables: customers(id, name, city) and orders(id, customer_id, amount, odate).

How:
  1. Find the table the task is about (see the table list above the box).
  2. Write the SQL statement step by step: what, from where, which rows.
  3. End the statement with ;
  4. Click Check answer. Your query runs on a practice copy of the table.

Hard Sales per customer

Why: Querying the database is daily work after you set up RDS.

What to do: Show customer_id and total amount per customer, only where total is above 1000.

Tables: customers(id, name, city) and orders(id, customer_id, amount, odate).

How:
  1. Find the table the task is about (see the table list above the box).
  2. Write the SQL statement step by step: what, from where, which rows.
  3. End the statement with ;
  4. Click Check answer. Your query runs on a practice copy of the table.

Hard Customers with no orders

Why: Querying the database is daily work after you set up RDS.

What to do: List names of customers who have never ordered.

Tables: customers(id, name, city) and orders(id, customer_id, amount, odate).

How:
  1. Find the table the task is about (see the table list above the box).
  2. Write the SQL statement step by step: what, from where, which rows.
  3. End the statement with ;
  4. Click Check answer. Your query runs on a practice copy of the table.

Quick revision cards

Revise this lesson in two minutes. Save the cards on your phone or download them as PNG files. The QR code on each card opens its lesson.

Comparison card: LAMP vs LEMP. LAMP: Linux + Apache + MySQL/MariaDB + PHP. LEMP: Linux + Nginx ('engine-x') + MySQL/MariaDB + PHP.
Comparison: LAMP vs LEMP · Download PNG
Revision card: What is the LAMP stack?. A dynamic site needs a web server, a language and a database working together. LAMP = Linux, Apache, MariaDB/MySQL, PHP. LEMP swaps Apache for Nginx (Engine-x). Install all three on Amazon Linux in one line, then start them. One line:
Revision card: What is the LAMP stack? · Download PNG
Revision card: Why the browser cannot run PHP. PHP code in the browser would show your passwords and logic. PHP runs on the server. Apache passes .php to php-fpm, which returns plain HTML. Start php-fpm with Apache. View Page Source shows HTML, never PHP.  arrives in the browser as:
Revision card: Why the browser cannot run PHP · Download PNG
Revision card: Test PHP with phpinfo(). Before building an app, prove PHP works. phpinfo() prints a page with the PHP version and loaded modules. Create info.php, open it, then delete it (it reveals server details). File /var/www/html/info.php:
Revision card: Test PHP with phpinfo() · Download PNG
Revision card: Automate setup with lamp.sh. Typing the same install on every server is slow and you forget steps. A shell script is a file of commands that runs top to bottom. -y answers yes. Write it, make it executable, run it. Inside lamp.sh:
Revision card: Automate setup with lamp.sh · Download PNG
Interview card: What does each part of LAMP do?. Linux runs everything, Apache serves pages, MariaDB stores data, PHP builds pages. Each layer can be swapped, like Nginx for Apache (LEMP). Login page: Apache › PHP › SELECT from MariaDB › HTML.
Interview card: What does each part of LAMP do? · Download PNG
Interview card: PHP code shows as text in the browser. Why?. PHP or php-fpm is not installed or not connected to the web server. Without it, the server returns the file contents. Install, then restart both:
Interview card: PHP code shows as text in the browser. Why? · Download PNG
Interview card: Apache fails with "Address already in use". Why?. Another program, usually Nginx, already listens on port 80. Only one program can own a port. Find and stop it:
Interview card: Apache fails with "Address already in use". Why? · Download PNG
Interview card: Why does Amazon Linux use MariaDB for MySQL?. MariaDB is an open-source fork of MySQL that ships in its repos. It speaks the same SQL and commands, so apps work unchanged. Package:
Interview card: Why does Amazon Linux use MariaDB for MySQL? · Download PNG

More cards: Ravi Sir's Cards.