UbuntuUbuntu Based

How To Install Drupal with Docker on Ubuntu 22.04 LTS

Install Drupal with Docker on Ubuntu 22.04

In this tutorial, we will show you how to install Drupal with Docker on Ubuntu 22.04 LTS. For those of you who didn’t know, Drupal is an open source platform for building amazing digital experiences. It’s made by a dedicated community. Drupal uses a modular architecture, which allows developers to add functionality to the core system by installing and configuring modules. There are thousands of modules available for Drupal, which provide a wide range of functionality, such as e-commerce, forums, and social media integration.

This article assumes you have at least basic knowledge of Linux, know how to use the shell, and most importantly, you host your site on your own VPS. The installation is quite simple and assumes you are running in the root account, if not you may need to add ‘sudo‘ to the commands to get root privileges. I will show you the step-by-step installation of Drupal with Docker on Ubuntu 22.04. You can follow the same instructions for Ubuntu 22.04 and any other Debian-based distribution like Linux Mint, Elementary OS, Pop!_OS, and more as well.

Prerequisites

  • A server running one of the following operating systems: Ubuntu 22.04, 20.04, and any other Debian-based distribution like Linux Mint.
  • It’s recommended that you use a fresh OS install to prevent any potential issues.
  • SSH access to the server (or just open Terminal if you’re on a desktop).
  • An active internet connection. You’ll need an internet connection to download the necessary packages and dependencies for Drupal and Docker.
  • A non-root sudo user or access to the root user. We recommend acting as a non-root sudo user, however, as you can harm your system if you’re not careful when acting as the root.

Install Drupal with Docker on Ubuntu 22.04 LTS Jammy Jellyfish

Step 1. First, make sure that all your system packages are up-to-date by running the following apt commands in the terminal.

sudo apt update
sudo apt upgrade

Step 2. Installing Docker.

By default, Docker is not available on Ubuntu 22.04 base repository. Now run the following command below to add the Docker repository to the system:

echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

Next, import the GPG key to your system:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

After the repository is enabled, now install the latest version of the Docker package using the below command:

sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

You can verify that Docker is installed and about the current version:

docker -v

After successfully installed, enable Docker (to start automatically upon system boot), start, and verify the status using the commands below:

sudo systemctl enable docker
sudo systemctl start docker
sudo systemctl status docker

By default, Docker requires root privileges. If you want to avoid using sudo every time you run the docker command, add your username to the docker group:

sudo usermod -aG docker $(whoami)
su - ${USER}

Confirm that your user is added to the Docker group:

groups

For additional resources on installing and managing Docker, read the post below:

Step 3. Create Docker Compose File for Drupal.

First, create a directory for Drupal configuration:

mkdir ~/drupal
cd ~/drupal

Now we create and open the Docker compose file using your favorite text editor:

nano docker-compose.yml

Add the following file:

services:
  mysql:
    image: mysql:8.0
    container_name: mysql
    restart: unless-stopped
    env_file: .env
    volumes:
      - db-data:/var/lib/mysql
    networks:
      - internal
  
  drupal:
    image: drupal:10-fpm-alpine
    container_name: drupal
    depends_on:
      - mysql
    restart: unless-stopped
    networks:
      - internal
      - external
    volumes:
      - drupal-data:/var/www/html
  
  webserver:
    image: nginx:1.22.1-alpine
    container_name: webserver
    depends_on:
      - drupal
    restart: unless-stopped
    ports:
      - 80:80
    volumes:
      - drupal-data:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
    networks:
      - external
  
  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - drupal-data:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email admin@your-domain --agree-tos --no-eff-email --staging -d your-domain.com -d www.your-domain.com

networks:
  external:
    driver: bridge
  internal:
    driver: bridge

volumes:
  drupal-data:
  db-data:
  certbot-etc:

Save and close the file.

Step 4. Configure Docker Compose for Nginx.

First, we create the directory for Nginx configuration:

mkdir nginx-conf

Next, create and open the file for Nginx using your favorite text editor:

nano nginx-conf/drupal.conf

Add the following file:

server {
    listen 80;
    listen [::]:80;

    server_name your-domain.com;

    index index.php index.html index.htm;

    root /var/www/html;

    location ~ /.well-known/acme-challenge {
        allow all;
        root /var/www/html;
    }

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass drupal:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location ~ /\.ht {
        deny all;
    }

    location = /favicon.ico { 
        log_not_found off; access_log off; 
    }
    location = /robots.txt { 
        log_not_found off; access_log off; allow all; 
    }
    location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
        expires max;
        log_not_found off;
    }
}

Once is done, save and close the file.

Step 5. Configure Docker for SSL.

Before generating SSL certificates, we start our containers using the following command:

docker compose up -d

Next, open a docker-compose file using the following command below:

nano docker-compose.yml

Replace the --staging flag in the Certbot service section and replace it with the --force-renewal flag:

  certbot:
    depends_on:
      - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
      - certbot-etc:/etc/letsencrypt
      - drupal-data:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email admin@your-domain.com --agree-tos --no-eff-email --staple-ocsp --force-renewal -d your-domain.com

Save and close the file, then run the docker compose up command again to recreate the Certbot container:

docker compose up --force-recreate --no-deps certbot

Step 6. Configure Nginx for SSL.

First, we Stop the Nginx server using the following command:

docker stop webserver

Next, create a new Nginx file for SSL configuration:

nano nginx-conf/drupal-ssl.conf

Add the following file:

server {
    listen 80;
    listen [::]:80;

    server_name your-domain.com;

    location ~ /.well-known/acme-challenge {
        allow all;
        root /var/www/html;
    }

    location / {
        rewrite ^ https://$host$request_uri? permanent;
    }
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name your-domain.com;

    index index.php index.html index.htm;

    root /var/www/html;

    server_tokens off;

    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    ssl_trusted_certificate /etc/letsencrypt/live/your-domain.com/chain.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:10m;
    ssl_session_tickets off;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    ssl_ecdh_curve secp384r1;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=300s;
    resolver_timeout 5s;

    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src * data: 'unsafe-eval' 'unsafe-inline'" always;

    location / {
        try_files $uri $uri/ /index.php$is_args$args;
    }

    rewrite ^/core/authorize.php/core/authorize.php(.*)$ /core/authorize.php$1;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass drupal:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }

    location ~ /\.ht {
        deny all;
    }

    location = /favicon.ico {
        log_not_found off; access_log off;
    }
    location = /robots.txt {
        log_not_found off; access_log off; allow all;
    }
    location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
        expires max;
        log_not_found off;
    }
}

Save and close the file, then make sure the Nginx container listens to port 443:

nano docker-compose.yml

Following the configuration:

webserver:
    image: nginx:1.22.1-alpine
    container_name: webserver
    depends_on:
      - drupal
    restart: unless-stopped
    ports:
      - 80:80
      - 443:443
    volumes:
      - drupal-data:/var/www/html
      - ./nginx-conf:/etc/nginx/conf.d
      - certbot-etc:/etc/letsencrypt
      - /etc/ssl/certs/dhparam.pem:/etc/ssl/certs/dhparam.pem
    networks:
      - external

Save and close the file, then remove the older HTTP configuration file using the following command:

rm nginx-conf/drupal.conf

Next, generate a Diffie-Hellman group certificate which we have already configured above:

sudo openssl dhparam -dsaparam -out /etc/ssl/certs/dhparam.pem 4096

Finally, recreate the Nginx container:

docker compose up -d --force-recreate --no-deps webserver

Step 7. Configure Firewall.

Now we set up an Uncomplicated Firewall (UFW) with Drupal to allow public access on default web ports 80 and 443:

sudo ufw allow OpenSSH
sudo ufw allow http
sudo ufw allow https
sudo ufw enable

Step 8. Accessing Drupal Web Interface.

Now open your web browser and access the Drupal Web UI using the URL https://your-domain.com. You will be redirected to the following page:

Install Drupal with Docker on Ubuntu 22.04 LTS Jammy Jellyfish

Congratulations! You have successfully installed Drupal with Docker. Thanks for using this tutorial for installing Drupal with Docker on the Ubuntu system. For additional help or useful information, we recommend you check the official Drupal website.

VPS Manage Service Offer
If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal!

r00t

r00t is a seasoned Linux system administrator with a wealth of experience in the field. Known for his contributions to idroot.us, r00t has authored numerous tutorials and guides, helping users navigate the complexities of Linux systems. His expertise spans across various Linux distributions, including Ubuntu, CentOS, and Debian. r00t's work is characterized by his ability to simplify complex concepts, making Linux more accessible to users of all skill levels. His dedication to the Linux community and his commitment to sharing knowledge makes him a respected figure in the field.
Back to top button