Install LAMP Stack on RHEL 9 | CentOS 9 Using Podman

Install LAMP Stack on RHEL 9 | CentOS 9 Using Podman

Learn how to install the LAMP stack on RHEL 9 | CentOS 9 using Podman with our comprehensive guide. Follow step-by-step instructions to set up Apache, MySQL, and PHP in a containerized environment for enhanced performance and security. Perfect for developers and system administrators!

Table of Contents

Introduction

If you’re looking to set up a robust web development environment on RHEL 9 or CentOS 9, installing the LAMP stack using Podman is an efficient and containerized approach. In this comprehensive guide, we’ll walk through the steps to install and configure the LAMP stack—Linux, Apache, MySQL (PostgreSQL in our case), and PHP—using Podman. By following these steps, you’ll be able to create a portable and scalable web application setup.

What is Podman?

Podman is a container management tool that allows you to run containers without needing a daemon. It’s particularly popular in environments that prefer lightweight and secure applications. Unlike Docker, Podman doesn’t require root privileges to run containers, making it a great choice for many Linux users.

What You’ll Need

Before you begin, ensure you have:

  • RHEL 9 or CentOS 9 installed
  • Podman installed (You can install it via your package manager)
  • Basic knowledge of command-line interface (CLI)

Why Use Podman for LAMP Stack?

FeatureDescription
DaemonlessRuns containers directly as a non-root user.
CompatibilitySimilar command structure to Docker.
Easy ManagementSimplifies the management of containers and pods.

Install LAMP Stack on RHEL 9 | CentOS 9 Using Podman

Step 1: Create a Pod

First, we need to create a pod to host our LAMP stack containers. If the pod doesn’t already exist, you can create it with the following command:

				
					podman pod create --name my-lamp-pod -p 9601:443 -p 5432:5432
				
			

Note: Mapping the HTTPS port 443 to 9601 (using the notation 9601:443) is just an example for this demonstration. You can map it to 443:443 or any port number within the available range of 1025 to 65535 that suits your needs.

Command [podman pod create]: Breakdown

OptionDescription
pod createCommand to create a new pod.
--name my-lamp-podSets the name of the pod.
-p 9601:443Maps port 443 (HTTPS) to host port 9601.
-p 5432:5432Maps PostgreSQL port 5432 for database access.

Step 2: Build a LAMP stack image

1.) First, open a Containerfile:

				
					vim Containerfile
				
			

2.) Copy and paste the following into the file:

				
					# Use a UBI/RHEL 9 base image
FROM registry.access.redhat.com/ubi9/ubi

# Install Nginx and PHP-FPM
RUN dnf install -y \
    nginx \
    php \
    php-fpm \
    php-mysqlnd \
    && dnf clean all

# Create the PHP-FPM socket directory
RUN mkdir -p /run/php-fpm && \
    chown -R nginx:nginx /run/php-fpm

# Copy custom Nginx configuration
COPY nginx.conf /etc/nginx/nginx.conf

# Copy SSL certificates (if needed)
COPY server.crt /etc/ssl/certs/server.crt
COPY server.key /etc/ssl/private/server.key

# Set permissions
RUN chown -R nginx:nginx /usr/share/nginx/html && \
    chmod -R 755 /usr/share/nginx/html

# Expose ports
EXPOSE 80
EXPOSE 443

# Start both Nginx and PHP-FPM
CMD ["sh", "-c", "php-fpm & nginx -g 'daemon off;'"]

				
			

File [Containerfile]: Breakdown

StepCommandPurpose
1FROM registry.access.redhat.com/ubi9/ubiUse a Universal Base Image (UBI) from Red Hat, specifically version 9.
2RUN dnf install -y \ nginx \ php \ php-fpm \ php-mysqlnd \ && dnf clean allInstall Nginx, PHP, PHP-FPM, and MySQL native driver, then clean up.
3RUN mkdir -p /run/php-fpm && chown -R nginx:nginx /run/php-fpmCreate PHP-FPM socket directory and change ownership to the nginx user.
4COPY nginx.conf /etc/nginx/nginx.confCopy custom Nginx configuration file into the container.
5COPY server.crt /etc/ssl/certs/server.crtCopy SSL certificate into the container.
5COPY server.key /etc/ssl/private/server.keyCopy SSL key into the container.
6RUN chown -R nginx:nginx /usr/share/nginx/html && chmod -R 755 /usr/share/nginx/htmlChange ownership and set permissions for the Nginx HTML directory.
7EXPOSE 80Declare that the container listens on port 80 (HTTP).
7EXPOSE 443Declare that the container listens on port 443 (HTTPS).
8CMD ["sh", "-c", "php-fpm & nginx -g 'daemon off;'"]Start PHP-FPM in the background and Nginx in the foreground.

3.) Build the LAMP stack image (called lampstack in this example) with the following command:

				
					podman build -t lampstack .
				
			

Run podman images command to verify:

				
					podman images
				
			
				
					REPOSITORY                                      TAG                    IMAGE ID      CREATED      SIZE
localhost/lampstack                             latest                 a6005d6b66d2  5 mins ago   345 MB

				
			

Step 3: Run the Application Container

Next, let’s deploy the Apache and PHP application container. We’ll mount a directory from the host to the container to serve the web application files.

				
					podman run -d --pod my-lamp-pod --name my-web-container -v /path/to/directory:/var/www/html lampstack:latest
				
			

Command [podman run]: Breakdown

OptionDescription
podman run -dRuns the container in detached mode.
--pod my-lamp-podConnects the container to the specified pod.
--name my-web-containerAssigns a name to the container.
-v /path/to/directory:/var/www/htmlBinds the specified directory to the container.

Configuring Apache and PHP

Ensure you have an index.php file in the /path/to/directory to test your setup (copy and paste the following line to the index.php file):

				
					<?php phpinfo(); ?>
				
			
Install LAMP Stack on RHEL 9 | CentOS 9 Using Podman

Photo by admingeek from Infotechys

You can place this file in your mounted directory to see if Apache serves it correctly.

Step 4: Run the PostgreSQL Container

Now, we need to run the PostgreSQL container. We will configure it with a user, password, and database:

				
					podman run -d --rm --pod my-lamp-pod --name my-db-container -e POSTGRES_USER=testuser -e POSTGRES_PASSWORD=pgpass_test_123 -e POSTGRES_DATABASE=login -v /path/to/directory/pgdata:/var/lib/postgresql/data:Z docker.io/postgres
				
			

Replace the POSTGRES variable names with your chosen names, such as DATABASE and USER.

Command [podman run]: Breakdown

OptionDescription
--rmAutomatically removes the container when stopped.
--name my-db-containerAssigns a name to the PostgreSQL container.
-e POSTGRES_USER=testuserSets the PostgreSQL username.
-e POSTGRES_PASSWORD=pgpass_test_123Sets the password for the PostgreSQL user.
-e POSTGRES_DB=loginCreates a database named ‘login’.
-v /path/to/directory/pgdata:/var/lib/postgresql/data:ZBinds a directory for persistent data. (:Z)

is a SELinux context modifier.

  • :Z: This option tells Docker to label the volume with a shared SELinux context. It allows the container to read and write to the volume while ensuring proper SELinux security policies are applied.
  • In essence, using :Z helps manage permissions and access controls when running containers on systems with SELinux enabled, ensuring that the container can access the specified directory without violating security policies.

Step 5: Verify Installation

Check Running Containers

To verify that your containers are running, use the following command:

				
					podman ps
				
			
				
					CONTAINER ID  IMAGE                                         COMMAND     CREATED     STATUS      PORTS                                          NAMES
73e6d92ea406  localhost/podman-pause:4.9.4-rhel-1723107101              4 hours ago  Up 4 hours   0.0.0.0:5432->5432/tcp, 0.0.0.0:9601->443/tcp  7a3b1227bf52-infra
69a3a918ebed  localhost/lampstack:latest                    /sbin/init  4 hours ago  Up 4 hours   0.0.0.0:5432->5432/tcp, 0.0.0.0:9601->443/tcp  my-web-container
49d1879e546c  docker.io/library/postgres:latest             postgres    4 hours ago  Up 4 hours   0.0.0.0:5432->5432/tcp, 0.0.0.0:9601->443/tcp  my-db-container

				
			

You should see both my-web-container and my-db-container listed.

Accessing the Web Application

Open a web browser and navigate to https://<your_server_ip>:9601 . You should see the PHP info page if everything is set up correctly.

Install LAMP Stack on RHEL 9 | CentOS 9 Using Podman

Photo by admingeek from Infotechys

Accessing PostgreSQL

You can access PostgreSQL using the following command from your terminal:

				
					podman exec -it my-db-container psql -U testuser -d login
				
			
				
					psql (17.0 (Debian 17.0-1.pgdg120+1))
Type "help" for help.

login=# 

				
			

This command will connect you to the PostgreSQL database using the user and database you specified.

Install LAMP Stack on RHEL 9 | CentOS 9 Using Podman: Benefits of Using Podman for LAMP Stack

FeatureDescription
LightweightPodman containers consume fewer resources compared to traditional virtual machines.
IsolationEach container operates in isolation, minimizing conflicts between applications.
PortabilityEasily migrate your setup across different systems without dependency issues.

Troubleshooting Common Issues

Web Application fails to start

If you’re unable to launch the web application or if Apache isn’t starting from your web browser, the issue is likely related to the firewall. To resolve this, run the following commands to allow traffic for HTTP, HTTPS, and the mapped port 9601:

				
					sudo firewall-cmd --permanent --add-port=80/tcp --add-port=443/tcp --add-port=9601/tcp
				
			
				
					sudo firewall-cmd --reload
				
			

Port Conflicts

Ensure that the ports you’re trying to map are not already in use by other services on your host machine.

Permissions Issues

If you encounter permission errors with mounted volumes, you may need to adjust the permissions of the host directories or use the :Z option to label the files correctly for SELinux.

Conclusion

By following this guide, you’ve successfully installed a LAMP stack on RHEL 9 or CentOS 9 using Podman. This setup not only allows for a flexible development environment but also leverages the benefits of containerization. Whether you’re developing a new application or hosting an existing one, this method provides a clean and efficient way to manage your web server and database. Feel free to experiment with different configurations and add more services to your pod as needed. Happy coding!

Did you find this article useful? Your feedback is invaluable to us! Please feel free to share your thoughts in the comments section below.

Related Posts

Leave a Reply

Your email address will not be published. Required fields are marked *