Manage your logs using Logrotate

You have finally set up your own server and your application using this guide, and you feel proud that your app is now running in the vast web. A few days later, when you accessed your application’s URL, you are greeted with a Server Not Responding error! In panic, you SSH into your server to see what is going on, and soon find out that you have just run out of disk space.

What happened?

Most likely the reason is that your log files grew larger and larger as your application is running and it started eating through the entire disk. A couple of possible reasons are:

  • There is a background process that runs database queries every set amount of time, and those queries get logged
  • Using a background queue such as DelayedJob that continuously logs debug messages into the log file
  • Malicious scrapers and bots that repeatedly attempt to gain admin access to your application (by using common login paths such as those used in WordPress, etc)
  • Unnecessary logging of events that have large contents (e.g. logging entire objects or entire request data)

To prevent this scenario we need a way to make sure our logs are cleaned up automatically, so we don’t need to manually remove old logs as they have a tendency to be forgotten. One popular tool for this is a program called logrotate.

Logrotate works by making sure that your log files don’t grow in size unchecked. It compresses the log file and labels it with a timestamp so you can go back to older log files, while keeping the current log file contents only within the specified time range. For example, it can compress and archive logs at the end of the day every day so you begin with a fresh log file at the start of each day.

Installation

Let’s start by installing it, here we assume that we are using Ubuntu or any Debian-based system.

sudo apt-get update
sudo apt-get install logrotate

System Configuration

Logrotate’s configuration file can be found in /etc/logrotate.conf. Modify it using your preferred text editor.

sudo nano /etc/logrotate.conf

By default you will see something like this:

# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
# compress

This is the system or overall setting of logrotate. It is not recommended that we actually modify this file (although you can if you wish) and it is best practice to use specific configuration files for each log file we want to rotate/archive.

Custom Configuration

The custom configuration files are placed in the /etc/logrotate.d directory. We create a separate file for each log type so it is easier to modify and manage. For example, here is a configuration for rotating Nginx logs:

Start by creating the custom configuration file called “nginx”

sudo nano /etc/logrotate.d/nginx

The contents of the file looks like:

/opt/nginx/logs/access.log { daily rotate 30 compress delaycompress missingok notifempty copytruncate } /opt/nginx/logs/error.log { daily rotate 30 compress delaycompress missingok notifempty copytruncate } read more

Solutions for some SSH problems

SSH (Secure Shell) is one of the most useful tools in the Unix arsenal. It provides a secure way of logging in and connecting to a remote server, allowing users to access and control the remote system through the network.

This article will enumerate some of the common SSH use cases and potential problems as well as solutions for each.

Passwordless SSH

Normally, when you SSH to a remote server, you will be required to enter your password to that server:

~$ ssh [email protected]
Password:

If you are running automated scripts like Capistrano that needs SSH access to a remote system, this can pose a problem as it pauses the execution of your script. To solve this or if you just get tired of providing your password every time you SSH, then its time to utilize SSH public keys.

Public keys are used to identify your system with the remote system you are logging into. First you need to generate your public key using this command:

ssh-keygen -t rsa

~$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/marvs/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/marvs/.ssh/id_rsa.
Your public key has been saved in /home/marvs/.ssh/id_rsa.pub.
The key fingerprint is:
5b:ee:0a:c6:46:4e:3f:ed:27:38:8c:74:55:4d:93:78 [email protected]

You can press Enter for every prompt in the process and it should be ok. This will generate the public key in:

/home/USERNAME/.ssh/id_rsa.pub

Then copy the generated key into the remote server’s authorized_keys file. SSH provides a convenience method for this (assuming you are connecting to the “REMOTE” server with username “marvs”:

ssh-copy-id -i [email protected]

You can also manually copy the key using SSH:

cat ~/.ssh/id_rsa.pub | ssh [email protected] "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Which is basically a shortcut for:

[email protected]> scp ~/.ssh/id_rsa.pub [email protected]:~/[email protected] [email protected]> ssh [email protected] Password: windowphonebookchivas [email protected]> mkdir -p .ssh [email protected]> cat [email protected] >> ~/.ssh/authorized_keys [email protected]> rm [email protected] read more

Install WordPress on Ubuntu

wp_logo

WordPress is one of (if not) the most popular Content Management System (CMS) in the world today. Using WordPress, it is quite easy to get started on blogging and since it has an active community around it, you will get regular updates and improvements as well.

You can start a blog using several hosted options like WordPress.com or Blogger/Blogspot for free. However, this comes at the cost of losing full control over your blog and most often prevents you from adding your own advertising in your blog in case you want to monetize it. Having your own WordPress installation provides total control on all aspects of your blog, like look and feel, plugins, and sometimes even better security.

This article assumes that you have already set up your server. We will also set up WordPress to run on the nginx web server instead of Apache.

Install MySQL

WordPress uses MySQL as its database. In Ubuntu, its pretty straightforward to install MySQL:

sudo apt-get install mysql-server

During the installation process, it will ask for the root password. Take note of this root password as you will need it to set up your application later on.

The configuration file is located at:

/etc/mysql/my.cnf

By default no configuration is needed and the MySQL service should be up and running. If you edited the configuration file or just need to restart the service in case of an issue:

sudo service mysql restart

In case you misplaced the root password, you can re-set the password using this command:

sudo dpkg-reconfigure mysql-server-5.5

Just replace the version number with the one installed in your system.

Install Nginx

Nginx is one of the most popular web servers today and is used by many high performance websites and web applications.

Note: If you are deploying Ruby on Rails applications in your server, you can skip this step and instead just use the installed Nginx via the passenger gem. More details can be found in this article.

The Ubuntu/Debian package manager provides a simple way of installing Nginx:

sudo apt-get update
sudo apt-get install nginx

If you are using Red Hat or CentOS, a similar package can be installed using this command:

sudo yum install nginx

If you want the maximum flexibility on installation options, then you can install Nginx from source using this guide from the official website.

Install PHP

PHP is the scripting language that WordPress is built upon, as well as many more web applications including Facebook. We will install PHP via the PHP-FPM module:

sudo apt-get install php5-fpm

We also need to install the PHP wrapper for the MySQL database that WordPress uses:

sudo apt-get install php5-mysql

Configure PHP

After that, we update some of the settings in our PHP installation.

First, we disable the feature that allows URLs to be “guessed” and return the closest match. While this can be useful for some cases, this can be a security hole allowing malicious users to execute arbitrary files in your system.

Open the configuration file and set cgi.fix_pathinfo to false:

sudo nano /etc/php5/fpm/php.ini

cgi.fix_pathinfo=0

Then we also set the correct path where the web server will listen to:

sudo nano /etc/php5/fpm/pool.d/www.conf

listen = /var/run/php5-fpm.sock

We also need to set the appropriate permissions so that PHP can read our WordPress files:

sudo nano /etc/php5/fpm/php-fpm.conf

Add the following at the end of the php-fpm.conf file and replace deploy with the user account you are using in the server:

listen.owner = deploy
listen.group = deploy

If you fail to do this, you may encounter this error when running the web server:

connect() to unix:/var/run/php5-fpm.sock failed (13: Permission denied) while connecting to upstream

Restart the php-fpm program to apply the changes:

sudo service php5-fpm restart

Set up the WordPress server block

In the main Nginx configuration file, we can see this line:

include /etc/nginx/sites-enabled/*;

This means that Nginx also looks at the /etc/nginx/sites-enabled directory for additional configuration and includes files inside that directory. This is helpful in organizing server block configurations in the system especially if you are running multiple applications.

We then create the server block for WordPress under this directory:

sudo nano /etc/nginx/sites-enabled/wordpress.conf

In the wordpress.conf file, put in the following:

server { listen 80; server_name mydomain.com www.mydomain.com; root /var/www/blog; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?q=$uri&$args; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root /var/www/blog; } # pass the PHP scripts to FastCGI server listening on the php-fpm socket location ~ \.php$ { try_files $uri =404; fastcgi_pass unix:/var/run/php5-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } read more

Deploying Rails apps using Capistrano

Capistrano Logo Deploying your application to the web is not a one-time thing. There will be changes to the application code, new assets to include, database updates, and so on. Applying these changes to your web server includes a list of commands that we need to do every time we need to deploy.

Capistrano solves this problem by automating the deploy process so you can execute all of the steps in a single command. Automation prevents user errors while deploying like forgetting the precompile task when assets have changed, missing database migrations, and remembering the sequence of commands. Automation also enables your infrastructure to scale so that your code is automatically deployed to all application servers without logging in to each one to manually deploy your code.

In order to use Capistrano, you need to set up your web server first (we will use Nginx in this article). If you have already done this, please skip the first section of the article and proceed to installing and setting up Capistrano.

Note: This article assumes that you have already set up your server and are using Ruby on Rails as your application framework.

Nginx

Installation

We will install Nginx via the Passenger gem.

In order to do this, we need root privileges. If you are using RVM, it already provides a sudo command called rvmsudo, but if you are using rbenv, you need to install the rbenv-sudo plugin first:

git clone git://github.com/dcarley/rbenv-sudo.git ~/.rbenv/plugins/rbenv-sudo

We then install the passenger gem by adding this line to our Gemfile:

gem 'passenger'

Then install the gem and its binaries:

bundle install

And if you are using rbenv, update with the newly installed binaries:

rbenv rehash

We are now ready to install Nginx via Passenger:

If you are using RVM:

rvmsudo passenger-install-nginx-module

If you are using rbenv:

rbenv sudo passenger-install-nginx-module

Compared to installing Nginx via the Ubuntu package manager (sudo apt-get install nginx) this method of installing Nginx does not provide the start and stop scripts so we can conveniently control the web server process. Thus we need to manually provide this init script in our system:

wget -O init-deb.sh https://raw.github.com/JasonGiedymin/nginx-init-ubuntu/master/nginx
sudo mv init-deb.sh /etc/init.d/nginx

There is a small change that needs to be done in our init script, which is to specify the location of the Nginx install. By default this is located at /opt/nginx, so we set it accordingly:

sudo nano /etc/init.d/nginx

NGINXPATH=${NGINXPATH:-/opt/nginx}      # root path where installed

We make our init script executable:

sudo chmod +x /etc/init.d/nginx

Then we also set it so that Nginx runs automatically when you reboot the system:

sudo /usr/sbin/update-rc.d -f nginx defaults

Rails application server block

We will place all our application code in /var/www/. Make sure that the deploy user that we created has read and write access to this directory.

Next we need to configure Nginx so that it runs our code in /var/www/. Nginx provides a simple way to organize our server configuration in server “blocks” which is very useful especially if we are running multiple applications in the same server. It will look for additonal configuration in the /etc/nginx/sites-enabled directory and includes it when running the web processes.

However, we will not be putting our configuration directly in /etc/nginx/sites-enabled, instead we will create them in the /etc/nginx/sites-available directory. In this example, we assume we have a Rails application called myrailsapp.

Create and edit a new file called myrailsapp.conf in the sites-available directory:

sudo nano /etc/nginx/sites-available/myrailsapp.conf

In the empty file, put in the following:

server {
  listen       80;
  server_name  mydomain.com www.mydomain.com;
  root /var/www/myrailsapp/current/public;
  # passenger_min_instances 4;

  location / {
    passenger_enabled on;
  }
}

If you are using SSL certificates for your domain, place the certificate/certificate bundle and the key file in the /etc/nginx/ssl directory, then add the following as well in the myrailsapp.conf file:

server { listen 443; server_name mydomain.com www.mydomain.com; root /var/www/myrailsapp/current/public; # passenger_min_instances 4; ssl on; ssl_certificate /etc/nginx/ssl/mydomain_bundle.crt; ssl_certificate_key /etc/nginx/ssl/mydomain.com.key; # Forward secrecy settings ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS +RC4 RC4"; location / { passenger_enabled on; } } read more

Install Ruby on Rails on Ubuntu

Ruby_on_Rails-logoAfter you set up your server, its time to deploy applications into it. One of the most popular web application frameworks is Ruby on Rails. This is built using the Ruby programming language and it enables developers to create web applications ranging from quick prototypes and Minimum Viable Products (MVPs) up to large distributed applications. Rails is an opinionated framework, meaning there is a standard way of doing things, but it can also be modified to suit your preferred architecture and coding style. By default however, Rails provides sensible and secure defaults that will help you run and deploy your applications quickly. Through using Ruby gems to augment functionality, you can create a fully-functional web application in a short amount of time.

We will start the process by setting up the dependencies needed for Ruby on Rails.

(Updated March 2018)

Install Git

Git is perhaps the most popular version control system today. By utilizing small functions and commands that do only one task (and does it well), it achieves tremendous flexibility and power.

Git is basically a command-line tool, however there are several graphical user interfaces (GUIs) built that support all major operating systems. A sample list can be found at https://git-scm.com/downloads/guis.

If you are using Ubuntu or any other Linux distribution, you can install git using the default package manager:

sudo apt-get install git

It is useful to specify global parameters in git, like your name and email address so that you do not need to specify it whenever you push to your repository.

git config --global user.name "Juan dela Cruz"
git config --global user.email "[email protected]"

To list the git configurations in your system:

git config --list

Install Ruby

Ruby is a programming language designed for developer happiness. It provides an elegant syntax that makes programming enjoyable. As Ruby on Rails is built on Ruby, we need to install Ruby itself in the system.

First we need to install the dependencies needed to compile and install Ruby. If you are using Ubuntu, this is as simple as the below command (other operating systems will have their equivalent packages):

sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev

If you plan on using ImageMagick for image processing in your application, like if you have a photo upload feature that requires the image to be resized, you also need to install these dependencies:

sudo apt-get install imagemagick libmagickwand-dev

Managing Ruby versions

There are times when you need to run applications using different Ruby versions. In this case it is important to properly manage the Ruby versions installed in your system. Two of the most popular version managers are RVM and rbenv. As these two work essentialy the same, it is up to you which one you should choose to use. There are arguments that RVM muddles more on your system than rbenv, although personally I have used both in my projects and they both work quite well.

In this article we will use rbenv as our Ruby version manager. If you opt to use RVM instead, their website includes a tutorial on how to install RVM.

Basically we will fetch a predefined install script from the git repository and run that script in our system. Security-aware individuals may cringe at this method, but at the moment this is the simplest and quickest way to install programs.

git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL

Then we install the script that makes it easy to build, compile and install Ruby:

mkdir -p "$(rbenv root)"/plugins
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

Once that is all set, we are now ready to install Ruby using rbenv:

rbenv install --list
rbenv install -v 2.4.3
rbenv global 2.4.3

Just replace the version number with the Ruby version you want to install. You can also install Ruby from source but take note that doing this will install Ruby in your local system and will not be managed in rbenv.

Install Bundler and Rails

When you installed Ruby, the package manager called Rubygems is also installed by default. Rubygems lets you install Ruby libraries called gems that provide specific functionality that you can include in your application. Ruby on Rails, the application framework that we will use, is also packaged as a gem. Ruby Toolbox is an awesome tool to find gems depending on your desired usage, and ranks it by popularity or activity.

When installing Ruby gems, the documentation is also installed by default. While there are cases when this local documentation is useful, most of the time you can refer to the internet for the documentation when you need it. You can opt not to include the gem documentation when you install gems and this will make the install faster and will consume less disk space.

To exclude the documentation when installing gems, use this command:

gem install rails --no-rdoc --no-ri

As typing this whenever you install gems can be tedious, you can also make this as the system default. Add the –no-document flag to your gemrc file:

echo "gem: --no-document" > ~/.gemrc

Make sure that Rubygems is updated to the latest stable version:

gem update --system

Now we are ready to install Bundler and Rails

gem install bundler
gem install rails

Bundler makes it easy to manage gems in your application using a configuration file called a Gemfile where you specify which gems and versions your application uses.

After installing new gems, we need to tell rbenv to use the latest binaries/executables that are included in the new installs.

rbenv rehash

Install a Javascript runtime library

Ruby on Rails’ asset pipeline requires a Javascript runtime library to be installed as well. Therubyracer is a Ruby gem that you can use for this purpose, however, the gem’s size can be an issue.

I recommend installing NodeJS and use it as the runtime library. You can install it from source from their home page, or you can use Ubuntu’s package manager to install it for you:

Add the NodeJS repository so Ubuntu can fetch it:

curl -sL https://deb.nodesource.com/setup | sudo bash -
sudo apt-get update
sudo apt-get install nodejs

Set up the database

A fully-functional web application needs a database to run. There are many free and available databases available and you should pick one that suits your needs. Relational databases like MySQL and PostgreSQL and document-oriented databases like MongoDB are some of the most popular choices.

In this article we will set up either MySQL or PostgreSQL.

Install MySQL

In Ubuntu, its pretty straightforward to install MySQL:

sudo apt-get install mysql-server

During the installation process, it will ask for the root password. Take note of this root password as you will need it to set up your application later on.

The configuration file is located at:

/etc/mysql/my.cnf

By default no configuration is needed and the MySQL service should be up and running. If you edited the configuration file or just need to restart the service in case of an issue:

sudo service mysql restart

In case you misplaced the root password, you can re-set the password using this command:

sudo dpkg-reconfigure mysql-server-5.5

Just replace the version number with the one installed in your system.

Install PostgreSQL

In Ubuntu, install the following packages:

sudo apt-get install postgresql postgresql-contrib libpq-dev

During the installation process, it will set up a default user called postgres. We will use this default user to create the database user we will use in our applications. In this example, we will create the pguser user.

sudo -u postgres createuser -s pguser

We then change the password of pguser using the PostgreSQL console:

sudo -u postgres psql

Inside the console, type the following commands:

\password pguser
...
(change password prompt)
...

While we are in the console, we can also create the PostgreSQL database that our application will use, and set the pguser user as the database owner so we get full access:

CREATE DATABASE webapp_development OWNER pguser;
\q

Create a new Rails application

Now that we have Ruby and a database installed, we can now create our Rails application. Let’s start by calling Rails’ new command to set up our application (called “awesomeapp” in this example).

rails new awesomeapp

Rails will automatically generate files inside the “awesomeapp” folder that contains everything necessary to run your application. It will also try to run bundle install and install the default Ruby gems set by Rails.

Open the Gemfile in the application folder and add the database wrapper gem that you need to use:

source 'https://rubygems.org' gem 'rails', '4.2.4' # If you are using MySQL gem 'mysql2' # If you are using PostgreSQL gem 'pg' # If you are using MongoDB gem 'mongoid' gem 'bson_ext' ...(your other gems below)... read more