Friday, August 31, 2018

Install Debian on Old Mac Mini (late 2009)

This article is part of the series on installing various Linux distribution on Old Mac Mini. In this post, we are going to install Debian on our old Mac Mini (late 2009) version.  Installing Debian on Mac Mini presents no major issue. We might need to reboot the machine to get the wifi to work occasionally, but most of the time the wifi works well without any issue. This is the second best Linux distribution that we have tried. Since we have been trying various Gnome desktop environment, this time we will use KDE Plasma desktop environment with Debian. There is one minor issue, KDE Plasma seems eat up CPU and memory resources. You might want to try Gnome instead.

Preparing USB

We downloaded Debian for KDE iso image. There are many type of Debian images. We use the 2.89GB version of Debian for KDE. Once we downloaded the image we burn the iso image to USB using Etcher. For those who need a tutorial for burning image to USB please refer to the Ubuntu tutorial.

Installing Debian

Once we boot up the iso image, we select Graphical Debian Installer. The first screen appear as shown below:

Select the language of your chose and click Continue.

Select the location of your choice. Click Continue.

Select your preferred keyboard layout. Click Continue when done. The system will copy component from the image and start to configure network.

Debian will detect our wifi but it could not find the drivers. The following screen appear to ask us to supply the driver.

Select no as we will configure the wifi after the installation. Click Continue. After the network is configured, the following screen will appear as below:

Enter your preferred host name of the Debian system. Click Continue.

Enter the domain name. Usually we leave it blank. Click Continue.

Enter the root password and click Continue.

Enter the full name of system user. Click Continue when done.

Enter the username and click Continue.

Enter the password of the user. Click Continue.

Configure time zone. Click Continue when done. After that, the system will start performing disk partition. The following screen will appear:

Over here, we choose to use the entire disk for Debian or we should use the free partition space. In this case, we choose to use entire disk. Click Continue.

The installer would ask to confirm which disk drive to use for the Debian system installation. Select the appropriate disk. Click Continue when done.

This screen will ask if you want separate home partition. For simplicity, choose to use all files in a single partition. Click Continue when done. Finally, the system will present the partition summary as shown below.

Please check carefully if the partition is done on the right disk if you have more than one had disk in a system. Click Continue to proceed,

This screen presents you the final confirmation of disk partition. Select Yes and click Continue. The system will proceed to install the base system and start copying the system files. Once the installation of the base system is done, the system will check and configure package manager.

Select Yes to use network mirror. Click Continue.

Select the country of the mirror. The closest the mirror the fastest the download. Click Continue when done.

Next you select the mirror within the country you have selected. Click Continue when done.

Finally, we are given the choice of configuring the proxy server. Usually, we skip this part. Enter the proxy server if you are suing one. Click Continue. The system will proceed with the installation.

The system will ask to configure boot loader.

Click Yes and Continue.

Click Continue.

Reboot the system when done.

Post Installation Setup


Once the system is rebooted, the first thing is to update the system. The best method of system update is to use the app Software Management. Open the app as shown below.

Select Updates and the system will check for any updates. You may need to use root password to apply the updates.

Administrator (Sudo)

Next, we need to add our user as administrator. To do that go to favorites and select System Settings

Select Account Details > User Manager, then we just need to check the box mark administrator.

We need to logout and log back in for it to be effective.

Install Wifi

To install wifi, we need to modify the repository list.  Use the command below to open up the source list.

sudo nano /etc/apt/sources.list

In the source file, you should see something similar as below

deb stable main
deb-src stable main

For each line we need to append contrib and non-free so that each line has
deb stable main contrib non-free

deb stable main contrib non-free
deb-src stable main contrib non-free

There are a total of 6 lines to append.

To install wifi driver use the command

sudo apt-get install firmware-b43-installer b43-fwcutter

After the installation is completed, we need to reboot the system. Please note that there is no need to modify the blacklist.conf file.

Install RealVNC Server

To install RealVNC server, we need to download the deb file from RealVNC site. To run the deb file use the command below:

sudo apt install ./VNC-Server-6.3.1-Linux-x64.deb

For configuration of RealVNC please refer to the post Install and Configure RealVNC in Linux Ubuntu 18.04 LTS.

Related Post

Please also check out the main post on re-purposing old Mac Mini.  This post also include the installation of Ubuntu on Mac Mini. We have also include hardware specification and other consideration in the main post.

Please also check out the summary result of testing various Linux distribution on Mac Mini (late 2009).
Install Linux on Mac Mini (late 2009) Result Summary


Thursday, August 30, 2018

Introduction to Docker - Day 4

On day 4, we will learn how to manage and clean up containers. Then we will learn how to create common folder to be use in docker container.

Docker Container Management

Listed below are many command that can be used to manage containers. For some function, there are more than one command/method to perform the task.

To list down all container that are active using the command:

docker container ls

To list down all container including non-active containers, use the command

docker container ls -a

To stop an active container

docker container stop <container_name>
docker container kill <container_name>
docker stop <container_name>
docker kill <container_name>

To remove container

docker container rm <container_name>
docker rm <container_name>

To remove all inactive container

docker rm $(docker ps -aq)
docker container prune

Sharing Folder with Containers

We can create a common folder to be used as data dump. After we exit the container, the data folder will still be around. Please follow the following example to create data folder

Use the following command to create a common folder

cd /Users/Shared
mkdir dockerfolder
cd dockerfolder

To run Ubuntu with the data folder, use the command

docker run -it --name myubuntu1 -v $(PWD):/home  ubuntu

The option -v allow us to mount a volume. In this example, we use $PWD which is the current directory (dockerfile) and map the folder to /home folder in Ubuntu.

Write some text as shown below

cd /home
echo "This is a test" >> test.txt

On the Mac OS, navigate to the Shared Folder (/Users/Shared/dockerfile) and check if the file test.txt exist.

Using $PWD is not a very good way as we might be moving in and out of the folder. Use the following command to run and mount the volume:

docker run -it -v /Users/Shared/dockerfolder:/home  ubuntu

We can map any folder in the host system with any existing folder in Ubuntu.

The syntax of folder mapping is as follows:

docker run -it -v <local_folder>:<container_folder> <image_name>


Wednesday, August 29, 2018

Introduction to Docker - Day 3

On Day 3, we will learn more about running docker app and various options. 

Running Docker Image

To run a docker image, the basic syntax is as follows:

docker run <image_name> 

Basic syntax is only able to run hello-world properly. For other apps, we need additional options.

To run a docker image with optional container name use the syntax:

docker run --name <container_name> <image_name>


docker run --name someName hello-world

Run Interactive Docker App

To run an interactive app we use the following command:

docker run -i -t --name <container_name> <image_name> <command_in_app>
  • -i is for interactive session
  • -t is to create a tty for user interaction
  • Usually we use -it
  • we can append additional command to be executed in the app. The command should be appended after the image name


docker run -it --name myubuntu ubuntu

We perform any task such just like a virtual machine. Type exit to end the session. We can remove the container using the custom container name that we supplied.

Example 2:

docker run -it --name python1 python:3.7-slim

Once we command is executed, we are brought into python shell. If we exit the shell, the container will be terminated and exit.

We can also run the above command without going into Python. We do that using alternate command as shown below:

docker run -it --name python2 python:3.7-slim /bin/bash

The space after the image name is reversed for execution command. We append the command to run bash shell instead of Python. We can enter Python from the bash shell and once we exited from Python shell, the system will return us to bash shell.

Run Server App

We can also run server app, however, the options are different. The syntax of the command is as follows:

docker run -d --name <container_name> -p <local_port>:<server_port> <image_name>

  • -d is to tell the container to run but detached from the terminal shell. This way we can still use the terminal for other purpose. 
  • -p is to map network port  from our Mac OS with the Linux system.
  • Please note that when we use -d, the server app will be running in the background, we need to use ps command to check the process and kill it when we need to stop the server.
For this example, we will run nginx webserver. Use the command below:

docker run -d -p 80:80 --name webserver nginx

The screen will return to prompt. To check for the process, we use the command docker ps.

docker ps

To test the webserver, use the address https://localhost in a web browser. You should see the following message from the web browser.

To terminate the server use the following command

docker stop webserver

If we check the docker process, we should return no process.


Tuesday, August 28, 2018

Setup Network Device on Ubuntu 18.04

To setup a network device on Ubuntu server 18.04, we need to use new network setup application netplan. Netplan allow us to configure new network adapter.

We encounter network setup issue when we need to add a second network adapter in VirtualBox for networking with host.

Using Ip Link

Before we use netplan, we can use the following command to show all device: 

ip link show

To temporary enable the device we can use the command below: (please replace eth0 with the network device that you want to configure):

sudo ip link set eth0 up

Use the following command to enable dhcp client.

sudo dhclient eth0

Using Netplan

To enable the network adapter permanently, we need to configure netplan. Use the following command to open the configuration file:

sudo nano /etc/netplan/50-cloud-init.yaml

On the configuration file, we add additional network device as follows. Please note that enp0s2 is the current default device and enp0s4 is the new device. Please also make sure that indentation are aligned correctly. This configuration file requires proper indentation. 

            addresses: []
            dhcp4: true
            addresses: []
            dhcp4: true
    version: 2

To test if the network setting is correct, use the following command:

sudo netplan try

If the test is successful, we can apply the setting using the command:

sudo netplan apply


Monday, August 27, 2018

Using SSH with VritualBox Guest OS

If we installed a sever such as Ubuntu server on VirtuaBox, we will not be able to ssh into the server since the network are isolated from each other. To establish connection with VirtualBox guest OS, we need to create a separate network and a 2nd adapter for host only connection.

Before we create a second adapter on the ubuntu server, we need to create a separate network for the host-only adapter.  

Create Host Network in VirtualBox

Open VirtualBox, select File >> Host Network Manager...

Click on Create to create a host network. A host network known as vboxnet0 is created with a separate subnet and a dhcp server. We can create one network for each server or we can use the same network between different server so that they talk to each other.

Next, we can setup a 2nd network adapter on the virtual machine. On the virtual machine, we can see that the first network adapter is setup as NAT device so that it can communicate with the internet.

On Adapter 2, we enable the network adapter and attached it our host network vboxnet0. 

Finally, we need to activate the network on the server.


Sunday, August 26, 2018

Comparing Virtual Machine on Mac

On Mac OS X, we have few choice of virtual machine to choose from. For free version, we have VirtualBox and Parallel desktop Lite. For paid version, we have WMWare Player and Parallel Desktop. 

For free version of VirtualBox and Parallel Desktop Lite, the features are quite similar although there are some differences. Almost all Linux distribution can be run on VirtualBox whereas only some version of Linux Distribution can be run on Parallel Desktop Lite. 

One of the disadvantage of Parallel Desktop Lite is that the guest OS could not tunnel into host VPN connection. However, Parallel Desktop (paid version) got no problem connecting with host VPN connection. VirtualBox also does not have a problem using host VPN connection. 

Both VirtualBox and Parallel Desktop Lite handles network differently. On Parallel Desktop Lite, the default network setup is shared network.  Host can ping to the guest OS and vice versa. This make ssh connection must easier between host and guest OS.

VirtualBox however handles network differently, to be able to ssh into guest network, we need to create a second network adapter so that host OS can ssh into guest OS. 

In term of network security, Parallel Desktop Lite has weaker security since host and guest OS can communicate easily. On the other hand, VirtualBox present a better security model since the network from client and host are isolated.


Saturday, August 25, 2018

Setup CentOS Network from Command Line

For CentOS minimal install, the network device is disabled by default. To turn on the device, we use network manager command line tools

First we need to check for if the network device exist:

nmcli d

Once we confirm that the device is present, use another tool to activate the network. Use the command below to activate the network.


Select "Edit a connection".

Select the network device and choose Edit....

Most of the setting are default, just make sure that "Automatically connect" is checked. Select OK when done.

On the main screen, select Activate a connection. Once the connection is activated, we are good to go.

We can check the network connection using the command below:

nmcli connection show


Friday, August 24, 2018

Introduction to Docker - Day 2

For second day of Introduction to Docker, we will learn how to run the docker test app with name option. After that, we discuss about pulling an actual docker application and we will learn the naming convention of docker image.

Run with Name Option

We start by running hello-world app without any option. Run the test app as follows:

docker run hello-world

List the container:

docker container ls -a

The result should be as follows:

We then remove the container using the ID or the name cranky_brahmagupta. This name is created randomly by the system if we failed to supply a name.

Now, we remove the container as follows:

docker rm cranky_brahmagupta

To run the container and supply a name, we use the option --name follow by a single space and the custom name. See example below:

docker run --name simple hello-world

List the container

docker container ls -a

The result is as follows:

Please note that the name of the container will be the name that we supplied. We can remove the container using the name.

docker rm simple

Pull Docker Image

As we have mentioned in the previous post, a docker image contains a single app. supply many apps such as Wordpress, mySQL, MongoDB, Python, CentOS, Alpine (light-weight Linux) and Ubuntu.

We can download these image first before running it. We use the pull command to download image without running it.

docker pull ubuntu

The result is as follow

As you can see, if we just use the image name ubuntu, the system will post fix the image name with a tag :latest.

We can try pulling other OS such as CentOS and Alpine. As we can see, Alpine has the smallest image size whereas CentOS takes up 200MB.

Feel free to try the following example:

docker pull alpine
docker pull hello-world
docker pull ubuntu
docker pull centos
docker pull python

Docker Image Tag

Docker uses tag to further differential different image with a same name. For example, if you search for python image for docker, it contains many version of python.

If we pull python:latest, the image will include both python2  and python3. We can download a specific version of python using different tag. On the docker for python webpage, there are many tags. The screenshot below is just a portion of the tag.

We can even download older version of Python using the tag.

Now, lets pull the slim version of Python 3 using the command below

docker pull python:3.7-slim

Resulting screenshot is as follows:

This image is much smaller than the default image python:latest. The default version contain both Python2 and Python3. The slim 3.7 version only contain Python 3.7 without any additional libraries.

Community Docker Image

There are also community developed docker images. The name of these images are prefix by their user account. For example, Google also supply docker image for its machine learning platform Tensorflow. The name of the image is tensorflow/tensorflow. The first tensorflow is the name of the account, the second name is the name of image.

Once you have your own docker account, you can create your own docker image. Let's say you have created your own version of hello-world. To identify and differentiate your version against the official version, we name the image as <username>/hello-world. So to pull an image not developed by, we use the naming convention mentioned above.

Now we pull Tensorflow as follows:

docker pull tensorflow/tensorflow

Resulting screenshot as follows:

Managing Images

Please note that all these images takes up hard disk space. To check how big the image size, use the command below:

docker images

We can remove unused docker image using the following command:

docker image rm <image_name>
# Alternatively
docker rmi <image_name>

Please also note that if you have more than one image with the same image name, we must include the tag. Otherwise, the system will remove the image with default tag "latest". Please also note that you need to remove the related container first before you can remove the image.


Thursday, August 23, 2018

Configure Unattended Upgrades on Raspberry Pi

If we were to run Raspberry Pi headless (without attached monitor), it would be nice if we can perform unattended system upgrades. In Debain/Ubuntu class of software, we can perform unattended upgrades using the software package unattended-upgrades. 

To install the software, use the command below: 

sudo apt-get install unattended-upgrades
# Following are additional software required
# we only need mailutils or bsd-mailx, choose 1
sudo apt-get install mailutils
sudo apt-get install bsd-mailx
sudo apt-get install update-notifier-common 

Next, we need to edit the configuration files:

sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

The configuration should be similar as below:

Unattended-Upgrade::Origins-Pattern {
        // Codename based matching:
        // This will follow the migration of a release through different
        // archives (e.g. from testing to stable and later oldstable).
//      "o=Debian,n=jessie";
//      "o=Debian,n=jessie-updates";
//      "o=Debian,n=jessie-proposed-updates";
//      "o=Debian,n=jessie,l=Debian-Security";
// Archive or Suite based matching:
        // Note that this will silently match a different release after
        // migration to the specified archive (e.g. testing becomes the
        // new stable).
//      "o=Debian,a=stable";
//      "o=Debian,a=stable-updates";
//      "o=Debian,a=proposed-updates";

Unattended-Upgrade::Mail "";
Unattended-Upgrade::Automatic-Reboot "true";

Basically, we commented out those type of upgrade we want to apply. The second last line allows the system to email us the status. We must install mailutils or mailx first in Raspbian for the email notification to be effective. The last line allow the system to reboot automatically. Please also make sure that update-notifier-common has been installed.

There are more option that we can set such as reboot time and log file in the configuration file. Uncomment any option when necessary.

Next, we need to amend another auto upgrade configuration file.

sudo nano /etc/apt/apt.conf.d/20auto-upgrades

The configuration files should have the following:

APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Download-Upgradeable-Packages "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::Verbose "1";
APT::Periodic::AutocleanInterval "7";

Finally, we perform a test to see if the upgrade process works:

sudo unattended-upgrade -d -v --dry-run

To enable unattended-upgrade use the following command:

sudo dpkg-reconfigure --priority=low unattended-upgrades


For further reference, please check out the following post:
Debian Wiki UnattendedUpgrades
Ubuntu Community Help: AutomaticSecurityUpdates
Ubuntu Official Documentation: Automatic Updates


Wednesday, August 22, 2018

Introduction to Docker - Day 1

This is a basic introduction to Docker for Mac. Before we starts to understand Docker, we must know about virtual machine. Readers for this blog is familiar with VirtualBox and Parallel. Recently, we are testing various new Linux distribution via virtual machine. So far we have installed more than 10 different flavor of Linux distribution. It takes up more than 80GB of hard disk space.  Since, a lot of them are different flavor of Debian/Ubuntu distribution, there are a lot of repetitive installation.

We are not going to show the standard layered chart. If you preferred the official layered chart, please check out the tutorial from docker. The chart below is an example of what happened to by Macbook Pro.

Linux AppLinux AppLinux AppLinux AppLinux AppLinux App
AntergosFreeBSDManjaroUbuntuElementaryMX Linux
Mac OS X
Macbook Pro Hardware

If we use Docker, then we can dispense with installing different flavor of Linux. We can still have different flavor of Linux in a docker but the foot print is very much smaller and there will be no repetition of base code.

Linux AppLinux AppLinux AppLinux AppLinux AppLinux App
AppAppDocker with Linux Base
Mac OS X
Macbook Pro Hardware

So instead of virtual machine or virtual OS, we have virtual app. This is the basic concept of Docker.

Docker is useful if we are to test an app in a controlled environment. Another use case is to implement development environment. For example, we need to install Octave and Python 3 in our laptop for machine learning. In addition, we also need to test out Tensor-flow a machine learning framework from Google. We can install Python 3 and Octave for Mac. We can also install Tensor-flow. However, all these development environment will be in the same machine and each component may have impact on each other. So it is best if we can isolate each development environment. This is where Docker comes in.

Install Docker

Now, lets dive into Docker. First we need to install Docker. To install Docker for Mac please refer to the nice tutorial from Docker. If you want install Docker in other system please refer to the main page of Docker documentation.

Docker for Mac

To explore the details on Docker for Mac, please refer to this site: . This site contains everything about Docker for Mac. However, we will go through them on a gradual progressing pattern.

Basic Command for Docker

Now that you have Docker installed in your system. You have a little whale on your top menu bar. Lets try some basic command. Docker uses terminal heavily, please fire up your terminal.

Check Docker Version

Use the following command to check the version of various component of Docker:

# Check the version of Docker
docker --version
# Check the version of Docker Compose
docker-compose --version
# Check the version of Docker Machine
docker-machine --version
# Check if current Docker is running experimental server
docker version -f {{.Server.Experimental}}

The result should be something similar as below:

Test Docker

To test if your Docker is running properly use the command below:

docker run hello-world

You should received the following message

Now lets examine the command line:
  • The first word docker tell bash shell that this is a docker command.
  • The second command is to instruct Docker to run something.
  • The third word hello-world is the name of a docker image.

A docker image is an image of an app.  When we execute the command, docker will check if there is any image in your local repositories that are named hello-world. If docker can't find any, it will pull the image from the main docker server and run it. If we run the same command again, you will received similar message:

Please note that the message unable to find image 'hello-world:latest' locally disappear. This is because we have previously downloaded the image. Docker just run the same image again.

Docker Image and Container

So lets get acquainted with 2 terms, Docker Image and Docker Container. A Docker Image contains an app. It is similar to the dmg file we download for Mac app. Usually, we run an image just like running an app.  Although technically, we can include more than one app in an image, but this defeat the purpose of isolation. Docker recommended that we put one app per image.

When we run an app like hello-world, it is actually running in a Docker Container. A Docker Container is an isolating environment or mini OS where an image can be run on.  So image is like an installation package and the container is just like a mini runtime environment. Once we exit the app, then the container is consider spent.

Checking Container

Now lets run the following command to check our container:

docker container ls

As you can see, there is no container. Actually, there is no active container. The command ls only list down any active container we have.

To check all containers including spent/used containers:

docker container ls -a

Now the system show 2 used container as below:

Every time we run an image it will create a new container.

As you can see from above, both container has the same image name. The only way to differentiate both containers are container ID and container names.

When we run the image, we do not give the container any name. By default, the system will give each container a different random name if we fail to provide a name while running it.

Now, let's remove the first container. Since we can identify them using container ID, we will remove the first container using container ID. Use the following command:

docker rm db65a18fc87a

After removing the container, when we list the container. Only one container left as shown below:

Next, we remove the remaining container using container name.

docker rm romantic_banach

Now there is no container left as shown below:

Now lets check out any images we stored locally. Use the command:

docker images

We have one image stored locally. Similarly, we can identify the image using image name or image ID.

To remove the local image, use the command

docker image rm hello-world
# Alternative command
docker rmi hello-world

There will be no image left.


Lets recap what we have learn:
  1. A docker image contains the code of an application. We run the image in order to execute the application.
  2. A docker container is an isolating environment which a docker image runs on.
  3. To run an image for testing use command: docker run hello-world
  4. To list active container: docker container ls
  5. To list all container including inactive container: docker container ls -a
  6. To remove a container: docker rm <container_id/name>
  7. To list all locally stored image: docker images
  8. To remove a local image: docker image rm <image_name/id>

We will stop for now. In the next post, we will look into images and pulling images.