I used an older Thinkpad model to test my setup

How to install WordPress on a CentOS 7 / RHEL 7 server

This how-to explains the necessary steps to install WordPress, the popular blogging platform, on your own CentOS 7 server. Hosting WordPress yourself can have several advantages: It gives you full control over your setup, your learn something and in my case it also led to significant improvements in speed and responsiveness of my page.

When I tried to install WordPress on a CentOS 7 server myself, I discovered that many of the how-tos available on the Internet were either outdated or led to configuration issues. Some tutorials were also outright insecure. Therefore I decided to write a blog entry that sums it all up and leads to a reasonably secure and also performant web server for WordPress.

Overview: Install and configure Nginx, PHP, MySQL/MariaDB and SELinux on CentOS 7 to run WordPress

This guide will cover the following topics, which is basically setting up a LEMP-stack (=Linux, Nginx, MySQL, PHP) plus WordPress. In the end some thoughts on performance tuning and security will be given.

Overview and links to the different parts of this blog entry:
Prerequisites
How to install Nginx, the webserver
How to install MariaDB, a MySQL database
How to create a database in MySQL/MariaDB for WordPress
How to install PHP
How to configure Nginx for WordPress
How to install WordPress
How to configure SELinux to make it work with WordPress
How to install phpMyAdmin and secure it to manage the database
Performance and security tweaks for your setup

This guide is for CentOS 7, but it should also work wit Redhat Enterprise Linux RHEL 7. In addition, Fedora Linux should be similar as well.

In the future I will also include how to set up SSL for your server. That being said, this guide comes with no warranty. Feel free to comment below if you have feedback.

Prerequisites

The prerequisites are that you have a server with CentOS 7 installed. The initial server setup is explained very well in this guide.

Installation of NGINX

To install Nginx, you have to activate the Centos 7 EPEL repository:
sudo yum install epel-release

Afterwards, you can install Nginx:
sudo yum install nginx

Start the service:
sudo systemctl start nginx

And open port 80 for http in your firewall and reload the firewall:
sudo firewall-cmd –permanent –zone=public –add-service=http
sudo firewall-cmd –reload

Now you can test your server by opening a browser:
http://(your IP)

If all went well, you should see the default welcome page of Nginx.

The next step is to make sure Nginx is loaded automatically during startup. If you later on do not wish to start Nginx automatically with each boot, just run the command below with “disable” instead of “enable”:
sudo systemctl enable nginx

The configuration of Nginx will be done further below in this blog post.

Installation of MariaDB

To run WordPress, we need a MySQL database. The open version of it is called MariaDB and is fully compatible with MySQL.

Install MariaDB on your server like this:
sudo yum install mariadb-server

After installation, enable it that is loaded automatically and start it:
sudo systemctl enable mariadb
sudo systemctl start mariadb

A very important step is to secure the database. MariaDB is shipped with a standard script that sets a root password and also increases the security of your installation. Run the script, set the root password and accept all other default options on the remaining questions. It asks for example whether to remove anonymous users (-> yes!) or disallow root login from remote (-> yes!). Run the script like this:
sudo mysql_secure_installation

Finally, edit the main configuration file. Here you need to ensure that the database only binds to the local address (i.e. that it cannot be accessed from the Internet) by setting the “bind-address” to 127.0.0.1. Also, the database has no business to look at your data, therefore access to local files should be disabled by setting the local-infile option to 0.
sudo nano /etc/my.cnf

Excerpt with the changes highlighted:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
bind-address = 127.0.0.1

#Disable access to local files
local-infile=0

Setting up a database for WordPress

Now everything is in place to actually create the database for WordPress that you will need later on. To do this, login to MariaDB with root.
Since we ran the script to secure the db installation before, it should ask for the MariaDB-root password now:
mysql -u root -p

Once you are logged in, you can create the database that is here called “wordpress”:
create database wordpress;

WordPress should not use the root user to access the database, therefore the next step creates another db user called “dbuser” with the password “password”. Please change to a different password and note the exact syntax of the command. The username has to be put written inside of ‘apostrophes’ and the password as well. The command needs to be closed with a semi-colon:

create user dbuser@localhost identified by 'password';

If all went well, MariaDB should respond like this:
MariaDB [(none)]> create user ‘dbuser’@localhost identified by ‘password’;
Query OK, 0 rows affected (0.00 sec)

Now is the time to give this new dbuser access to the database “wordpress” we created in the step before. This is done like this:

grant all on wordpress.* to 'dbuser' identified by 'password';

Now you are done in the database console and can write “exit” to exit:
exit

Installation of PHP

The next step is to install PHP. This is done like this:
sudo yum install php php-mysql php-fpm

Afterwards, you need to edit a few configuration files. Open php.ini first:
sudo nano /etc/php.ini

Scroll to the “paths and directories” section, and make sure the cgi.fix_pathinfo is set to null. This is an important security setting that tells php to only search for and execute the exact filename it receives. With the default setting, PHP would attempt to execute the closest file match. For example, if the file script.php is not found, but a file script.jpg is found, PHP would execute the latter one. This would allow users to run code in PHP that they should not be allowed to. Setting this to 0 solves this problem:

Paths and Directories section:
cgi.fix_pathinfo=0

Afterwards, scroll down to the “file uploads” section of php.ini and increase the maximum upload file size. The default was too low in my case, so I set it to 200 MB. Choose whatever fits you best. This is needed in the future, when you for example import a database via phpMyAdmin or when you upload other files via php:

File uploads section
upload_max_filesize = 200M

Now, open the www.conf configuration file that resides in /etc/php-fpm.d/www.conf:
sudo nano /etc/php-fpm.d/www.conf

Change the listen option like this. This makes sure PHP uses a socket:
listen = /var/run/php-fpm/php-fpm.sock

Further down in the file, uncomment the listen owner and group and make sure it is set like this:
listen.owner = nobody
listen.group = nobody

In addition, change user and group to nginx:
user = nginx
group = nginx

Afterwards, we can start and enable PHP:
sudo systemctl start php-fpm
sudo systemctl enable php-fpm

Configuration of Nginx

Now you need to configure Nginx so that it can handle PHP files. Open the main configuration file in /etc/nginx/nginx.conf. Nginx uses a modular setup. That means you can put the configuration of the servers (similar to virtual hosts in Apache) for example to /etc/nginx/conf.d/* or /etc/nginx/default.d/*. In this tutorial, for the sake of simplicity, I configured Nginx only by using the main configuration file. This has the advantage that you can see every everything in one file only. Please make sure that the /etc/nginx/conf.d/* and /etc/nginx/default.d/* directories are empty.

Now open the main configuration file
sudo nano /etc/nginx/nginx.conf

Remove everything and replace it with the following content. The only part you need to update is to replace YOURHOSTNAME with the hostname of your server, for example domain1.com or example.dyndns.org, in line 45:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;
   
    #set uploads by users to 100 MB
    client_max_body_size 100m;

    #root directory and index definition for http (general)
    root   /usr/share/nginx/html;
    index index.php index.html index.htm;

    #Default server - 
    server {
	listen 80 default;
        return 404;         
       }

    server {
    listen       80;
    server_name  YOURHOSTNAME;

    location / {
        try_files $uri $uri/ /index.php;
    }
    
    error_page 500 502 503 504 /50x.html;    
    location = /50x.html {
        root /usr/share/nginx/html;
    }
    
    error_page 404 /404.html;
    location = /404.html {
        root /usr/share/nginx/html;
    }
      
    #adds expiry date for static content
    location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public";
     }    

   # location /database {
   #     auth_basic "Please login";
   #     auth_basic_user_file /etc/nginx/pma_pass;
   #	}

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    #prevents .htaccess files from being downloadable
    location ~ /\.ht {
        deny  all;
    }
  
    # Prevents php uploaded in uploaddir from being executed
    #location /uploaddir {
    #    location ~ \.php$ {return 403;}
    #        # [...]
    #        }

}

    # Compresses certain files for better performance
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 1000;
    gzip_types text/plain text/css application/javascript 
    application/json application/x-javascript text/xml application/xml 
    application/xml+rss text/javascript application/vnd.ms-fontobject 
    application/x-font-ttf font/opentype image/svg+xml image/x-icon text/x-js;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

}

A few comments on the configuration

These comments are just made for further understanding. If you like you can skip this part, more on the security and performance tweaks can be found at the end of this tutorial.

This allows users to upload files up to 100MB through the server. Adjust the value to your liking:

#set uploads by users to 100 MB
    client_max_body_size 100m;

This defines the root directory for Nginx. It is valid for all servers (servers are like virtual hosts in Apache). This is also the directory where WordPress will be put. The index directive returns the first file it can find. I.e. index.php is served before index.html, for example:

#root directory and index definition for http (general)
    root/usr/share/nginx/html;
    index index.php index.html index.htm;

This configures the server for WordPress. Replace YOURHOSTNAME with the right name, i.e. example1.com or example.dyndns.org, etc:

 server {
    listen       80;
    server_name  YOURHOSTNAME;

The following parts handles how webpages are opened. This is needed for example for WordPress posts that have the title in the URL:

 location / {
        try_files $uri $uri/ /index.php;
    }

Now custom error pages are defined. They are actually rarely used because most of the time you will see the 404 page from WordPress itself:

error_page 500 502 503 504 /50x.html;    
    location = /50x.html {
        root /usr/share/nginx/html;
    }
    
    error_page 404 /404.html;
    location = /404.html {
        root /usr/share/nginx/html;
    }

This part tells Nginx how to handle PHP files and forward them to PHP via the socket connection:

 location ~ \.php$ {
        try_files $uri =404;
        fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

There are some other parts in the configuration file that I will explain in the performance enhancement section of this post.

Installation of WordPress – First Part

Now the preparation is finished and you finally start the installation of WordPress. We go to the directory /usr/share/nginx/html where the html is stored:

sudo cd /usr/share/nginx/html

and download WordPress:

sudo wget http://wordpress.org/latest.zip

We unzip the file:

sudo unzip latest.zip

and move the contents from the ./wordpress-folder into our html directory:

sudo mv wordpress/* .

Then we remove the empty worpress directory and the downloaded “latest.zip” file:

sudo rmdir wordpress
sudo rm latest.zip

Finally, we set the correct permissions so that Nginx can read and write correctly:

sudo chown nginx.nginx -R .

Now WordPress is unpacked and we are almost ready to go, almost!

SELinux

It took me a long time to figure out why my WordPress was not working as expected until I found out that at this point of the installation you need to take care of SELinux. SELinux is a linux kernel security module that is enabled on default in CentOS. It enforces access control policies and manages which program is allowed to do what. SELinux can be sometimes a pain in the back to configure and I saw some other how-tos that simply disabled it. However, I did not want to simply disable it, but to find the correct configuration. Since most of the documentation is made for Apache, it took a while to figure out what to do.

The trick is that although Nginx got the correct file permissions in the last step above, it still needs to be granted permissions to write and execute for certain directories for WordPress. In my case, I wanted WordPress being able to update itself automatically and it should also be possible to install themes and plugins from the dashboard. This means that Nginx needs to be able to write and execute in some directories. This can be done like this.:

The first two commands tell SELinux where Nginx is allowed to execute php files:

sudo chcon system_u:object_r:httpd_sys_script_exec_t:s0 /usr/share/nginx/html/*.php
sudo chcon system_u:object_r:httpd_sys_script_exec_t:s0 /usr/share/nginx/html/wp-includes/*.php

The next commands allows Nginx to to read and write. Adjust the first command to whereever your “upload” directory is located:

sudo chcon -R system_u:object_r:httpd_sys_rw_content_t:s0 /usr/share/nginx/html/wp-content/uploads
sudo chcon -R system_u:object_r:httpd_sys_rw_content_t:s0 /usr/share/nginx/html/wp-content/upgrade
sudo chcon -R system_u:object_r:httpd_sys_rw_content_t:s0 /usr/share/nginx/html/wp-content/themes
sudo chcon -R system_u:object_r:httpd_sys_rw_content_t:s0 /usr/share/nginx/html/wp-content/plugins
sudo chcon -R system_u:object_r:httpd_sys_rw_content_t:s0 /usr/share/nginx/html/wp-content

Installation of WordPress – Second Part

Now you can install WordPress. Simply open a webbrowser and access your server with it’s IP or hostname:

http://localhost or http://HOSTNAME

Then follow the instructions. Remember to use the database user details we set up above with username “dbuser” and “password”, depending on what you set up.

Installation of phpMyAdmin

When working with WordPress it can come in handy to look at the database from time to time. Especially when making or restoring backups. For this I like to use phpMyAdmin, which is a database administration tool with a web interface.

Install it like this:
sudo yum install phpmyadmin

Then create a link between the directory phpMyAdmin resides in and the root directory for Nginx:
sudo ln -s /usr/share/phpMyAdmin /usr/share/nginx/html

Adjust the permissions for Nxinx and PHP:
sudo chown -Rfv root:nginx /var/lib/php/session

Afterwards, restart PHP:
sudo systemctl restart php-fpm

The next step is important for security reasons: If you have phpMyAdmin installed in the default location, everybody knows that it can be accessed by going to http://yourdomain.com/phpMyAdmin. This is a security risk because somebody could brute force his or her way into your database. Therefore, rename directory. In this example it is renamed to “database”, but better choose something more difficult to guess:
cd /usr/share/nginx/html
sudo mv phpMyAdmin database

In addition, we will password-protect phpMyAdmin from the webserver side. To do this, create a password and hash it through this function.
openssl passwd -1

Now create a new file called pma_pass:
sudo nano /etc/nginx/pma_pass

In this file, add a username of your liking and the encrypted password:
username:encryptedpassword

Then, open the nginx.conf file and uncomment the following section. This tells Nginx to ask for a password when you open ../database:

location /database {
        auth_basic "Please login";
        auth_basic_user_file /etc/nginx/pma_pass;
	}

Now, restart nginx:
sudo systemctl restart nginx

You are now able to access phpMyAdmin at http://yourserver/database

Security and Performance tweaks

First of all, as I already mentioned in the introduction, make sure you have secured your server in general. Important is that your server is up-to-date with the latest software, that the firewall is on and only lets http and ssh through and that SSH itself is secured. How to do this is beyond the scope of this article, but you can have a look at this guide.

For the webserver, I added the following configuration for security and performance. The configuration is already included in the nginx configuration file above.

I defined a default server that listens on port 80 and replies with a 404 message. The reason is that when I later on host several domains with different hostnames, I only want to “activate” the hostnames. Let’s assume my IP is 127.0.0.1 and I host www.example1.com and www.example2.com. If I only enter the IP, a 404 error will come, if I enter any of the domains (=hostnames), the right page will be served.

#Default server 
    server {
	listen 80 default;
        return 404;         
       }

This part of the configuration adds an expiry date for static content. This improves the rating of your page when you run it through speed test websites:

#adds expiry date for static content
    location ~* \.(ico|css|js|gif|jpeg|jpg|png|woff|ttf|otf|svg|woff2|eot)$ {
        expires 30d;
        add_header Pragma public;
        add_header Cache-Control "public";
     } 

Just in case you are switching from Apache or import files to your webserver that use .htaccess (Nginx does not use it!), the following prevents that a website visitor can download those files and look at usernames for example:

 #prevents .htaccess files from being downloadable
    location ~ /\.ht {
        deny  all;
    }

The following excerpt prevents php from being executed in the upload directory. Uncomment and change it to the directory you need:

    # Prevents php uploaded in uploaddir from being executed
    #location /uploaddir {
    #    location ~ \.php$ {return 403;}
    #        # [...]
    #        }

Lastly, this part uses compression for text-based files which improves the loading time of your website:

    # Compresses certain files for better performance
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_min_length 1000;
    gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml 
    application/xml+rss text/javascript application/vnd.ms-fontobject application/x-font-ttf 
    font/opentype image/svg+xml image/x-icon text/x-js;

Done!

Now everything should be set up. Feel free to test, comment and give feedback!

Asian Adventure: Jakarta – A Capital With Heart and Traffic

The second destination of the South-East Asia tour after Singapore was Jakarta, the capital of Indonesia.

Thunderstorms, Tropical Rain and White Light

The flight from Singapore to Jakarta takes about 2 hours. I flew with AirAsia in one of their brandnew Airbus A319/320. The space on the plane was similarly to Ryanair quite tight, however, you could buy a variety of warm food on the flight.

Street vendor selling fruit in Jakarta, Indonesia

Street vendor selling fruit in Jakarta, Indonesia

The Indonesian capital greeted me with thunderstorm and heavy, tropical rain. It was as if you put the shower on. The humidity was at 100%. Another thing I noticed from the car when leaving the airport: The lights you see are different from Europe. Mostly fluorescent neon lights are used that put everything into a cold, white/blueish light.

Not A Tourist City, Yet Much To Experience

Jakarta is not a tourist city. During the entire stay of about a week, I saw only a handful of visitors in some shopping malls. Jakarta is huge. More than 10 Million people live in this metropolis. What is interesting though, is that the Jakarta is divided into “cities within the city”. In European cities, you often have to go to the other end of the town to get something done. In Jakarta, everything you need is availably within your immediate area.

Flooded highway on the way from the airport into Jakarta

Flooded highway on the way from the airport into Jakarta

The huge amount of people also means that there is a lot of traffic. There is no subway system, hence everybody is using their car or a motorcycle to get from A to B. There is also an express bus system where the buses have their own lanes. Cars and motorcycles must not use the bus lanes, however, nobody seems to care and not even physical barriers seem to hinder cars driving there.

In addition to the sheer amount of cars, the traffic is also very dense. I was very suprised that I did not see any accident, especially since the motorcycles constantly overtake the cars. Timewise, it is quite usual to be 30 minutes in a traffic jam to drive 7 kilometers of road.

Everything Under 30 degrees Is Cold

In contrast to Singapore, many buildings in Jakarta are not fully air conditioned. The installed air conditioning vents make it just “less hot”. It also seems to me that Indonesians have a different sense of temperature: Everything below 30 degrees Celsius is perceived as “cold”.

Traffic in Jakarta - Bus express lane on the right

Traffic in Jakarta – Bus express lane on the right

Many things are less organized (or not organized at all) than in European cities. For example, there is a constant smell of fire in the air because there is always somebody burning something somewhere. Add to that the exhaust from the cars, the chemicals against the Dengue mosquitoes and the humidity and it feels “as if you are breathing cloth” as somebody said. However, I found the air to be not that bad, I had more problems with the heat.

City of Contrasts

Jakarta is also a city of contrasts. While on the one side you can see big luxorious villas with expensive cars parking there, you see on the other side also slums where people live in small hats by a river that carries the sewage water. On some highway entry roads, you also see day laborers waiting to get work for the day.

In other areas, Jakarta can easily match up with other big capitals. There are many restaurants and an extremely well-organized take away service. You can just call and after about 30 minutes someone comes and brings you the food right to your doorstep. Jakarta has also numerous shopping malls and they are top-notch, just like in Singapore or in the US. Prices for luxury goods are of course cheaper than in other cities, but still they cost money.

Another good point: I bought a 3G SIM card for my iPad to surf on the Internet. 3G was often faster than the Wifi offered in restaurants or domestic connections. I could even use it to call home with Skype.

Asian Adventure: Efficient Singapore

It finally happened. I went to a place, I never thought I would travel to. Too far away, too crowded, “out of area”. Or actually not: I travelled to South-East Asia. Singapore, Jakarta, Ubud.

This blog post is about the first destination: Singapore.

Marina Bay Sands Hotel in Singapore

Marina Bay Sands Hotel in Singapore

The Flying Sofa

The route went from Oslo to Copenhagen to Singapore. Singapore Airlines was the carrier of choice, and that choice was a good one: In Economy class on the Boeing 777-200 the seats were wide and the service superb.

Before takeoff, the flight attendands who are dressed in traditional Singaporean clothing handed out a menu. Showing like in a restaurant what would be served during the flight, food and drinks could be ordered anytime during the flight. Only the hot meals were served at fixed times.

The time during the 12 hour flight passed by quickly, partly thanks to the excellent choice of movies and music from the entertainment system. I have never flown a more comfortable airline than Singapore Airlines: The service was friendly, the food was excellent, and I could sleep on standard Economy seats. Hence, I called it the flying sofa.

Cheap, Humid and Crowded

I always thought “Asia is cheap, humid and crowded”. After landing in Singapore, I figured out it is actually true. Only that it is not that cheap. Prices in Singapore are only slightly lower than prices in Germany.

Since Asians tend to avoid the sun, and since it is too hot outside anyway, the main attraction are the city’s numerous shopping malls. Usually, the metro stops directly transition into a mall. You never know where the metro stop ends and where the mall begins and vice versa.

Popular in these malls are expensive European or American luxury brands. And since Singaporeans seem to have money, these boutiques are crowded. Second most important after the malls is the food: Every mall has a food court that offers a wide choice of Asian and Western food. Remember to NEVER order anything that is spicy. When they say it is “a little spicy”, it is usually too hot.

Otherwise, Singapore presents itself as a highly-efficient city. Everything is regulated, misbehavior like drinking or eating in the metro is heavily fined. The city is very clean. You never see litter lying around.

Heartless Efficiency?

This efficiency has only one drawback: It sometimes feels a bit heartless. If you have a problem that does not fit into the Singaporean’s “Standard Operating Procedures” you have lost.

The Metro "MRT" in Singapore. Highly efficient and very clean.

The Metro “MRT” in Singapore. Highly efficient and very clean.

Example: The Singapore Flyer is a kind of ferris wheel that allows you to see the city from above. “Last admission 22.15” it says on their website. Arriving at 22.07 at the ticket office, happy to have made it just in time before closing, I learn that the last ticket sale closes at 22.00. After kindly asking and only getting a “no” as an answer, I see that it is hopeless to get in and let go of this attraction. A visit is not possible for me.

50 Grades of Snow

When I grew up, I read somewhere that the Inuit had a large number of words to describe snow. At the time, snow was just snow for me – white and cold. After living in Scandinavia for a while, I start to understand the different types of snow and ice.

Slippery or not?

To know the types of snow and ice is important. It can help to answer the main question: Is the street slippery or not? When I first came to Scandinavia, I quickly realized that snow is not just snow. For example, when it is below minus 12 degrees, almost any snow that is on normal streets is very compact and hard, making it easy to walk. Just like on the normal asphalt.

If the temperature get warmer, the “ugly” range is from -3 until +2 degrees. Here the snow is not really melting yet, but instead becomes more fluffy and dangerously slippery. Above +2 degrees, it is so warm, that the snow is just wet. It is not nice to walk on, but it is less slippery similarly to when it is raining.

Icy road topped with sand to make walking easier

Icy road topped with sand to make walking easier

If the temperature then falls again and it freezes, the wet snow becomes ice. Then again it can become very slippery. Drops the temperature again below -5 even the icy parts are easier to walk on.

Snow clasification

This snow classification is of course not an exact science. To be able to describe the snow conditions is also important for skiing. After going on a cross-country tour, I was asked by a Norwegian colleague immediately how the snow was, how the top layer was, the consistency and all kinds of details I had never imagined.

To know the snow also shows that you are not an outsider. People who have just arrived and walk too slow and too careful immediately stand out.

Working in Norway: Dress code at the job

Wrote an article about the different ways to dress on the job in Norway as a man. It got published in one of Germany’s best news papers, Die Zeit:

Dress code in Norway - My article published in Die Zeit

Dress code in Norway – My article published in Die Zeit

The main point is basically that the dresscode in Norway is quite relaxed. Even at companies that are usually known for having a strict and formal dresscode in other parts of the world. You can read the article here in German: http://www.zeit.de/lebensart/mode/2013-01/leserartikel-norwegen-kleidung

Ubuntu 12.10 on the Asus F201E / X201E

Since I am currently over-saturated with Apple products (MacBook, iPad, iPhone, iPod – I have them all) or Windows products (at work), I was looking for a portable notebook to escape the Apple/Windows universe every now and then to play a bit with Linux.

Requirements were that the notebook had to be light and very cheap – the latter characteristic is also good for traveling because you don’t need to worry too much that the notebook gets stolen. The choice fell on the Asus F201E that is called X201E (http://www.asus.com/Notebooks/Versatile_Performance/X201E/) in the US.

Choppy YouTube videos with shipped Ubuntu
It came preinstalled with Ubuntu 12.04 64-Bit, however the performance of fullscreen HD Flash videos was very poor. Videos on websites like YouTube were displayed very choppy and sometimes also with a lag in the audio track. Therefore, I tried to install newer graphics drivers, tried several other tweaks and a few other Linux distributions – with no real improvement.

The Asus F201E running Ubuntu 12.10.

The Asus F201E running Ubuntu 12.10.

Fresh install of Ubuntu 12.10
Finally, I found out that my favorite distribution for better performance (less choppy Flash video) and usability for desktop use (installed fonts, installed Flash plugin, drivers, clearness of the user interface) was Ubuntu 12.10. The main trick here was to take the 32-Bit version and NOT the 64-Bit version although the processor supports it.

I used Linux Live USB creator on Windows to put the downloaded iso file from Ubuntu (link) onto a USB stick and make it bootable. I booted from the stick using the legacy BIOS option by pressing ESC during startup and then selecting the USB stick in the menu and not the UEFI boot option.

The UEFI install caused a lot of trouble and did not work, also with the other Linux distributions. To save time, I therefore opted for the good old BIOS option that seemed to work. I let Ubuntu partition the entire 500 GB harddrive. The installation went fine, only a few things had to be changed to make it work as before:

Minor tweaks necessary
For a few issues, some tweaks were necessary to fix them.

Brightness keys
After the installation, the keys for the brightness were not working. This could be fixed by editing the /etc/default/grub file and changing the line “GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash” to “GRUB_CMDLINE_LINUX_DEFAULT=”quiet splash acpi_osi=”. After running “sudo update-grub” in the terminal and rebooting, the keys were working again.

Network card not working
Besides, the ethernet controller was not recognized and did not work, while Wifi was functioning just fine. This could be fixed my installing the package linux-backports-modules-cw-3.6-quantal-generic. This package will install several other packages (depending on the current kernel used) and after running “modprobe alx” in the terminal as super user, the ethernet card was working also.

Asus software sources
The original Ubuntu that came with the Asus was using two special software sources, those I added again in 12.10. They were “http://asus.archive.canonical.com/updates precise-annan public” and “http://asus.archive.canonical.com/updates precise-annan public (Source Code)”. I don’t really know whether Ubuntu 12.10 is using any of these Asus packages, but for future reference, I just included them in this blog post.

System up and running
After fixing these few issues, Ubuntu 12.10 is running fine. Flash videos play more smoothly and everything seems to work just as intended. Speed-wise, the notebook naturally cannot compete with devices that have faster processors and are more expensive, but with this build quality it is a nice travel companion at the fraction of the price of a MacBook air.

Airbus A380 in Cologne

This Saturday, the world’s biggest passenger plane Airbus A380 made its first-time landing at Cologne-Bonn Airport (CGN/EDDK).

Since I was curious, I had to go and take some pictures. It turned out to be really crowded with all kinds of people. A mountain biker asked me on the way “Hey, do you know what is happening here?”. He thought there would be a kind of open air concert.

The Airbus finally touched down at around 17.30 local time and when it was over my head it was so huge that it did not really fit onto the photo. I was standing in the approach zone of runway 14L, a few hundred meters before the runway threshold (special thanks to this website). NRWeblog also took some photos.

Here are some pictures from the landing:

Sitting on a Volcano

Not only Norway has beautiful lakes, Germany has, too. My favourite lake in Oslo is Sognsvann, but this one comes close. It is called “Laacher See” and it is a potentially active volcano. At some spots you can see little bubbles coming out of the water.

In contrast to Sognsvann it lacks an efficient subway connection, but the Benedictine monastery Maria Laach Abbey (seen in the background of the first picture) more than makes up for it.

One Google Maps you find the lake here.