Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save imanilchaudhari/1f24652823b68480882f8c4eb7234533 to your computer and use it in GitHub Desktop.
Save imanilchaudhari/1f24652823b68480882f8c4eb7234533 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 \
python-software-properties \
python \
g++ \
make \
fail2ban \
apache2-utils \
curl \
bc \
git \
htop \
ntp \
ntpdate
```
## 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.
```
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
```
## 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 <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
```
## 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 = Europe/Stockholm
mysql.default_socket = /var/run/mysqld/mysqld.sock
```
Enable mcrypt.
```
phpenmod mcrypt
```
## Install MySQL
```
aptitude install -y \
mysql-server \
mysql-client
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment