Deploying On DigitalOcean Using Docker

This guide outlines how to manually deploy Laraone CMS to fast and reliable cloud hosting provider DigitalOcean

Prerequisite

You will need an account at DigitalOcean before you can complete all the steps in this guide. Once you register for an account at DigitalOcean you can continue with the guide below.

Select Droplet

  • Initiate the process of creating a new droplet
  • Navigate to Marketplace tab and perform a search for Docker app running on Ubuntu 18.04
  • Press Create Docker Droplet button
  • Skip Block Storage
  • Choose Datacenter region
  • Under Select additional options select User data checkbox

Droplet Script

Paste in below script into User data textbox

#!/bin/bash
sudo fallocate -l 1G /swapfile;
chmod 600 /swapfile;
mkswap /swapfile;
swapon /swapfile;
echo "/swapfile   none    swap    sw    0   0" >> /etc/fstab;
sudo apt-get -qqy update
sudo apt install git -y
sudo git clone https://github.com/laraone/laraone.git /root/src
sudo mkdir /root/mysql
sudo touch /root/mysql/my.cnf
sudo mkdir /root/php
sudo touch /root/php/local.ini

Above bash script will be executed as soon as the droplet boots up for the first time.

This script will:

  • Create a simple 1GB swapfile
  • Set correct file & folder permissions
  • Install few required php packages
  • Pull Laraone CMS project from Github repository
  • Create an empty mysql config file

Note: Swapfile creation is required for 5$ droplets, but it can be skipped by using more powerful droplets. Remove it only if you are techically skilled and know what you are doing. If you remove it but experience composer errors while installing the CMS, then swapfile is required and it should be created. This is due to PHP dependency manager Composer requiring quite a lot of RAM memory to satisfy package dependencies.

Authentication

It is recommended that you select SSH keys option as authentication. Note that droplets that use SSH keys have password authentication disabled by default. This makes them secure against brute-force attacks. Only select One-Time Password option if you know what you are doing. If One-Time Password is the option you select, we advise you to create a password with at least 18 random characters and store it inside password keeper application.

To create SSH Keys checkout these links for a guide Windows and here for Linux and MacOS

Create Droplet

Scroll to the bottom of the page and press the button that says Create Droplet, DigitalOcean will spin up a droplet with your configuration. Wait a while till the droplet is created before proceeding to next step.

Note: After the droplet is created, it's user-data bash script is executed. You may experience 1-5 minute wait time depending on your droplet speed.

Create Docker Files

Navigate to /root directory and create docker-compose.yml file. This file defines services used by Docker containers. Fill it with data below:

    version: '3'
    services:
    php:
        build:
        args:
            user: laraone
            uid: 1000
        context: ./
        dockerfile: Dockerfile
        container_name: php
        restart: unless-stopped
        tty: true
        environment:
        SERVICE_NAME: php
        SERVICE_TAGS: dev
        working_dir: /var/www/html
        volumes: 
        - ./src:/var/www/html
        - ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
        ports:
        - "9000:9000"
        networks:
        - laravel
    
    nginx:
        image: nginx:stable-alpine
        container_name: nginx
        restart: unless-stopped
        tty: true
        ports:
        - "80:80"
        - "443:443"
        volumes:
        - ./src:/var/www/html
        - ./nginx:/etc/nginx/conf.d/
        networks:
        - laravel
    
    mysql:
        image: mysql:5.7.22
        container_name: mysql
        restart: unless-stopped
        tty: true
        ports: 
        - "3306:3306"
        volumes:
        - dbdata:/var/lib/mysql
        - ./mysql/my.cnf:/etc/mysql/my.cnf
        environment:
        MYSQL_DATABASE: laraone
        MYSQL_USER: laraone_user
        MYSQL_PASSWORD: secret
        MYSQL_ROOT_PASSWORD: secret
        SERVICE_TAGS: dev
        SERVICE_NAME: mysql
        networks:
        - laravel
    
    networks:
    laravel:
        driver: bridge
        
    volumes:
    dbdata:
        driver: local

Since MySQL service is created using data from this configuration file, we highly advise you to change values for MYSQL_DATABASE, MYSQL_USER, MYSQL_PASSWORD and MYSQL_ROOT_PASSWORD variables.

While in /root directory, create another file named Dockerfile which runs series of instructions needed for images to be built. Copy this into your Dockerfile

    FROM php:7.3-fpm

    # Arguments defined in docker-compose.yml
    ARG user
    ARG uid

    # Install system dependencies
    RUN apt-get update && apt-get install -y \
        git \
        curl \
        libfreetype6-dev \
        libjpeg-dev \
        libpng-dev \
        libonig-dev \
        libxml2-dev \
        libtidy-dev \
        libzip-dev \
        zip \
        unzip

    # Clear cache
    RUN apt-get clean && rm -rf /var/lib/apt/lists/*

    # Install PHP extensions
    RUN docker-php-ext-install pdo_mysql gd dom tidy xmlrpc bcmath mbstring xml zip

    # Configure gd extension
    RUN docker-php-ext-configure gd --with-gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ --with-png-dir=/usr/include/

    # Get latest Composer
    COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

    # Create system user to run Composer and Artisan Commands
    RUN useradd -G www-data,root -u $uid -d /home/$user $user
    RUN mkdir -p /home/$user/.composer && \
        chown -R $user:$user /home/$user

    # Set working directory
    WORKDIR /var/www/html

    USER $user

Now create a new folder /root/nginx and inside it create default.conf file. This file is used by nginx service and contains configuration data for webserver. Copy the following code in default.conf

    server {
        listen 80;
        index index.php index.html;
        server_name localhost; 
        error_log /var/log/nginx/error.log;
        access_log /var/log/nginx/access.log;
        root /var/www/html/public;
        
        client_max_body_size 100M;

        location / {
        try_files $uri $uri/ /index.php?$query_string;
        }


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

ENV File

We need to create and customize an .env file. This is a file where application's basic configuration is stored. In user-data script we already renamed existing .env.example file to .env so you should just edit and save it. It is located in /root/src directory.

The .env file should look like this:

    APP_NAME=Laraone
    APP_ENV="local"
    APP_KEY=
    APP_DEBUG=true
    APP_URL=http://localhost

    #ADMIN_USERNAME=admin_username
    #ADMIN_EMAIL=name@example.com
    #ADMIN_PASSWORD=Example123456
    #ADMIN_FIRSTNAME=firstname
    #ADMIN_LASTNAME=lastname

    LOG_CHANNEL=stack

    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laraone
    DB_USERNAME=laraone_user
    DB_PASSWORD=secret

    BROADCAST_DRIVER=log
    CACHE_DRIVER=file
    SESSION_DRIVER=file
    QUEUE_DRIVER=sync

    REDIS_HOST=127.0.0.1
    REDIS_PASSWORD=
    REDIS_PORT=6379

    MAIL_DRIVER=smtp
    MAIL_HOST=mailtrap.io
    MAIL_PORT=2525
    MAIL_USERNAME=
    MAIL_PASSWORD=
    MAIL_ENCRYPTION=

    MAIL_FROM_ADDRESS=noreply@example.com
    MAIL_FROM_NAME="${APP_NAME}"

    MAIL_SENDMAIL="/usr/sbin/sendmail -bs"

    MAILGUN_DOMAIN=
    MAILGUN_SECRET=
    MAILGUN_ENDPOINT="api.mailgun.net"

    MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
    MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"

Uncomment all settings starting with ADMIN by removing # in front of them. Then set each setting, this will be used by installation command to create the first Admin user.

Note: Password must be at minimum 8 characters. If you do not wish to set first and lastname, leave them commented out with #

Next make sure to update all of these settings with data that matches your setup in Database Creation step you did previously

    APP_URL=https://mywebsite.com
    DB_DATABASE=laraone
    DB_USERNAME=custom_db_username
    DB_PASSWORD my_db_password

If you plan to be using email to get password resets and email activation links then also update these according to your needs. Using your gmail account settings is possible. Or perhaps you have access to private email server using smtp. Update below settings accordingly to your needs.

    MAIL_DRIVER=smtp
    MAIL_HOST=mailtrap.io
    MAIL_PORT=2525
    MAIL_USERNAME=
    MAIL_PASSWORD=
    MAIL_ENCRYPTION=

If you plan to use MailGun a service where you get up to 10000 free emails per month, then you need configure these settings:

    MAIL_DRIVER=mailgun
    MAILGUN_DOMAIN=enter your mailgun domain
    MAILGUN_SECRET=enter your mail gun API secret
    MAILGUN_ENDPOINT="api.mailgun.net"

Example Mailgun config can look like this

    MAIL_DRIVER=mailgun
    MAILGUN_DOMAIN=mg.mydomain.com
    MAILGUN_SECRET=key-LE5Y4jy3DM5Qc6Acnh7z9BJzi6oY
    MAILGUN_ENDPOINT=api.mailgun.net

Note: Secret key above is fake, so use the one you get from Mailgun when you sign up for an account there.

It's good to set a global from email address and name. These are used in emails that are sent from the your website.

    MAIL_FROM_ADDRESS=noreply@mydomain.com
    MAIL_FROM_NAME="${APP_NAME}"

Add application owner

For safety reasons root shouldn't be the owner of /root/src/ folder. What you need to do is create a new linux user by running:

    useradd laraone

Now run a command to create password for this user:

    passwd laraone

You will now be prompted to enter new UNIX password for this user, and once again to confirm it. Make him the owner of /root/src/ folder:

chown -R laraone:www-group /root/src

To set up directory permissions for Laraone CMS, run this command:

    chmod -R 755 /root/src

Setup PHP config

Open /root/php/local.ini file and insert:

    upload_max_filesize=100M
    post_max_size=100M

Start Docker Services

Since predefined .env file and docker config files were already imported using user-data script, you only need to run this command which starts Docker services:

    docker-compose up -d

Update Composer

Before we install the CMS it's a good idea to let composer update it self. Navigate to /root/src folder and run this command:

    docker exec -it php composer update

Install CMS

To finally install Laraone CMS it self, just run:

    docker exec -it php php artisan laraone:install

Note: If installation is successfull you will get a success message and version numbers of Laraone backend and admin. If that is so visiting your domain you should see a welcome page. User you have specified as admin in the .env file above has been created and you can login as that user if you go to mywebsite.com/auth/login and start building your website.