Neo4j is a different type of database, is a graph database. It is quite cool and it is worth to spend the time to learn how it works.
The main benefit of a graph database is that the information is interconnected as a graph, and allows to execute complex queries very quickly.
One of the sample databases in Neo4j is (big part of) the content of IMDb.com (the movie database). Here is the description of some possible queries:
- Find actors who worked with Gene Hackman, but not when he was also working with Robin Williams in the same movie.
- Who are the five busiest actors?
- Return the count of movies in which an actor and director have jointly worked
In this post
- we install Neo4j in an LXD container on Ubuntu (or any other GNU/Linux distribution that has installation packages)
- set it up so we can access Neo4j from our Ubuntu desktop browser
- start the cool online tutorial for Neo4j, which you can complete on your own
- remove the container (if you really wish!) in order to clean up the space
Creating an LXD container
See Trying out LXD containers on our Ubuntu in order to make the initial (one-time) configuration of LXD on your Ubuntu desktop.
Then, let’s start with creating a container for neo4j:
$ lxc launch ubuntu:x neo4j Creating neo4j Starting neo4j $ _
Here we launched a container named neo4j, that runs Ubuntu 16.04 (Xenial, hence ubuntu:x).
Let’s see the container details:
$ lxc list +----------+---------+----------------------+------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +----------+---------+----------------------+------+------------+-----------+ | neo4j | RUNNING | 10.60.117.91 (eth0) | | PERSISTENT | 0 | +----------+---------+----------------------+------+------------+-----------+ $ _
It takes a few seconds for a new container to launch. Here, the container is in the RUNNING state, and also has a private IP address. It’s good to go!
Connecting to the LXD container
Let’s get a shell in the new neo4j LXD container.
$ lxc exec neo4j -- sudo --login --user ubuntu To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. ubuntu@neo4j:~$ sudo apt update Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease Get:2 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB] Get:3 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB] Get:4 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB] Get:5 http://archive.ubuntu.com/ubuntu xenial/main Sources [868 kB] Get:6 http://security.ubuntu.com/ubuntu xenial-security/main Sources [61.1 kB] Get:7 http://security.ubuntu.com/ubuntu xenial-security/restricted Sources [2,288 B] Get:8 http://archive.ubuntu.com/ubuntu xenial/restricted Sources [4,808 B] Get:9 http://archive.ubuntu.com/ubuntu xenial/universe Sources [7,728 kB] Get:10 http://security.ubuntu.com/ubuntu xenial-security/universe Sources [20.9 kB] Get:11 http://security.ubuntu.com/ubuntu xenial-security/multiverse Sources [1,148 B] Get:12 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [219 kB] Get:13 http://security.ubuntu.com/ubuntu xenial-security/main Translation-en [92.0 kB] Get:14 http://security.ubuntu.com/ubuntu xenial-security/universe amd64 Packages [79.1 kB] Get:15 http://security.ubuntu.com/ubuntu xenial-security/universe Translation-en [43.9 kB] Get:16 http://archive.ubuntu.com/ubuntu xenial/multiverse Sources [179 kB] Get:17 http://archive.ubuntu.com/ubuntu xenial-updates/main Sources [234 kB] Get:18 http://archive.ubuntu.com/ubuntu xenial-updates/restricted Sources [2,688 B] Get:19 http://archive.ubuntu.com/ubuntu xenial-updates/universe Sources [134 kB] Get:20 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse Sources [4,556 B] Get:21 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [485 kB] Get:22 http://archive.ubuntu.com/ubuntu xenial-updates/main Translation-en [193 kB] Get:23 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [411 kB] Get:24 http://archive.ubuntu.com/ubuntu xenial-updates/universe Translation-en [155 kB] Get:25 http://archive.ubuntu.com/ubuntu xenial-backports/main Sources [3,200 B] Get:26 http://archive.ubuntu.com/ubuntu xenial-backports/universe Sources [1,868 B] Get:27 http://archive.ubuntu.com/ubuntu xenial-backports/main amd64 Packages [4,672 B] Get:28 http://archive.ubuntu.com/ubuntu xenial-backports/main Translation-en [3,200 B] Get:29 http://archive.ubuntu.com/ubuntu xenial-backports/universe amd64 Packages [2,512 B] Get:30 http://archive.ubuntu.com/ubuntu xenial-backports/universe Translation-en [1,216 B] Fetched 11.2 MB in 8s (1,270 kB/s) Reading package lists... Done Building dependency tree Reading state information... Done 2 packages can be upgraded. Run 'apt list --upgradable' to see them. ubuntu@neo4j:~$ exit logout $ _
The command we used to get a shell is this, sudo –login –user ubuntu
We instructed to execute (exec) in the neo4j container the command that appears after the — separator.
The images for the LXD containers have both a root account and also a user account, in the Ubuntu images is called ubuntu. Both accounts are locked (no default password is available). lxc exec runs the commands in the containers as root, therefore, the sudo –login –user ubuntu command would obviously run without asking passwords. This sudo command creates a login shell for the specified user, user ubuntu.
Once we are connected to the container as user ubuntu, we can then run commands as root simply by using sudo in front of them. Since user ubuntu is in /etc/sudoers, no password is asked. That is the reason why sudo apt update was ran earlier without asking a password.
The Ubuntu LXD containers auto-update themselves by running unattended-upgrade, which means that we do not need to run sudo apt upgrade. We do run sudo apt update just to get an updated list of available packages and avoid any errors when installing, just because the package list was changed recently.
After we updated the package list, we exit the container with exit.
Installing neo4j
This is the download page for Neo4j, https://neo4j.com/download/ and we click to get the community edition.
We download Neo4j (the Linux(tar)) on our desktop. When we tried this, version 3.1.1 was available.
We downloaded the file and it can be found in ~/Downloads/ (or the localized name). Let’s copy it to the container,
$ cd ~Downloads/ $ ls -l neo4j-community-3.1.1-unix.tar.gz -rw-rw-r-- 1 user user 77401077 Mar 1 16:04 neo4j-community-3.1.1-unix.tar.gz $ lxc file push neo4j-community-3.1.1-unix.tar.gz neo4j/home/ubuntu/ $ _
The tarball is about 80MB and we use lxc file push to copy it inside the neo4j container, in the directory /home/ubuntu/. Note that neo4j/home/ubuntu/ ends with a / character to specify that it is a directory. If you omit this, you get an error.
Let’s deal with the tarball inside the container,
$ lxc exec neo4j -- sudo --login --user ubuntu ubuntu@neo4j:~$ ls -l total 151401 -rw-rw-r-- 1 ubuntu ubuntu 77401077 Mar 1 12:00 neo4j-community-3.1.1-unix.tar.gz ubuntu@neo4j:~$ tar xfvz neo4j-community-3.1.1-unix.tar.gz neo4j-community-3.1.1/ neo4j-community-3.1.1/bin/ neo4j-community-3.1.1/data/ neo4j-community-3.1.1/data/databases/ [...] neo4j-community-3.1.1/lib/mimepull-1.9.3.jar ubuntu@neo4j:~$
The files are now in the container, let’s run this thing!
Running Neo4j
The commands to manage Neo4j are in the bin/ subdirectory,
ubuntu@neo4j:~$ ls -l neo4j-community-3.1.1/bin/ total 24 -rwxr-xr-x 1 ubuntu ubuntu 1624 Jan 5 12:03 cypher-shell -rwxr-xr-x 1 ubuntu ubuntu 7454 Jan 17 17:52 neo4j -rwxr-xr-x 1 ubuntu ubuntu 1180 Jan 17 17:52 neo4j-admin -rwxr-xr-x 1 ubuntu ubuntu 1159 Jan 17 17:52 neo4j-import -rwxr-xr-x 1 ubuntu ubuntu 5120 Jan 17 17:52 neo4j-shared.sh -rwxr-xr-x 1 ubuntu ubuntu 1093 Jan 17 17:52 neo4j-shell drwxr-xr-x 2 ubuntu ubuntu 4 Mar 1 12:02 tools ubuntu@neo4j:~$
According to Running Neo4j, we need to run “neo4j start“. Let’s do it.
ubuntu@neo4j:~$ neo4j-community-3.1.1/bin/neo4j start ERROR: Unable to find Java executable. * Please use Oracle(R) Java(TM) 8, OpenJDK(TM) or IBM J9 to run Neo4j Server. * Please see http://docs.neo4j.org/ for Neo4j Server installation instructions. ubuntu@neo4j:~$
We need Java, and the documentation actually said so. We just need the headless JDK, since we are accessing the UI from our browser.
ubuntu@neo4j:~$ sudo apt install default-jdk-headless Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: ca-certificates-java default-jre-headless fontconfig-config fonts-dejavu-core java-common libavahi-client3 libavahi-common-data libavahi-common3 libcups2 libfontconfig1 libfreetype6 libjpeg-turbo8 libjpeg8 liblcms2-2 libnspr4 libnss3 libnss3-nssdb libpcsclite1 libxi6 libxrender1 libxtst6 openjdk-8-jdk-headless openjdk-8-jre-headless x11-common [...] Setting up default-jdk-headless (2:1.8-56ubuntu2) ... Processing triggers for libc-bin (2.23-0ubuntu5) ... Processing triggers for systemd (229-4ubuntu16) ... Processing triggers for ureadahead (0.100.0-19) ... ubuntu@neo4j:~$
Now, we are ready to start Neo4j!
ubuntu@neo4j:~$ neo4j-community-3.1.1/bin/neo4j start Starting Neo4j. Started neo4j (pid 4123). By default, it is available at http://localhost:7474/ There may be a short delay until the server is ready. See /home/ubuntu/neo4j-community-3.1.1/logs/neo4j.log for current status. ubuntu@neo4j:~$ tail /home/ubuntu/neo4j-community-3.1.1/logs/neo4j.log nohup: ignoring input 2017-03-01 12:22:41.060+0000 INFO No SSL certificate found, generating a self-signed certificate.. 2017-03-01 12:22:41.517+0000 INFO Starting... 2017-03-01 12:22:41.914+0000 INFO Bolt enabled on localhost:7687. 2017-03-01 12:22:43.622+0000 INFO Started. 2017-03-01 12:22:44.375+0000 INFO Remote interface available at http://localhost:7474/ ubuntu@neo4j:~$
So, Neo4j is running just fine, but it has been bound on the localhost which makes it inaccessible to our desktop browser. Let’s verify again,
ubuntu@neo4j:~$ sudo lsof -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME dhclient 225 root 6u IPv4 110811 0t0 UDP *:bootpc sshd 328 root 3u IPv4 111079 0t0 TCP *:ssh (LISTEN) sshd 328 root 4u IPv6 111081 0t0 TCP *:ssh (LISTEN) java 4123 ubuntu 210u IPv6 121981 0t0 TCP localhost:7687 (LISTEN) java 4123 ubuntu 212u IPv6 121991 0t0 TCP localhost:7474 (LISTEN) java 4123 ubuntu 220u IPv6 121072 0t0 TCP localhost:7473 (LISTEN) ubuntu@neo4j:~$
What we actually need, is for Neo4j to bind to all network interfaces so that it becomes accessible to our desktop browser. Being in a container, the all network interfaces means to bind the only other interface, the private network that LXD created for us:
ubuntu@neo4j:~$ ifconfig eth0 eth0 Link encap:Ethernet HWaddr 00:16:3e:48:b7:85 inet addr:10.60.117.21 Bcast:10.60.117.255 Mask:255.255.255.0 inet6 addr: fe80::216:3eff:fe48:b785/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:30029 errors:0 dropped:0 overruns:0 frame:0 TX packets:17553 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:51824701 (51.8 MB) TX bytes:1193503 (1.1 MB) ubuntu@neo4j:~$
Where do we look in the configuration files of Neo4j to get it to bind to all network interfaces?
We look at the Neo4j documentation on Configuring the connectors, and we see that we need to edit the configuration file neo4j-community-3.1.1/conf/neo4j.conf
We can see that there is an overall configuration parameter for the connectors, and we can set the default_listen_address to 0.0.0.0. This 0.0.0.0 in networking terms means that we want the process to bind to all networking interfaces. Let’s remind us here that in our case of LXD containers that reside in private networking, this is OK.
# With default configuration Neo4j only accepts local connections. # To accept non-local connections, uncomment this line: #dbms.connectors.default_listen_address=0.0.0.0
to
# With default configuration Neo4j only accepts local connections. # To accept non-local connections, uncomment this line: dbms.connectors.default_listen_address=0.0.0.0
Let’s restart Neo4j and check whether it looks OK:
ubuntu@neo4j:~$ neo4j-community-3.1.1/bin/neo4j restart Stopping Neo4j.. stopped Starting Neo4j. Started neo4j (pid 4711). By default, it is available at http://localhost:7474/ There may be a short delay until the server is ready. See /home/ubuntu/neo4j-community-3.1.1/logs/neo4j.log for current status. ubuntu@neo4j:~$ tail /home/ubuntu/neo4j-community-3.1.1/logs/neo4j.log 2017-03-01 12:57:52.839+0000 INFO Started. 2017-03-01 12:57:53.624+0000 INFO Remote interface available at http://localhost:7474/ 2017-03-01 13:01:58.566+0000 INFO Neo4j Server shutdown initiated by request 2017-03-01 13:01:58.575+0000 INFO Stopping... 2017-03-01 13:01:58.620+0000 INFO Stopped. nohup: ignoring input 2017-03-01 13:02:00.088+0000 INFO Starting... 2017-03-01 13:02:01.310+0000 INFO Bolt enabled on 0.0.0.0:7687. 2017-03-01 13:02:02.928+0000 INFO Started. 2017-03-01 13:02:03.599+0000 INFO Remote interface available at http://localhost:7474/ ubuntu@neo4j:~$ sudo lsof -n -i COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME dhclient 225 root 6u IPv4 110811 0t0 UDP *:bootpc sshd 328 root 3u IPv4 111079 0t0 TCP *:ssh (LISTEN) sshd 328 root 4u IPv6 111081 0t0 TCP *:ssh (LISTEN) java 4711 ubuntu 210u IPv6 153406 0t0 TCP *:7687 (LISTEN) java 4711 ubuntu 212u IPv6 153415 0t0 TCP *:7474 (LISTEN) java 4711 ubuntu 220u IPv6 153419 0t0 TCP *:7473 (LISTEN) ubuntu@neo4j:~$
The log messages still say that Neo4j is accessible at http://localhost:7474/, which is factually correct. However, lsof shows us that it is boung to all network interfaces (the * means all).
Loading up Neo4j in the browser
We know already that in our case, the private IP address of the neo4j LXD container is 10.60.117.21. Let’s visit http://10.60.117.21:7474/ on our desktop Web browser!
It works! It asks us to log in using the default username neo4j with the default password neo4j. Then, it will ask us to change the password to something else and we are presented with the initial page of Neo4j,
The $ ▊ prompt is there for you to type instructions. According to the online tutorial at https://neo4j.com/graphacademy/online-training/introduction-graph-databases/
you can start the tutorial if you type :play movie graph and press the Run button. Therefore, load on one browser tab the tutorial and on other tab run the commands in the neo4j server from the LXD container!
Once you are done
Once you have completed the tutorial, you can keep the container in order to try out more tutorials and learn more about neo4j.
However, if you want to remove this LXD container, it can be done by running:
$ lxc stop neo4j $ lxc delete neo4j $ lxc list +----------+---------+----------------------+------+------------+-----------+ | NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | +----------+---------+----------------------+------+------------+-----------+ +----------+---------+----------------------+------+------------+-----------+ $ _
That’s it. The container is gone and LXD is ready for you to follow more LXD tutorials and create more containers!
Recent Comments