I've had to setup a couple of servers from scratch recently and figured I'd document how I did it so that the next time I can get it done quicker. Feel free to use it yourself but I take no responsibility for the accuracy of this.
This post covers users, ssh, git, oh my zsh, LAMP, MongoDB and NodeJS/NPM.
Add a new user and give them sudo access
adduser your_username vi /etc/sudoers
Insert the following below the
root user (should look identical to
root, except for the username)
your_username ALL=ALL ALL
If you get "write errors" when trying to save, just add:
:w !sudo tee %
Generating SSH keys
On the local computer
cd ~/.ssh # Checks to see if there is a directory named ".ssh" in your user directory ssh-keygen -t rsa -f name_of_file_rsa -C "email@example.com" # [-t] type # [-f] output_keyfile # [-C] comment
Follow prompts and name the RSA file differently to others in .ssh directory making sure to add a passphrase.
Getting keys to the server
On the server
On the local computer
The command below reads the content of the key you just created on your computer, and appends that key to the
~/.ssh/authorized_keys file on your server. If you don't have an existing
authorized_keys file, it creates one. Replace
example.com with your domain:
cat ~/.ssh/name_of_file_rsa.pub | ssh firstname.lastname@example.org 'cat - >> ~/.ssh/authorized_keys'
Set correct permissions on .ssh directory (local and server)
chmod 700 ~/.ssh && chmod 600 ~/.ssh/*
Server SSH configuration (server)
Make the following changes:
Port 1234 # causes SSH to listen on port 1234. # You can use any unused port from 1 to 65535. # It's recommended to choose a privileged port (port 1-1024) # which can only be used by root. If your SSH daemon # stops working for some reason, a rogue application # can't intercept the connection. PermitRootLogin no # Disallows direct root login.
sudo /etc/init.d/ssh restart
Test SSH connection
ssh your_username@server_ip -p 1234 # Replace username, IP address and 1234. # 1234 is the port numberyou set in sshd_config file on the server
Creating an ssh shortcut
I prefer to keep my ssh details in a config file, allowing me to just write
ssh shortcut_name. Create a shortcut shortcut in
~/.ssh/config file using this as an example:
Host shortcut_name HostName 220.127.116.11 or domain name # Custom port number specified in server sshd config file: Port 1234 User your_username IdentityFile ~/.ssh/name_of_file_rsa ServerAliveInterval 30 ServerAliveCountMax 120
Test the ssh connection using the shortcut:
If this fails, check that it is using the correct identity file created in the keygen step,
name_of_file_rsa. If it succeeds then proceed with disabling password login attempts on server for extra security.
Disabling password login
On the server again:
And find the line that reads
Change to no to disable tunnelled clear text passwords
PasswordAuthentication no # Uncomment this line and change to no so that we can no longer login with a password
Install developer tools (Ubuntu)
sudo apt-get update && sudo apt-get install build-essential
Fix Perl locale warnings (Ubuntu 12)
sudo apt-get install language-pack-en-base
Install required dependencies
sudo apt-get install libcurl4-gnutls-dev libexpat1-dev gettext libz-dev libssl-dev build-essential
Install Git from apt:
sudo apt-get install git
Install Git from updated repo:
# Update everything sudo apt-get update sudo apt-get upgrade # Add ability to add other repositories sudo apt-get install python-software-properties # Upgrade to latest stable git # Adds latest git releases to install list sudo add-apt-repository ppa:git-core/ppa sudo apt-get update sudo apt-get install git
Install Oh My ZSH
Oh My ZSH makes working on the commandline not painful.
sudo apt-get update && sudo apt-get install zsh
cd ~/tmp curl -L https://github.com/robbyrussell/oh-my-zsh/raw/master/tools/install.sh | sh
The manual way
Clone the repository
git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
Optional – Backup your existing ~/.zshrc file
cp ~/.zshrc ~/.zshrc.orig
Create a new zsh config by copying the provided zsh template.
cp ~/.oh-my-zsh/templates/zshrc.zsh-template ~/.zshrc
Set zsh as your default shell:
chsh -s /bin/zsh
Start / restart zsh (open a new terminal is easy enough…)
Install my custom zsh mods
~/src/customise-ohmyzsh/install.sh and set
server if it different from "server" then execute:
This will install my custom
.zshrc file and the
sheedy.zsh-theme a customised version of the doubletree theme.
Instructions from MediaTemple
sudo apt-get install apache2 php5 libapache2-mod-php5 mysql-server mysql-client php5-mysql
Visit the IP address and check that apache is loading the test page.
sudo vi /etc/apache2/ports.conf
NameVirtualHost *:80 with the IP address.
Edit the default virtual host
sudo vi /etc/apache2/sites-available/default
<VirtualHost *:80> to the IP addrres.
Optional – The default site will be what displays for your server if someone requests a domain, subdomain, or IP address that resolves to your server but doesn't have a distinct VirtualHost file. The content for this domain is stored in /var/www/. If you don't want to have a default website, you can disable it. Run this command to disable the default site (only if desired):
sudo a2dissite default sudo /etc/init.d/apache2 reload
Create a new site
sudo touch /etc/apache2/sites-available/example.com sudo vi /etc/apache2/sites-available/example.com
Add the following content (replace examples with your own IP address and domain name):
Add the ServerAlias line with any domains or subdomains that you also want to redirect to the domain listed on the ServerName line. It's a good idea to at least include the www. subdomain. You can list additional entries right after the first one, with a space in between. If you want to include all subdomains, enter
<VirtualHost xxx.xxx.xxx.xxx:80> ServerName example.com ServerAlias www.example.com ServerAdmin email@example.com DocumentRoot /var/www/example.com/html ErrorLog /var/www/example.com/log/error.log # Possible values include: debug, info, notice, warn, error, crit, # alert, emerg. LogLevel warn CustomLog /var/www/example.com/log/access.log combined </VirtualHost>
The file you just edited references some paths that don't yet exist. Let's create them:
sudo mkdir -p /var/www/example.com/html sudo mkdir -p /var/www/example.com/log
Enable your new site:
sudo a2ensite example.com sudo /etc/init.d/apache2 reload
HTTPS Configuration (SSL)
The mod_ssl module is available in apache2-common package. Execute the following command from a terminal prompt to enable the mod_ssl module:
sudo a2enmod ssl
There is a default HTTPS configuration file in
/etc/apache2/sites-available/default-ssl. In order for Apache2 to provide HTTPS, a certificate and key file are also needed. The default HTTPS configuration will use a certificate and key generated by the ssl-cert package. They are good for testing, but the auto-generated certificate and key should be replaced by a certificate specific to the site or server.
To configure Apache2 for HTTPS, enter the following:
sudo a2ensite default-ssl
The directories /etc/ssl/certs and /etc/ssl/private are the default locations. If you install the certificate and key in another directory make sure to change SSLCertificateFile and SSLCertificateKeyFile appropriately.
sudo touch /var/www/example.com/html/info.php sudo vi /var/www/example.com/html/info.php
Add the following to the file:
<?php phpinfo(); ?>
Follow the prompts of this command:
Login to mysql
sudo mysql -u root -p
For this example, we will create the database 'woot', grant the user 'meh' read/write privileges and assign the password 'DBF5f3'.
create database woot; grant all on woot.* to 'meh' identified by 'DBF5f3';
Install and upgrade PHPMyAdmin
sudo apt-get install phpmyadmin
sudo add-apt-repository ppa:nijel/phpmyadmin sudo apt-get update sudo apt-get install phpmyadmin
Configure Package Management System (APT)
The Ubuntu package management tool (i.e. dpkg and apt) ensure package consistency and authenticity by requiring that distributors sign packages with GPG keys. Issue the following command to import the 10gen public GPG Key:
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 7F0CEB10
sudo touch /etc/apt/sources.list.d/10gen.list sudo vi /etc/apt/sources.list.d/10gen.list
And include the following line for the 10gen repository
deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen
Now issue the following command to reload your repository:
sudo apt-get update
Issue the following command to install the latest stable version of MongoDB:
sudo apt-get install mongodb-10gen
Follow instructions (possibility to miss this part)
sudo apt-get autoremove
These packages configure MongoDB using the
/etc/mongodb.conf file in conjunction with the control script. You will find the control script is at
This MongoDB instance will store its data files in the
/var/lib/mongodb and its log files in
/var/log/mongodb, and run using the
mongodb user account.
MMS is a MongoDB monitoring service.
Install pyton setuptools
sudo apt-get install python-setuptools
Install pymongo dependencies
sudo apt-get install build-essential python-dev
sudo easy_install pymongo
Upgrade to the latest version of the driver
sudo easy_install -U pymongo
Install the MMS Agent
If you have not downloaded the MMS agent already, click the “download agent” link immediately after you sign into MMS (e.g. http://mms.10gen.com to download an agent specifically configured for your account.
You can run the agent on any system that can connect to the MongoDB instances you want to monitor. As long as it can connect to each instance, you can use a single agent to do all the monitoring. Do be sure that the agent can make outgoing connections via HTTPS on port 443.
Unzip the archive and run the agent with the following command:
The above command is sufficient for testing the MMS agent. For production deployments, you will want to daemonize the process and ensure that it restarts following a system restart. Your operating system likely has a preferred method for managing daemon processes.
As a temporary measure, the following command will start the agent process detached from the current terminal session:
nohup python agent.py > /[LOG-DIRECTORY]/agent.log 2>&1 &
Replace “[LOG-DIRECTORY] with the path to your MongoDB logs.
This command allows the agent survive the current terminal session and writes all messages to the agent.log file. You may include this command in your MongoDB control script or use your system’s
/etc/rc.local equivalent; however, avoid running the agent as root.
Installing the mongo driver for PHP
Install pear and pecl
sudo apt-get install php5-dev php5-cli php-pear
sudo pecl install mongo
Caused the following error for me:
downloading mongo-1.3.1.tgz ... Starting to download mongo-1.3.1.tgz (118,731 bytes) ..........................done: 118,731 bytes 49 source files, building running: phpize Configuring for: PHP Api Version: 20090626 Zend Module Api No: 20090626 Zend Extension Api No: 220090626 /usr/bin/phpize: 209: /tmp/pear/temp/mongo/build/shtool: Permission denied Cannot find autoconf. Please check your autoconf installation and the $PHP_AUTOCONF environment variable. Then, rerun this script. ERROR: `phpize' failed
I found that the
autoconf version seemed really old and found no useful ways to upgrade it so downloaded the source directly then installed it:
wget http://au.archive.ubuntu.com/ubuntu/pool/main/a/autoconf/autoconf_2.68-1ubuntu1_all.deb sudo dpkg -i autoconf_2.68-1ubuntu1_all.deb
That didn't fix it.
which autoconf returned
/usr/bin/autoconf, showing that I did in fact have it installed so I followed theses instructions:
sudo su export PHP_AUTOCONF=/usr/bin/autoconf export PHP_AUTOHEADER=/usr/bin/autoheader
But that didn't seem to help, even when adding to my
.zshrc and executing
This stackoverflow question seemed to get really close but I got new errors
mkdir /root/tmpz mount --bind /root/tmpz /tmp umount /tmp; umount /var/tmp umount: /tmp: device is busy. (In some cases useful info about processes that use the device is found by lsof(8) or fuser(1))
This command told me what was causing the directory to be busy
lsof | grep /tmp
And in my case it was
mysqld so I stopped those services and then tried it again:
sudo pecl install mongo
Enable MongoDB driver for php
sudo vi /etc/php5/apache2/php.ini
Add the following:
# MongoDB Driver extension=mongo.so # Allow 64-bit Integers in PHP [mongodb] mongo.native_long = 1
Installing NodeJS and NPM
sudo apt-get update sudo apt-get install git-core curl build-essential openssl libssl-dev git clone https://github.com/joyent/node.git cd node git tag # Gives you a list of released versions git checkout v0.8.16 ./configure make sudo make install node -v curl http://npmjs.org/install.sh | sudo sh npm -v
- Source – Installing Node.js and NPM on Ubuntu 11.04
- Source – Installing Node.js and NPM on Ubuntu/Debian
If you need to uninstall for any reason
# From within Node source directory sudo make uninstall
This would be a lot easier though
sudo apt-get install python-software-properties sudo add-apt-repository ppa:chris-lea/node.js sudo apt-get update sudo apt-get install nodejs npm