Setting up a Low Resource VPS for Hosting

I plan on soon purchasing an inexpensive VPS for hosting websites and running some of the applications I have developed. My plan is to buy one of the cheapest services available and then optimize as much as I can to take advantage of the limited resources. Before I purchase a VPS, I am doing experiments on my 15 year old Dell Inspiron 700m to see just how much I can optimize the services I want to run. I plan to have web hosting, php, mysql, and maybe WordPress. Since the Inspiron is a single CPU with ~1GB of ram it is perfect for testing out what I can do.

First I start out with a clean Ubuntu 18.04 installation and the following are steps I’ve taken primarily to reduce the memory footprint since that seems to be the biggest limiting factor in cheap VPS’s.

LXDE: light GUI disabled by default

I installed LXDE as a light window manager along with Lubuntu. It works fine with 1GB of ram and should be fine with half that much. However, I will rarely be using it remotely so it should be disabled by default.
To disable:

systemctl set-default multi-user.target

To enable it by default:

systemctl set-default graphical.target

to turn it on as needed:

systemctl start lightdm.service

Disabling Services I don’t need

Disabling the following services saves RAM and I will give the rational why I don’t need them.
CUPS – this is a printer service. There are no printers anywhere near this server.

systemctl disable cups

NMBD & SMBD – These are two services related to network communication with windows PCs and file sharing. Completely useless in a Linux environment.

systemctl disable nmbd
systemctl disable smbd

RSYSLOG – If you search the web for disabling this service you’ll get a bunch of nerds telling you not to. I’ve worked on Linux development for years and the information in Kernel logs rarely tell you anything useful and it’s not worth the RAM and disk traffic it uses up. Chances are you don’t even know where these logs are stored so you’re not missing anything.

systemctl disable rsyslog

APPORT – This is a services related to error reporting. Since it doesn’t really do anything to STOP program crashes and errors, only reporting them to developers, it is useless to me.

systemctl disable apport

Disabling the above services reduces bootup RAM requirements by 10MB for me.

Installing LEMP stack for Ubuntu

Because of the RAM restrictions, I’m going with an Nginx web server instead of Apache. Nginx is supposedly faster, uses less ram, and supports more concurrent connections on low resource machines.

apt-get install nginx
apt-get install mysql-server-5.7
mysql_secure_installation

Go through the MySQL setup
Install PHP:

apt-get install php-fpm php-mysql

Configure php to work with Nginx.

nano /etc/nginx/sites-available/testing.com

then copy the following into the file:

server {
        listen 80;
        root /var/www/html;
        index index.php index.html index.htm index.nginx-debian.html;
        server_name testing.com;

        location / {
                try_files $uri $uri/ =404;
        }

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        }

        location ~ /\.ht {
                deny all;
        }
}

Enable the configuration:

rm /etc/nginx/sites-enabled/default
ln -s /etc/nginx/sites-available/testing.com /etc/nginx/sites-enabled/default 

Optimizing Services

Installing LEMP increases my baseline RAM by about 150MB, at idle! This needs be culled back.
For Mysql add the following to your config file in /etc/mysql/mysql.conf.d/mysqld.cnf to use MyISAM instead of Innodb. This will give decent performance with less overhead on light to medium traffic. Also I tweek some other parameters I’m not really sure what they do but I read about them on the internet. The DIFF for my file is below

 diff mysqld.cnf.backup mysqld.cnf
47,49c47,57
< key_buffer_size               = 16M
< max_allowed_packet    = 16M
< thread_stack          = 192K
---
>
> default-storage-engine=MyISAM
> default-tmp-storage-engine=MyISAM
> skip-innodb
> key_buffer_size               = 8M
> max_allowed_packet    = 1M
> sort_buffer_size      = 64K
> read_buffer_size      = 64K
> read_rnd_buffer_size  = 64K
> net_buffer_length     = 2K
> thread_stack          = 64K
50a59,60
> max_connections               = 10
>
61c71
< query_cache_size        = 16M
---
> query_cache_size        = 1M
87c97
< max_binlog_size   = 100M
---
> max_binlog_size   = 1M
105a116,125
> [mysql]
> no-auto-rehash
>
> [isamchk]
> key_buffer = 8M
> sort_buffer_size = 8M
>
> [myisamchk]
> key_buffer = 8M
> sort_buffer_size = 8M

FTP server

apt-get install vsftpd

Then you’ll want to change the default configuration. You should probably backup your /etc/vsftpd.conf file and then replace it with the following:

listen=NO
listen_ipv6=YES
anonymous_enable=NO
local_enable=YES
write_enable=YES
local_umask=022
dirmessage_enable=YES
use_localtime=YES
xferlog_enable=YES
connect_from_port_20=YES
chroot_local_user=YES
secure_chroot_dir=/var/run/vsftpd/empty
pam_service_name=ftp
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
pasv_enable=Yes
pasv_min_port=40000
pasv_max_port=50000
allow_writeable_chroot=YES
user_sub_token=$USER
local_root=/home/$USER/ftp

Then to add security use sftp. add the following to your /etc/ssh/sshd_config file:

Match group sftp
ChrootDirectory /home
X11Forwarding no
AllowTcpForwarding no
ForceCommand internal-sftp

Then you’ll want to create a SEPARATE user with the only purpose to use FTP, as ssh will not work. First create the sftp group, then the user to that group, set password, and restrict that user’s home directory to only be usable by that user(sftpuser).

addgroup sftp
useradd -m sftpuser -g sftp
passwd sftpuser 
chmod 700 /home/sftpuser/
mkdir /home/sftpuser/ftp

You can now login to the ftp server using sftpuser and the password you made.

Coding Development Environment

apt-get install git libmysqlclient-dev libunac1-dev gdb

Configuring firewall UFW

ufw allow ssh
ufw allow 22
ufw allow 'Nginx HTTP'
ufw enable