In this blog post, I will describe how to automate the installation of LEMP stack on Ubuntu server using cloud-init. cloud-init allows us to spin a server for testing/development. LEMP stack consists of four major software components.

  • Linux – The operating system on which the EMP is running.
  • NGINX – Another powerful web server, similar to Apache.
  • MariaDB – An open-source relational database management system.
  • PHP – Server-side scripting language used to process web pages.

You can further enhance the configuration by pulling code automatically from a Git repository and also configure the database automatically.

Further information about LEMP stack is available at

Cloud Platforms and OS Support

Using the cloud-init template, you can deploy the LEMP stack on Amazon Web Services EC2 instance or a droplet on Digital Ocean.

The cloud-init LEMP template can be downloaded from

cloud-init LEMP Template

This section provides details on the cloud-init templates that are available via my GitHub repository. Using cloud-init, we will be doing the following on our server.

  1. Perform software upgrade on the server.
  2. Install NGINX, MariaDB, and PHP.
  3. After installation has completed, configure the software components and start the services provided automatically.

While I try to do my best in explaining the configuration template, you can read the cloud-init docs that provide more details.

Package Upgrade

A single line will update the available packages list and will also upgrade the server.

package_upgrade: true

Software installation

NGINX and PHP packages are installed during first boot using the configuration block shown below.

  - nginx
  - php-mysql
  - php7.0-mcrypt
  - php7.0-gd
  - php7.0-curl

Create files

Using the “write_files” feature that is available within cloud-init, we create two files.

  1. NGINX default configuration.
  2. index.php in /var/www/html/ that provides information about the PHP installation and helps validate that the installation completed successfully.
- path: /etc/nginx/sites-available/default
  content: |
    server {
      listen 80 default_server;
      listen [::]:80 default_server ipv6only=on;
      root /var/www/html;
      index index.php index.html index.htm;
      server_name localhost;
      location / {
        try_files $uri $uri/ =404;
      error_page 404 /404.html;
      error_page 500 502 503 504 /50x.html;
      location = /50x.html {
        root /usr/share/nginx/html;
      location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
        fastcgi_index index.php;
        include fastcgi.conf;

- path: /var/www/html/index.php
  content: |

Install and configure MariaDB

Installation and configuration of MariaDB are done using the runcmd block. Using runcmd gives us better control and allows us to configure a password for the root account of MariaDB. Finally, using cloud-init, the password for the root user of MariaDB is stored in  /root/mysql.txt file.

# Variable named HNAME is set
- export HOSTNAME=$(hostname -f)

# A random password is generated for MariaDB.
- export MDBPASS=`dd if=/dev/urandom bs=1 count=12 2>/dev/null | base64 -w 0 | rev | cut -b 2- | rev`

# In order to install MariaDB without an human interaction, the following three commands are required.
- export DEBIAN_FRONTEND=noninteractive
- echo "mariadb-server-10.0 mysql-server/root_password password $MDBPASS" | debconf-set-selections
- echo "mariadb-server-10.0 mysql-server/root_password_again password $MDBPASS" | debconf-set-selections

# Using the commands below, MariaDB repository is setup.
- sudo apt-get -y install software-properties-common
- sudo apt-key adv --recv-keys --keyserver hkp:// 0xF1656F24C74CD1D8
- sudo add-apt-repository 'deb [arch=amd64,i386,ppc64el] xenial main'

# Install mariadb-server using apt.
- sudo apt update
- sudo apt -y install mariadb-server

# NGINX configuration is updated so that the server name changes to the name of the instance and NGINX is restarted
- sed -i 's/server_name localhost;/server_name '$HOSTNAME';/' /etc/nginx/sites-available/default
- systemctl restart nginx

# mysql password is stored in /root/mysql.txt file
- echo "$MDBPASS" >> /root/mysql.txt

If you land into any issues, please feel free to comment, and I will try my best to respond. Additionally, you can review the troubleshooting cloud-init blog post.