Server setup for Ubuntu 16.04 on Digital Ocean
The setup installs the following software:
apt-get update && apt-get dist-upgrade -y
apt-get autoremove -y
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
apt-get install -y \
build-essential \
python-software-properties \
python \
g++ \
make \
fail2ban \
apache2-utils \
curl \
bc \
git \
htop \
ntp \
ntpdate
dpkg-reconfigure tzdata
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
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
apt-get install -y nodejs
Update npm.
npm update -g
curl -sS https://getcomposer.org/installer | php -- \
--install-dir=/usr/bin \
--filename=composer
htpasswd -c /etc/default/htpasswd <htpasswd-username>
add-apt-repository ppa:nginx/development
apt-get update && apt-get install nginx-full -y
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.
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;
keepalive_timeout 15;
send_timeout 10;
large_client_header_buffers 2 1k;
Restart Nginx.
service nginx restart
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 <username>:<username> /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
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
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 = Europe/Stockholm
mysql.default_socket = /var/run/mysqld/mysqld.sock
Enable mcrypt.
phpenmod mcrypt
aptitude install -y \
mysql-server \
mysql-client