ownCloud on Docker + CentOS 7

Docker-shippingLooking for a Canadian-based Dropbox alternative that’s also easy to setup and manage? Look no further. Using the power of Docker as well as Cloud Brewery’s open-source docrane project, we’re going to create a self-healing ownCloud installation, that’s also easy to patch and upgrade. In this tutorial, we’re going to be using CentOS 7 as our Docker host, however you can adapt these instructions for any other Linux distro.

To get started, let’s grab and install Docker:

curl https://get.docker.com | bash
usermod -a -G docker centos

That may take a few minutes to complete. This might be a good time to grab a coffee.

Next up, we’re going to install docrane (and it’s dependencies):

easy_install pip 
yum install -y git libffi-devel gcc python-devel
git clone https://github.com/CloudBrewery/docrane.git
cd docrane && pip install -r requirements.txt && python setup.py install

In order to run docrane, we’re going to use supervisord. You could also use systemd, but we like supervisor for its simplicity as well as it’s auto-restart functionality.

pip install supervisor
mkdir -p /etc/supervisord/conf.d /var/log/supervisor /var/log/docrane 
chown centos /var/log/docrane && chown centos /var/log/supervisor
wget -O /etc/supervisord/supervisord.conf https://raw.githubusercontent.com/CloudA/examples/master/generic/centos7/supervisord.conf

Next up, let’s configure supervisor to run via systemd:

wget -O /usr/lib/systemd/system/supervisord.service https://raw.githubusercontent.com/CloudA/examples/master/generic/centos7/supervisord.service
systemctl enable supervisord && systemctl start supervisord
systemctl enable docker && systemctl start docker

This will configure docrane’s supervisor program:

wget -O /etc/supervisord/conf.d/docrane.ini https://raw.githubusercontent.com/CloudA/examples/master/generic/centos7/docrane.ini

Next, in order to run docrane, we’ll need to bootstrap an etcd Docker container. Docrane uses etcd to read its configuration from so that it knows what Docker containers to run and how to run them. You’ll note in the config file above that we specified a -p etcd in our docrane command. This tells docrane to run a docker start on the etcd container prior to booting the rest of its containers.

HostIP="$(ip a show docker0 | grep "inet " | awk '{ print $2 }' | sed -e 's_/[0-9]*__')" docker run -d -p 4001:4001 -p 2380:2380 -p 2379:2379 --name etcd quay.io/coreos/etcd:v2.2.5  -name etcd0  -advertise-client-urls http://${HostIP}:2379,http://${HostIP}:4001  -listen-client-urls http://0.0.0.0:2379,http://0.0.0.0:4001  -initial-advertise-peer-urls http://${HostIP}:2380  -listen-peer-urls http://0.0.0.0:2380  -initial-cluster-token etcd-cluster-1  -initial-cluster etcd0=http://${HostIP}:2380  -initial-cluster-state new
yum install -y wget && cd ~ 
wget https://github.com/coreos/etcd/releases/download/v2.2.5/etcd-v2.2.5-linux-amd64.tar.gz
tar xf etcd-v2.2.5-linux-amd64.tar.gz
mv etcd-v2.2.5-linux-amd64/etcdctl /usr/local/sbin/ && rm -Rf etcd-v2.2.5-linux-amd64*

Let’s make sure that everything is running properly by creating our /docrane etcd directory and booting up docrane without any containers configured.

etcdctl mkdir /docrane && supervisorctl reload && supervisorctl update
tail -f /var/log/docrane/docrane.log

The log should output something like this:

2016-02-23 14:19:47,611 - docrane - WARNING - ---- Starting docrane ----
2016-02-23 14:19:47,611 - docrane - WARNING - Pre-booting etcd
2016-02-23 14:19:47,722 - docrane - INFO - Containers found:
2016-02-23 14:19:47,723 - docrane - INFO - []

Next, let’s configure our containers in etcd. We’re going to put our Docker volumes in /opt for ease of access.

mkdir /opt/mysql-data /opt/owncloud-data
export MYSQL_PASS=$(strings /dev/urandom | grep -o '[[:alnum:]]' | head -n 30 | tr -d '\n'; echo)
etcdctl set /docrane/mysql/image mysql
etcdctl set /docrane/mysql/tag 5.7
etcdctl set /docrane/mysql/volume_bindings '{"/opt/mysql-data": {"bind": "/var/lib/mysql", "mode": "rw"}}'
etcdctl set /docrane/mysql/volumes '["/var/lib/mysql"]'
etcdctl set /docrane/mysql/environment "{'MYSQL_ROOT_PASSWORD': '$MYSQL_PASS'}"
etcdctl set /docrane/owncloud/volume_bindings '{"/opt/owncloud-data": {"bind": "/var/www/html", "mode": "rw"}}'
etcdctl set /docrane/owncloud/volumes '["/var/www/html"]'
etcdctl set /docrane/owncloud/image owncloud
etcdctl set /docrane/owncloud/links '{"mysql": "mysql"}'
etcdctl set /docrane/owncloud/ports '{80: 8888}'
etcdctl set /docrane/owncloud/tag 8.2.2-apache

Our final step in booting our containers is to restart docrane so that it picks up our newly configured containers. Note that docrane will watch these etcd directories now that it is aware of them, so any changes to the owncloud or mysql etcd key/value pairs will cause docrane to restart the container with the new configuration applied.

supervisorctl restart docrane && tail -f /var/log/docrane/docrane.log
Output:
2016-02-23 14:27:19,697 - docrane - WARNING - ---- Starting docrane ----
 2016-02-23 14:27:19,698 - docrane - WARNING - Pre-booting etcd
 2016-02-23 14:27:19,727 - docrane - INFO - Containers found:
 2016-02-23 14:27:19,727 - docrane - INFO - [u'mysql', u'owncloud']
 2016-02-23 14:27:19,739 - docrane - INFO - Pulling mysql:5.7...
 2016-02-23 14:28:21,351 - docrane - WARNING - Container mysql not running.
 2016-02-23 14:28:21,352 - docrane - INFO - Creating mysql...
 2016-02-23 14:28:21,353 - docrane - INFO - Creating with params: {'config_ports': {}, 'links': None, u'image': u'mysql:5.7', u'tag': u'5.7', 'create_ports': [], 'environment': {'MYSQL_ROOT_PASSWORD': 'n7EEmbl0dOe6TPJTEy3gAueAobjLht'}, 'volume_bindings': {'/opt/mysql-data': {'bind': '/var/lib/mysql', 'mode': 'rw'}}, 'udp_ports': None, 'volumes': ['/var/lib/mysql'], 'volumes_from': None, 'command': None, 'ports': None}
 2016-02-23 14:28:21,753 - docrane - WARNING - Starting mysql...
 2016-02-23 14:28:22,025 - docrane - INFO - Watching container 'mysql'
 2016-02-23 14:28:22,032 - docrane - INFO - Pulling owncloud:8.2.2-apache...
 2016-02-23 14:29:54,830 - docrane - WARNING - Container owncloud not running.
 2016-02-23 14:29:54,831 - docrane - INFO - Creating owncloud...
 2016-02-23 14:29:54,836 - docrane - INFO - Creating with params: {'config_ports': {80: 8888}, 'links': {'mysql': 'mysql'}, u'image': u'owncloud:8.2.2-apache', u'tag': u'8.2.2-apache', 'create_ports': [80], 'environment': None, 'volume_bindings': {'/opt/owncloud-data': {'bind': '/var/www/html', 'mode': 'rw'}}, 'udp_ports': None, 'volumes': ['/var/www/html'], 'volumes_from': None, 'command': None, 'ports': {80: 8888}}
 2016-02-23 14:29:55,365 - docrane - WARNING - Starting owncloud...
 2016-02-23 14:29:55,998 - docrane - INFO - Watching container 'owncloud'

Finally, let’s create a database for our ownCloud installation to use. Note the MySQL root password that you generated can be accessed by running etcdctl get /docrane/mysql/environment. Also, we highly recommend using a more secure password than mysecretpassword for your owncloud user.

docker exec -it mysql bash
TERM=xterm mysql -u root -pn7EEmbl0dOe6TPJTEy3gAueAobjLht
 create database owncloud;
 grant all on owncloud.* to 'owncloud'@'%' identified by 'mysecretpassword';
exit
exit

Now that we have our ownCloud installation up and running, we’ll need to finalize the configuration. To do so, we’ll need to browse to our installation by going to http://<PUBLIC_IP>:8888/. Make sure that TCP port 8888 is opened in your security group.

owncloud-screen1

To configure ownCloud to use our MySQL install rather than the default SQLite database, we’ll need to click on “Storage & database” and select “MySQL/MariaDB. From there, we’ll want to enter the MySQL details that we configured above. Note that because we’re using Docker linking, the hostname is mysql.

owncloud-screen2

Make sure to fill in an admin username and password and click “Finish setup”. After a few seconds, you should be greeted by the ownCloud “Files” screen.

owncloud-screen3

And there we have it! A working installation of ownCloud running in Docker.