Unsupported Version
This article applies to an unsupported version of Ubuntu. More info...


Candidate for Deletion
This article may not be appropriate for this wiki, and may be deleted. More info...

UbuntuRelease: JeOS 8.04 (Hardy Heron)

For 8.10 (Intrepid) please see JeOSVMBuilder


This page aims at documenting how to create virtual appliance using Ubuntu Server Edition's JeOS.


What is JeOS?

Ubuntu JeOS (pronounced "Juice") is an efficient variant of the Ubuntu Server operating system, configured specifically for virtual appliances. Currently available as a CD-ROM ISO for download, JeOS is a specialized installation of Ubuntu Server Edition with a tuned kernel that only contains the base elements needed to run within a virtualized environment.

Ubuntu JeOS has been tuned to take advantage of key performance technologies in the latest virtualization products from VMware. This combination of reduced size and optimized performance ensures that Ubuntu JeOS Edition delivers a highly efficient use of server resources in large virtual deployments.

Without unnecessary drivers, and only the minimal required packages, ISVs can configure their supporting OS exactly as they require. They have the peace of mind that updates, whether for security or enhancement reasons, will be limited to the bare minimum of what is required in their specific environment. In turn, users deploying virtual appliances built on top of JeOS will have to go through fewer updates and therefore less maintenance than they would have had to with a standard full installation of a server.

Initial setup

At this point in time, JeOS is meant to run under VMWare Server, VMWare ESX and KVM and may not work under other virtualization technologies yet. It is assumed in this tutorial that you have already installed a virtualization environment. We also assume that you know how to use a text based text editor such as nano or vi. If you have not used any of them before, you can get an overview of the various text editors available by reading the PowerUsersTextEditors page. This tutorial has been done on VMWare server, but the general principle should remain.

Download JeOS

The latest version of JeOS iso image can be downloaded from http://cdimage.ubuntu.com/jeos/releases/.

  • wget http://cdimage.ubuntu.com/cdimage/jeos/releases/8.04.3/release/jeos-8.04.3-jeos-i386.iso

It is always a good idea to verify the md5 sum of the downloaded file by comparing the content of http://cdimage.ubuntu.com/cdimage/jeos/releases/8.04.3/release/MD5SUMS with the result of

  • md5sum ubuntu-8.04.3-jeos-i386.iso

If the values are not the same, you should try to download the file again.

Installation of JeOS

Installation of JeOS is done the same way you would install any other OS in VMWare, but here are a few thing to consider:

  • If you plan on shipping a virtual appliance, do not assume that the end-user will know how to extend disk size to fit their need, so either plan for a large virtual disk to allow for your appliance to grow, or explain fairly well in your documentation how to allocate more space.
  • Given that RAM is much easier to allocate in a VM, RAM size should be set to whatever you think is a safe minimum for your appliance.

Defining the VMWare machine

The following example is based on using VMWare server:

  1. Create a new virtual machine.
  2. Click next.
  3. Select Custom configuration, click next.

  4. Select Linux, pick Ubuntu in the version drop down menu, click next.

  5. Pick a name for your virtual appliance (use something that makes sense for your product), click next.
  6. Pick one processor (always default to the lowest configuration you think your users may have), click next.
  7. Letting the machine be private is a good secure basis, click next.
  8. Pick the minimum RAM you think your appliance will need (this can be changed easily by the user later on). Click next.
  9. Bridged networking might seem a sensible default to simplify user set-up later on, click next.
  10. Pick a disk size that makes sense for your virtual appliance. A minimum of 8G seems reasonable, particularly if you do not pick allocate disk space now. Split the disk into 2Gb files makes sense if you want to allow storage on FAT volumes. Click next.

  11. Pick where you want to store the disk image, click Finish.

JeOS installation parameters

Once your machine has been defined, you need to start it, but before you do that you need to tell it to boot from the ISO image you downloaded earlier. The installer for JeOS is very similar to the Ubuntu Server Installer, but as we are preparing a virtual appliance, there are a few steps that we want to change from a regular install.

Assigning a fixed IP address

As a virtual appliance that may be deployed on various very different networks, it is very difficult to know what the actual network will look like. In order to simplify configuration, it is a good idea to take an approach similar to what network hardware vendors usually do, namely assigning an initial fixed IP address to the appliance in a private class network that you will provide in your documentation. An address in the range is usually a good choice.

When you arrive at the screen Configure your network asking you to provide a hostname for this machine:

  • press escape to access the network configuration menu
  • select Configure network manually in the next screen

  • Enter a fixed IP address and other network information in the subsequent screen.
  • once this is done, the installer will continue to its next steps automatically


Partitioning of the virtual appliance will have to take into consideration what you are planning to do with is. Because most appliances will run as server, using separate /home, /usr, /var and /tmp partition would make sense.

User and password

Again setting up a virtual appliance, you will need to provide a default user and password that is generic so that you can include it in your documentation. We will see later on in this tutorial how we will provide some security by defining a script that will be run the first time a user actually logs in the appliance, that will, among other things, ask him to change his password. In this example I will use 'user' as my user name, and 'default' as the password.

Preparing the OS

Once we are done with the initial installation of JeOS and our virtual machine is now waiting with a login prompt, we now have to prepare our operating to accommodate our application. It is generally a good time to make a snapshot of your clean VMWare image, so that if a mistake is made later on, it will be possible to revert to a blank page without having to reinstall everything.

The very first thing to do after install of the sytem is to check that it is up to date. This is done by running:

  • sudo apt-get update && sudo apt-get upgrade

Installing VMware Tools

VMWare Tools will allow to have a better control of our appliance by the VMware environment, so it is a pretty good idea to set it up. For Ubuntu 8.04 you will have to get VmwareTools version 6.0.3 or later, 6.0.2 won't compile.

  • First setup our environement by installing the build tools:
    sudo aptitude install build-essential linux-headers-$(uname -r)
  • Next install the package psmisc to get killall that is required by the VMware tools
    sudo aptitude install psmisc
  • Next should ask VMware to mount the VMwareTools CD by clicking on VM > Install VMware Tools… in the VMware Server menu.

  • Mount the cdrom
    mount /media/cdrom0
  • uncompress the tools to the tmp directory
    cd /tmp
    tar -xvzf /media/cdrom0/VMwareTools*.gz
  • run the vmware-install.pl script accepting all the defaults (done by the -d flag)
    sudo vmware-tools-distrib/vmware-install.pl -d
  • Pay no attention to the instructions for using the vmxnet driver; it's already loaded at this point.
  • Clean up
    rm -rf vmware-tools-distrib

Installing required packages

In this example we will be installing a very simple application consisting of a web page that accesses a mysql database. We will therefore require our OS to provide us with:

  • Apache
  • PHP
  • MySQL

which is in the end a basic LAMP stack that we will pull in one single step using the tasksel command:

  • sudo apt-get install lamp-server^

Note that at this point we could easily install any additional packages that we might need using, for example, the aptitude command line utility.

Once we are done installing our base packages, it is another good time to do a snapshot our virtual machine. We also can save the intermediary steps by doing a full copy of the virtual machine by issuing the following command on our host after powering it down (you will have to adapt it to your particular environment):

  • cp -rf /var/lib/vmware/Virtual\ Machines/JeOS /var/lib/vmware/Virtual\ Machines/JeOS-basePackages/

Security considerations


Another convenient tool that we want to have on our appliance is OpenSSH, as it will provide our admins to access to access the appliance remotely. However, pushing in the wild an appliance with a pre-installed OpenSSH server is a big security risk as all these server will share the same secret key, making it very easy for hackers to target our appliance with all the tools they need to crack it open in a breeze. As for the user password, we will instead rely on a script that will install OpenSSH the first time a user logs in so that the key generated will be different for each appliance.

However, it might be simpler during the set-up to access our appliance using ssh, so we still install it at this time, but we will need to make sure that fully removed by the time we ship our appliance, which is described in the last part of this tutorial. To install it, simply run:

  • sudo apt-get install openssh-server


When we ran apt-get to install the lamp-server^, the only question we were asked was to provide a default password for MySQL. It would not be wise to have all our deployed appliances to use the same password, so we will have to have it changed as well the first time a user logs in our appliance.

Installing and maintaining our application

In general this is a 4 step process :

  1. Package our application so that it is easily deployable.
  2. Finish to prepare the system so that our application can run. Here we will simply create a mysql user for our application to use.
  3. Install the application. Here we will just add a single file in /opt/sample-app/ and configure apache to access it.
  4. Setup the system so that it will be automatically updated everyday.

Package the application

Two option are available to us:

  • The recommended method to do so is to make a Debian package. Since this is outside of the scope of this tutorial, we will not perform this here and invite the reader to read the documentation on how to do this at https://wiki.ubuntu.com/PackagingGuide. In this case it is also a good idea to setup a repository for your package so that updates can be conveniently pulled from it. See http://www.debian-administration.org/articles/286 for a tutorial on this.

  • Manually install the application under /opt as recommended by the FHS guidelines at http://www.pathname.com/fhs/. This is the approach we will be using here for more simplicity even though this is not the one we would recommend for any serious application as it does mean more complexity in maintaining it. We cover this in the “How to get your application updated” section below.

Setting up a MySQL user

Our application requires to access the MySQL database. For security reasons, we do not want this user to be the root MySQL user, so we define a user named www-data that has read access to the local databases and can only connect locally with some password.

  • First we need to connect to the mysql monitor using the default password we specified earlier:
    user@JeOS:$ mysql -p --user=root
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 9
    Server version: 5.0.51a-3ubuntu5.4 (Ubuntu)
    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
  • Then we can create our user and exit the mysql monitor:
    mysql> GRANT SELECT ON *.* TO 'www-data'@'localhost' IDENTIFIED BY 'password';
    Query OK, 0 rows affected (0.00 sec)
    mysql> exit

Installing our application

In this example our application is a very simple PHP page that lists the databases available in MySQL:

  • <?php
    ?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
       <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
       <meta name="description" content="Database List">
       <title>Database List</title>
    <h1>Database list</h1>
    $link = mysql_connect('localhost', 'www-data', 'password');
    $db_list = mysql_list_dbs($link);
    $i = 0;
    $cnt = mysql_num_rows($db_list);
    while ($i < $cnt) {
        echo "<li>" . mysql_db_name($db_list, $i) . "</li>\n";

To install it:

  • sudo mkdir /opt/sample-app/

  • open the file /opt/sample-app/index.php using sudo with your text editor of choice

  • paste the above page content in the text editor, save and exit
  • sudo chown -R www-data:www-data /opt/sample-app to allow apache to read it.

Then we just need to modify apache default configuration to point to our application direcory:

  • open the file /etc/apache2/sites-enabled/000-default using sudo with your text editor of choice

  • change all instances of /var/www/ to /opt/sample-app

  • save and exit te
  • sudo /etc/init.d/apache2 reload

You can now test your application by pointing your browser to the IP address of the virtual appliance.

Setting up for automated updates

To have your system be configured to update itself on a regular basis, we will just install unattended-upgrades:

  • sudo aptitude install unattended-upgrades

How to get your application updated

If you decided to package your application as a Debian package and did setup your own repository, all you need to do is to add your repository to /etc/apt/source.list.d/. The above auto-update cron will then pull the update each time you provide it in your repository. Another advantage of using a packaged approach is that, if your dependencies evolve during the life of your application, all updated dependencies will be automatically installed in the same process.

If you decided to install your application manually, it is really up to you on how you will be automating the updates. A possible solution would be to:

  • place a tar file with your app on some http server along with a version file
  • create a script that is placed in /etc/cron.daily that regularly compares the version file on the server with the version file that you would have stored in /opt/sample-app/
  • download and apply the new tar file if the version available on-line is greater
  • reload apache

Preparing first user boot

Because of the security risks we outlined earlier, we need to have a few tasks performed the first time a user logs in:

  • Re-install openssh if the appliance can be accessed this way
  • Ask for a new user password
  • Ask for a new MySQL root password
  • Regenerate the ssl certificate if our application can be accessed through ssl

To do so we will add a line to the very end of /etc/bash.bashrc:

  • if [ ! -e /etc/opt/sample-app/initial_config_done ]; then
      sudo touch /etc/opt/sample-app/initial_config_done

Through this line, the script /opt/sample-app/bin/initial_config will be executed upon first login if the file /etc/opt/sample-app/initial_config_done does not exist. So we now need to

  • create the directory /etc/opt/sample-app/: sudo mkdir /etc/opt/sample-app/

  • create the script /opt/sample-app/bin/initial_config using sudo pasting the script below using your text editor of choice:

    # Let's change the user's password
    echo "Thank you for choosing our sample-app appliance"
    echo "For the security of the appliance, we need you to change this user password now."
    # Now change the mysql password
    echo "We now need you to specify a new MySQL root password"
    let done=0
    while [ $done -eq 0 ]; do
      read -e -s -r -p "New mysql root password:" PASS1
      echo ""
      read -e -s -r -p "Retype mysql root password:" PASS2
      if [[ "$PASS1" == "$PASS2" ]]; then
        let done=1
        #perform the actual change assuming that our initial password is default
        mysqladmin -u root --password='default' password $PASS1
        echo "The 2 passwords did not match, please try again."
    #Perform the reinstall of openssh so that the key is regenerated
    echo "We are now going to generate your ssh keys."
    sudo apt-get --purge -y remove openssh-server
    sudo apt-get install -y openssh-server
    # You can add here any first user login actions that you require
  • Make it executable sudo chmod a+x /opt/sample-app/bin/initial_config

Cleaning before shipping


After testing our appliance a bit, it is now time to make it clean before shipping it:

  • Remove the /etc/opt/sample-app/initial_config_done file sudo rm /etc/opt/sample-app/initial_config_done

  • Reset the passwords to their default values if you have changed them
  • Remove services that are no longer needed (remember to remove configuration files, too, so use sudo aptitude purge, sudo apt-get --purge remove, or sudo dpkg -P whichever tool you prefer). From our example this would include

    • openssh-server
    • build-essential
    • linux-headers-$(uname -r)
  • Clear out the apt cache sudo apt-get clean

  • Remove $HOME/.ssh for both user and root sudo rm -rf /home/user/.ssh && sudo rm -rf /root/.ssh

  • Remove any build directories that may have been used in the process. In our example that would be the content of the /tmp directory
  • If you are planning to move, clone or convert this as a virtual machine, you need to let JeOS re-find the network interfaces uppon the next reboot. Otherwise you will end up with no network connection or so ever. To do this you need to edit the file /etc/udev/rules.d/70-persistent-net.rules. Remove all lines which look like this # PCI device 0x1022:0x2000 (pcnet32) an this SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="00:AA:BB:CC:DD:EE", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

  • Remove the history of your commands: history -c

  • Shutdown the system
  • In VMWare management console
    • go to your virtual machine settings
    • select the virtual disk
    • defragment it (which should reclaim all the space you freed, making your appliance smaller)
  • your appliance is ready for shipment!


We sincerely hope that this tutorial will be making building you own appliance simpler. For further documentation on the Ubuntu Server Edition, please refer to our Server Guide: https://help.ubuntu.com/7.10/server/C/. If you are interested in learning more, have questions or suggestions, you are welcome to come talk with us at:

External Links

The following are unverified suggestions made by users.

* TurnKey Core - the 100MB common base system on top of which all TurnKey Linux software appliances are built. Features include a live installer, configuration and installation console, rich web administration interface, and automatic daily package updates.

* Bootstrap JeOS - a 67MB bare minimum system that includes exactly just enough operating system to boot live, setup networking and install packages from the package repositories.


JeOS (last edited 2017-09-26 16:55:37 by ckimes)