Skip to content

Instantly share code, notes, and snippets.

@TableBookspro
Created September 13, 2016 21:20
Show Gist options
  • Save TableBookspro/a973cab0e9df5d242f2896ad847cd861 to your computer and use it in GitHub Desktop.
Save TableBookspro/a973cab0e9df5d242f2896ad847cd861 to your computer and use it in GitHub Desktop.

Droplet with Git Pull Deploy Configured

The purpose of this tutorial is to configure an environment that will be useful for developing simple HTML, CSS, and JS projects. While the workflow is somewhat non-standard and against git best practices, it is what I intended to achieve. Upon completion of configuration, user will be able to push changes onto master branch in github and see them instantly reflected on their digital ocean droplet. No need for branches like live dev staging release etc.

Setup an Ubuntu 16.04 x64 droplet with SSL encryption via Digital Ocean

Click to See Details

Initial Server Setup with Ubuntu 16.04

Server Setup - Abridged Notes
  • Initialize an Ubuntu 16.04 droplet from the Digital Ocean Control Panel
  • It is best to add your localhost's (your computer) ssh pubkey during this process
  • Take note of it's IP Address, which will be referred to as SERVER_IP_ADDRESS going forward
  • Login to your droplet via the following command:

ssh root@SERVER_IP_ADDRES

  • You will be prompted to change the root password, do this and not it down, this will be referred to as ROOT_PASSWORD going forward.
  • Using root is dumb, don't do it. Because of that, before doing anything, we will make a user account. To do this run:

add user USERNAME

  • Enter a password for this account and note it down, this will be referred to as USERNAME_PASSWORD going forward.
  • You will be prompted for other information, skip all of these by hitting ENTER to leave blank.
  • Your USERNAME account needs to have access to root priveliges (aka able to use the sudo command), to do this, run:

usermod -aG sudo USERNAME

  • Add SSH access to your USERNAME account

SKIP FOR NOW...til Step 7

  • If you do not have an ssh-keypair on your localhost, generate it:

ssh-keygen

  • You will find it at ~/.ssh assuming you are on OSX
  • Use the hombrew package ssh-copy-id, to install it, run:

brew install ssh-copy-id

  • Now run it (from localhost) via:

ssh-copy-id USERNAME@SERVER_IP_ADDRESS

  • You can now ssh into your server.
  • Disable Password Authentication (Assuming SSH Works)

sudo vim /etc/ssh/sshd_config

  • Look for the line #PasswordAuthentication yes, change to:
PasswordAuthentication no
  • Save an Quit
  • Reload the SSH daemon

sudo systemctl reload sshd

  • Test the configuration in a new terminal before closing out the current session:

ssh USER@SERVER_IP_ADDRESS

  • Setup a basic firewall by running:

sudo ufw app list

  • Allow SSH Connections by running:

sudo ufw allow OpenSSH

  • Enable the firewall, by running:

sudo ufw enable

  • Check firewall Status

sudo ufw status


Install LAMP stack on Ubuntu 16.04

Install LAMP stack - Abridged Notes
  • Install Apache:

sudo apt-get update

sudo apt-get install apache2

  • Test the configuration (it will show a warning):

sudo apache2ctl configtest

  • Open up the config file:

sudo vim /etc/apache2/apache2.conf

  • At the bottom of that file, add:

ServerName server_domain_or_IP

  • Save and Close
  • Test config again:

sudo apache2ctl configtest

  • Restart Apache

sudo systemctl restart apache2

  • Adjust the firewall to allow web traffic

sudo ufw app list

sudo ufw app info "Apache Full"

  • Allow "Apache Full"

sudo ufw allow in "Apache Full"

sudo apt-get install mysql-server

  • Enter a password for MySQL root user, take note of this as MySQL ROOT PASSWORD
  • Run a script to lock down MySQL:

sudo mysql_secure_installation

  • Respond no (N) when asked if you want to configure VALIDATE PASSWORD PLUGIN
  • Respond yes (Y) to all of the prompts that follow
  • Install PHP

sudo apt-get install php libapache2-mod-php php-mcrypt php-mysql

  • Open the dir.conf file:

sudo vim /etc/apache2/mods-enabled/dir.conf

  • Edit as follows:
<IfModule mod_dir.c>
    DirectoryIndex index.html index.cgi index.pl index.php index.xhtml index.htm
</IfModule>

changes to:

<IfModule mod_dir.c>
    DirectoryIndex index.php index.html index.cgi index.pl index.xhtml index.htm
</IfModule>
  • Basically, you are moving index.php far to the left
  • Save and close
  • Restart Apache

sudo systemctl restart apache2

  • Check status of Apache

sudo systemctl status apache2

  • Test PHP processing

sudo vim /var/www/html/info.php

  • Add the following into that file:
<?php
phpinfo();

Setup a Host Name (Domain Name) with your Server

Setup a Host Name - Abridged
  • Lookup WHOIS

whois example.com

  • Change your Domain Server
  • With your Registrar, point your nameservers to Digital Ocean:
ns1.digitalocean.com
ns2.digitalocean.com
ns3.digitalocean.com
  • Run WHOIS again to confirm, might take a while.

  • Configure your Domain on Digital Ocean

  • Basically, in your control panel, jsut add the domain, it will do the rest


Setup Apache Virtual Hosts on 16.04

Setup Apache Virtual Hosts - Abridged
  • Create the Directory Structure
  • Document root on standard Apache is at /var/www
  • Make a dirctory for your domain:

sudo mkdir -p /var/www/example.com/public_html

  • Grant Permissions
  • $USER will be your UERNAME

sudo chown -R $USER:$USER /var/www/example.com/public_html

  • Modify the Permissions

sudo chmod -R 755 /var/www

  • Your web server should now have the permissions it needs to serve content
  • Create Demo Pages for your Virtual Host

vim /var/www/example.com/public_html/index.html

  • Inside the file, add:
<html>
  <head>
    <title>Welcome to Example.com!</title>
  </head>
  <body>
    <h1>Success!  The example.com virtual host is working!</h1>
  </body>
</html>
  • Create New Virtual Hosts File by copying the 000-defualt.conf file

sudo cp /etc/apache2/sites-available/000-default.conf /etc/apache2/sites-available/example.com.conf

  • Edit that file:

sudo vim /etc/apache2/sites-available/example.com.conf

  • Edit the file as follows:
<VirtualHost *:80>
    ServerAdmin webmaster@localhost     // ENTER YOUR EMAIL
    DocumentRoot /var/www/html          // MODIFY TO: /var/www/example.com/public_html
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

// ADD THESE

    ServerName example.com  
    ServerAlias www.example.com

</VirtualHost>
  • Save and close
  • Enable the Virtual Hosts

sudo a2ensite example.com.conf

  • Disable the default:

sudo a2dissite 000-default.conf

  • Restart Apache:

sudo systemctl restart apache2


How To Secure Apache with Let's Encrypt on Ubuntu 16.04

Secure Apache - Abridged Notes
  • Install Let's Encrypt (Free SSL/TLS Certificates)

sudo apt-get update

sudo apt-get install python-letsencrypt-apache

  • Start the interactive installation

sudo letsencrypt --apache -d example.com

sudo letsencrypt renew

  • Generated Message will look like:
Processing /etc/letsencrypt/renewal/example.com.conf

The following certs are not due for renewal yet:
  /etc/letsencrypt/live/example.com/fullchain.pem (skipped)
  No renewals were attempted.
  • Now let's setup a cronjob to Autorenew your certificate:

sudo crontab -e

  • Slect the enditor to open it in (I use vim)
  • All in one line, at the end of the file, add:
30 2 * * 1 /usr/bin/letsencrypt renew >> /var/log/le-renew.log

Setup Use of Repo Specific Deploy Keys

Click to See Details

Make an .ssh directory in /var/www and give permissions to www-data user:

sudo mkdir /var/www/.ssh

sudo chown www-data /var/www/.ssh

Switch user to www-data:

sudo -u www-data bash

cd /var/www/.ssh

Generate an ssh keypair that will connect your server (via www-data) and your Github project:

ssh-keygen -t rsa -C "IDENTIFY THE KEY BY REPO"

I also like to name it id_rsa_REPONAME.pub so that identifying the keypairs is easier

cat id_rsa_REPONAME.pub

Copy that and paste it as a deploy key in your Github Repos settings.

You also need to add this keypair to your config file

vim config will create or allow you to edit this file if it already exists. You need this config to help your server match incoming ssh requests from github. NOTE: this is not necessary when you provide github account level ssh access to your server. All of that said, you should use this method as it segregates the concerns properly.


EDIT THE .ssh/config FILE

You need to alter the config file:

Host github.com-REPONAME
Hostname github.com
User git
IdentityFile /var/www/.ssh/id_rsa_REPONAME
IdentitiesOnly yes

And do the same with all future repos

Save and exit.

Test your new ssh key:

ssh -T [email protected]

Should output Hi YOURGITUSERNAME/REPONAME! You've successfully authenticated, but GitHub does not provide shell access.

This confirms that specific deploy key can be found by github. You can also see it highlighted in green on the github side.


exit (this drops you out of www-data and back into your user account)

chown www-data:www-data /the/path/to/public_html

Switch back into www-data:

sudo -u www-data bash

cd /the/path/to/public_html

Before you clone

Make sure you have a file named githubdeploy.php in the root of your repo

<?php `git pull`;?>

git clone THE_REPO_SSH_URL utilizing the syntax in Step 3

exit (this drops you out of www-data and back into your user account)

On Github:

Add the url path to githubdeploy.php as a webhook on Github.

DONE

Summary

You now have a Digital Ocean Droplet that automatically pulls everytime a change is pushed to the master of your repo hosted on Githb. This is not necessarily the proper way to accomplish this. And it definitely isn't a form of continuous deployment, which would use various branches to better segregate work. It is, a quick and easy way to have a changes reflected on a server. Lastly, it is somewhat dangerous in that it gives your servers user www-data ssh access to your github account, not just one repo (a la deploy keys). While this might be considered foolish, it makes hosting mutiple repos alot easier.

Alternative - Using Github Account Access


Click to See Details

Make an .ssh directory in /var/www and give permissions to www-data user:

sudo mkdir /var/www/.ssh

sudo chown www-data /var/www/.ssh

Switch user to www-data:

sudo -u www-data bash

cd /var/www/.ssh

Generate an ssh keypair that will connect your server (via www-data) and your Github:

ssh-keygen -t rsa -C "IDENTIFY THE KEY"

cat id_rsa.pub

Copy that and paste it as an authorized ssh key in your Github account settings.

exit (this drops you out of www-data and back into your user account)

chown www-data:www-data /the/path/to/public_html

Switch back into www-data:

sudo -u www-data bash

cd /the/path/to/public_html

Before you clone

Make sure you have a file named githubdeploy.php in the root of your repo

<?php `git pull`;?>

git clone THE_REPO_SSH_URL

exit (this drops you out of www-data and back into your user account)

On Github:

Add the url path to githubdeploy.php as a webhook on Github.

DONE


.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment