In this tutorial, we'll explain how to deploy a secure LEMP stack on Docker with Let's Encrypt SSL on Ubuntu 24.04.
Learn how to deploy a complete LEMP stack (Nginx, MariaDB, PHP) on Docker with SSL security using Let's Encrypt. This step-by-step guide covers the entire process, from setting up Docker containers to securing your site with a free SSL certificate from Let's Encrypt. By the end, you'll have a fully functional and secure environment ready for production. Perfect for developers looking to streamline their web application deployment with Docker and ensure HTTPS security.
Prerequisites
- A Ubuntu 24.04 installed dedicated server or KVM VPS.
- A root user access or normal user with sudo rights.
- Basic knowledge of Docker.
Install LEMP Stack on Docker
Step 1: Create a Project Directory
First, create a directory for your project. This directory will hold your Docker configuration files.
mkdir lemp-docker && cd lemp-docker
Step 2: Configure Firewall
We're configuring firewall first, because on next step we are generating SSL certificate. It needs HTTP port open in firewall.
ufw allow 80/tcp
ufw allow 443/tcp
ufw reload
Step 3: Generate SSL Certificate
Before proceeding further, we need to generate standalone SSL certificate using Certbot. We need the certificate path to add in the docker compose file.
sudo apt install certbot -y
Run the following command to obtain an SSL certificate:
Note: Replace your_domain
with your domain.
sudo certbot certonly --standalone -d your_domain
After your execute above command it will provide the SSL certificate installed path. Copy SSL certificate saved path, we need it for next step to add in the default.conf
file. It looks like:
Certificate is saved at: /etc/letsencrypt/live/your_domain/fullchain.pem
Key is saved at: /etc/letsencrypt/live/your_domain/privkey.pem
Step 4: Install Docker
We need to install Docker. If you have already installed Docker in your system, you can skip this step.
Following commands are copied from official website:
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl -y
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
To install the latest version, run:
sudo apt-get install docker-ce -y
Step 5: Configure Nginx
Create a default configuration file for Nginx in the nginx directory.
mkdir nginx && cd nginx
Create a file named default.conf
in the nginx
directory with the following content:
nano default.conf
Replace yourdomain.com
with your domain and add following content:
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name lemp.hnxcode.dev www.yourdomain.com;
root /var/www/html;
index index.php index.html;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass php_fpm:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ~ /\.ht {
deny all;
}
}
Save and exit the file.
Step 6: Create a PHP File to Test the Setup
Create an html directory in your project and add a index.php
file:
cd ../ && mkdir html && cd html
Create a file named index.php
in the html directory with the following content:
nano index.php
Add following code:
<?php
phpinfo();
?>
This simple PHP script will display the PHP configuration page.
Step 7: Create a docker-compose.yml File
In your project directory, create a docker-compose.yml
file. This file will define the services for Nginx, MariaDB, and PHP.
cd ../ && nano docker-compose.yml
Add following content:
version: '3.8'
services:
nginx:
image: nginx:latest
container_name: nginx_server
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx:/etc/nginx/conf.d
- ./html:/var/www/html
- /etc/letsencrypt:/etc/letsencrypt
- ./ssl:/etc/nginx/ssl
depends_on:
- php
php:
image: php:8.2-fpm
container_name: php_fpm
volumes:
- ./html:/var/www/html
depends_on:
- mariadb
mariadb:
image: mariadb:latest
container_name: mariadb_server
environment:
MYSQL_ROOT_PASSWORD: your_root_password
MYSQL_DATABASE: your_database_name
MYSQL_USER: your_user
MYSQL_PASSWORD: your_password
volumes:
- ./db_data:/var/lib/mysql
ports:
- "3306:3306"
Step 8: Deploy the Containers
Now, you can deploy the Docker containers using Docker Compose.
docker compose up -d
This command will pull the necessary Docker images, create the containers, and start the services in detached mode.
Check the Docker container running using following command:
docker ps
If any container is not running, check the logs of the container.
docker ps -a
Copy the stopped container id
docker container logs [CONTAINER ID]
Check the log and fix the issue. Remove all the existing container and redeploy:
docker compose down
docker compose up -d
Step 9: Verify the Setup
Open your web browser and navigate to https://yourdomain.com
. You should see the PHP information page, which confirms that Nginx is serving PHP files through PHP-FPM.
Conclusion
You now have a working LEMP stack running on Docker, with Nginx, MariaDB, and PHP all configured and ready to use. This setup is ideal for developing and testing web applications in a consistent environment.
Key Points
- Nginx serves as the web server, handling requests and forwarding them to PHP-FPM.
- PHP-FPM processes PHP scripts.
- MariaDB handles the database, storing all your application data.
- Docker Compose simplifies the setup by allowing you to define and manage multi-container Docker applications.
- Let's Encrypt provides free SSL certificates, making it easy to secure your site.
- Certbot automates the process of obtaining and renewing SSL certificates.
- Nginx Configuration ensures that both HTTP and HTTPS traffic are correctly handled, with HTTP traffic being redirected to HTTPS.
This environment is easy to scale, maintain, and replicate, making it an excellent choice for modern web development.