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.