Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save codescribblr/9e0e987b9dfc7d903c414681b8c31b91 to your computer and use it in GitHub Desktop.
Save codescribblr/9e0e987b9dfc7d903c414681b8c31b91 to your computer and use it in GitHub Desktop.
Server setup for Ubuntu 16.04 on Digital Ocean

Server setup for Ubuntu 16.04 on Digital Ocean

The setup installs the following software:

  • Nginx
  • MySQL
  • PHP
  • Node
  • Composer

Update system

apt-get update && apt-get dist-upgrade -y
apt-get autoremove -y

Add new user

Instead of using root as the user, we add a new one.

useradd -d /home/<username> -m -s /bin/bash <username>
usermod -a -G adm,cdrom,sudo,dip,plugdev <username>

If you provided your SSH key when creating the droplet, you can copy the authorized_keys to the new username to skip needing a password when connecting.

mkdir /home/<username>/.ssh
cp /root/.ssh/authorized_keys /home/<username>/.ssh/
chmod 600 /home/<username>/.ssh/authorized_keys
chown -R <username>:<username> /home/<username>/.ssh

Run visudo and add the following line at the end of the file.

<username> ALL=(ALL) NOPASSWD: ALL

Create and expose a SSH Key for the new user

ssh-keygen -t rsa -C "name@email.com"
cat ~/.ssh/id_rsa.pub

Install packages

apt-get install -y \
build-essential \
software-properties-common \
python \
g++ \
make \
fail2ban \
apache2-utils \
curl \
bc \
git \
htop \
ntp \
ntpdate \
unzip \
aptitude

Set correct timezone

dpkg-reconfigure tzdata

Install firewall

sudo apt-get install ufw

Allow SSH, HTTP and HTTPS.

sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https

Enable firewall.

sudo ufw enable

Check the status of the firewall.

sudo ufw status verbose

Install NodeJS

curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
apt-get install -y nodejs

Update npm.

npm update -g

Install Composer

curl -sS https://getcomposer.org/installer | php -- \
--install-dir=/usr/bin \
--filename=composer

Create default htpasswd file

htpasswd -c /etc/default/htpasswd <htpasswd-username>

Install Nginx

add-apt-repository ppa:nginx/development
apt-get update && apt-get install nginx-full -y

Configure Nginx

Check number of cores to set worker_processes.

grep processor /proc/cpuinfo | wc -l

Check core limit for number of connections.

ulimit -n

Configure Nginx accordingly. Be careful not to duplicate any directives.

sudo nano /etc/nginx/nginx.conf
worker_processes <number-of-cores>;
worker_connections <core-limit>;
multi_accept on;
server_tokens off;
server_names_hash_bucket_size 64;
server_name_in_redirect off;

gzip on;
gzip_disable "msie6";

gzip_vary on;
gzip_proxied any;
gzip_comp_level 2;
gzip_buffers 16 8k;
gzip_min_length 1100;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/rss+xml text/javascript image/svg+xml application/x-font-ttf font/opentype application/vnd.ms-fontobject;

access_log off;

client_body_buffer_size 10K;
client_header_buffer_size 1k;
client_max_body_size 64m;
client_header_timeout 12;
client_body_timeout 12;

send_timeout 10;
large_client_header_buffers 2 1k;

Test Nginx Config and Restart Nginx if OK.

nginx -t
service nginx restart

Configure Nginx vhost

Create config file for virtual host.

pico /etc/nginx/sites-available/<domain-name>.conf
server {
  listen 80;
  listen [::]:80;

  root /var/www/<domain-name>/public/;
  index index.php index.html;

  server_name <domain-name>;
  charset utf-8;

  location ~* \.(?:manifest|appcache|html?|xml|json)$ {
    expires -1;
  }

  location ~* \.(?:rss|atom)$ {
    expires 1h;
    add_header Cache-Control "public";
  }

  location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm|htc)$ {
    expires 1M;
    add_header Cache-Control "public";
  }

  location ~* \.(?:css|js)$ {
    expires 1y;
    add_header Cache-Control "public";
  }                                                                                                                 

  location ~* \.(?:ttf|ttc|otf|eot|woff|woff2)$ {
    expires 1M;
    add_header Cache-Control "public";
  }

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

    auth_basic "Restricted";
    auth_basic_user_file /etc/default/htpasswd;
  }

  location ~ \.php$ {
    include snippets/fastcgi-php.conf;

    fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
    fastcgi_intercept_errors on;
  }
}

# Redirect www to non-www
server {
  server_name www.<domain-name>;
  return 301 http://<domain-name>$request_uri;
}

Create public directory in site folder.

mkdir -p /var/www/<domain-name>/public

Fix correct owner.

chown -R www-data:www-data /var/www/<domain-name>
sudo usermod -a -G www-data <username>
sudo chmod -R g+rw /var/www/<domain-name>

Enable vhost.

ln -s /etc/nginx/sites-available/<domain-name>.conf /etc/nginx/sites-enabled/<domain-name>.conf

Restart Nginx.

service nginx restart

Install PHP

apt-get -y install \
php7.0-fpm \
php7.0-mysql \
php7.0-curl \
php7.0-gd \
php7.0-intl \
php-pear \
php-imagick \
php7.0-imap \
php7.0-mcrypt \
php-memcache \
php7.0-pspell \
php7.0-recode \
php7.0-sqlite3 \
php7.0-tidy \
php7.0-xmlrpc \
php7.0-xsl \
php7.0-mbstring \
php-gettext

Configure PHP

Adjustments for php-fpm is based on the 2GB Digital Ocean setup.

pico /etc/php/7.0/fpm/pool.d/www.conf
listen.owner = www-data
listen.group = www-data

pm.max_children = 16
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pico /etc/php/7.0/fpm/php.ini
post_max_size = 64M
upload_max_filesize = 64M
date.timezone = America/New_York
mysql.default_socket = /var/run/mysqld/mysqld.sock
sed -i s/\;cgi\.fix_pathinfo\=1/cgi\.fix_pathinfo\=0/g /etc/php/7.0/fpm/php.ini;

Enable mcrypt.

phpenmod mcrypt

Install MySQL

aptitude install -y \
mysql-server \
mysql-client

POINT DNS A Record

ADD SSL To Webserver

sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install python-certbot-nginx

sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'

sudo certbot --nginx -d <domain-name> -d <domain-name>

SETUP LSYNCD

apt-get update
apt-get -y install lsyncd

Now we need to setup the default files and directories for our logs and settings

sudo mkdir /var/log/lsyncd
touch /var/log/lsyncd/lsyncd.{log,status}
sudo mkdir /etc/lsyncd

sudo nano /etc/lsyncd/lsyncd.conf.lua

Here's the default settings for the lsyncd config file Install on the primary server, and list all the servers that you want to copy to in this one file.

settings {
   logfile    = "/var/log/lsyncd/lsyncd.log",
   statusFile = "/var/log/lsyncd/lsyncd.status",
   statusInterval = 20
}
servers = {
 "<private-server-ip-to-copy-to>"
}
 
for _, server in ipairs(servers) do
sync {
    default.rsyncssh,
    source="/var/www/",
    host=server,
    targetdir="/var/www/",
    rsync = {
     archive = true,
     acls = true,
     verbose = true,
     rsh = "/usr/bin/ssh -p 22 -o StrictHostKeyChecking=no"
   },
}
end

SETTING UP A REMOTE MYSQL SERVER

apt-get update && apt-get dist-upgrade -y
apt-get autoremove -y

apt-get -y install mysql-server

mysql_secure_installation

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
bind-address            = <REMOTE IP ADDRESS OR 0.0.0.0 FOR ALL>

save and exit
mysql
CREATE USER '<username>'@'<REMOTE IP ADDRESS OR % FOR ALL>' IDENTIFIED BY '<PASSWORD>';
GRANT ALL PRIVILEGES ON <DATABASENAME>.* TO '<username>'@'<REMOTE IP ADDRESS OR % FOR ALL>';
FLUSH PRIVILEGES;
exit
service mysql restart
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment