# 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/ -m -s /bin/bash usermod -a -G adm,cdrom,sudo,dip,plugdev ``` 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//.ssh cp /root/.ssh/authorized_keys /home//.ssh/ chmod 600 /home//.ssh/authorized_keys chown -R : /home//.ssh ``` Run `visudo` and add the following line at the end of the file. ``` 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 ``` ## 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 ; worker_connections ; 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/.conf ``` ``` server { listen 80; listen [::]:80; root /var/www//public/; index index.php index.html; server_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.; return 301 http://$request_uri; } ``` Create public directory in site folder. ``` mkdir -p /var/www//public ``` Fix correct owner. ``` chown -R : /var/www/ ``` Enable vhost. ``` ln -s /etc/nginx/sites-available/.conf /etc/nginx/sites-enabled/.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 ```