Deploy a Secure Instance of Owncloud 6 With Docker

I’ve recently bought a new storage server and one of the first softwares I needed is Owncloud. Owncloud provides universal access to your files via the web, your computer and your mobile devices. It’s very similar to dropbox.

Docker allows us to easily create lightweight, portable, self-sufficient containers from any application. If you are not familiar with it, I suggest you read the Docker Getting Started.

Requirements

  • A Linux Machine: I use Ubuntu Precise 12.04. You can also setup a simple vm using vagrant.

  • Docker. Note that if you want to use Ubuntu Precise, you’ll need to install a 3.8 kernel. Just follow the installation instructions of the official docker documentation.

  • Git

Step 1

Pull our base image.

1
sudo docker pull ubuntu:12.04

Step 2

Clone my docker repository, which contains the following files:

  • service/owncloud_ssl: main directory for the owncloud ssl image
  • service/owncloud_ssl/Dockerfile: docker file to build the image
  • service/owncloud_ssl/site-owncloud: nginx site configuration to serve the app.
  • service/owncloud_ssl/start.sh: entrypoint for our container, which starts the application
1
2
git clone https://github.com/aboudreault/docker.git
cd docker/service/owncloud_ssl

Step 3

Edit the Dockerfile configuration. Open ‘service/owncloud_ssl/Dockerfile’ file with your editor. There is two config options:

  • APP_DATA: this is the default owncloud value. You don’t have to modify this really.
  • SSL_SUBJ: this is the information required for the SSL Certification generation. Modify this with your own info.

If your server has only one disk partition, you can simply comment the line 30 (VOLUME [“…”]) of the Dockerfile and go to step 4.

In my case, my storage server has two partitions, / with 20G and /mnt/data with 500G. Obviously, I want to use the bigger partition for my owncloud instance. This can be done easily with a docker volume. For now, the only thing we need is to create the directory that will be used for the docker volume.

1
sudo mkdir /mnt/data/owncloud

Step 4

Edit the nginx site configuration. Basically, you only need to modify the server_name with your own site url. Open ‘service/owncloud_ssl/site-owncloud’ file with your editor and modify the line 3: server_name files.alanb.ca;. You can comment that line if you don’t have a specific url yet.

Step 5

Build your docker image. I assume you are already in the service/owncloud_ssl/ directory.

1
sudo docker build --rm -t owncloud_ssl .

Step 6

Deploy your instance!

If you don’t need a docker volume:

1
sudo docker run -P -d -t owncloud_ssl

If you need a docker volume:

1
sudo docker run -P -d -v /mnt/data/owncloud:/var/www/owncloud/data -t owncloud_ssl

You’re instance should now be running. You can verify this with:

1
sudo docker ps

The above command also tells you what is the container id of your instance and what port of your main machine has been mapped to the container port 443. You can get more information about the container with the inspect command (ports, ip address, volume, etc.):

1
sudo docker inspect <container_id>

Step 7

Access your application. You can quickly test your instance using wget. You’ll need to know the host port that is mapped to the container port 443.

1
wget https://localhost:<mapped_port>

At this step, it’s up to you how you want to expose your application. Some options:

  • If you have many public ip addresses, you can simply use iptables to forward the ip/port (443) traffic directly to the container.

  • You can setup a ssl nginx proxy that listen port 443 on the main machine that will take care to pass the requests to the container.

  • If you use vagrant, check the documentation to forward a port.

  • In my case, I’ve created a basic haproxy instance with docker. If you are interested, you might want to take a look at it in my repository.

I hope this helped you to get started.

New Year, New Start

Since my decision to quit Mapgears last september, I’ve had the chance to work with Blaise Laflamme on a startup project. It has been a so good experience to work as a freelance developer that I’ve decided to continue that way.

I’m pleased to announce that this new year is a new start for me as a freelance developer. You can take a look at my resume to see my experience. I would love to hear about your project and see how we can work together.

Feel free to contact me by email.

I’m Looking for New Opportunities

After six years at Mapgears, I’ve recently decided to quit my job. Mapgears has been my first and only job in computer science. It is the best company so far that I could have expected to begin my career. I have had the chance to learn a lot in geospatial and opensource software development during all these years, especially with the MapServer/OSGeo team. The experience of Daniel (Mapgears President) with his team and all the OSGeo developers I worked with is simply invaluable.

I will not elaborate on the reasons of my decision, but being in the consulting world since I were a student, I beleive it’s time for me to explore something different. I am in very good terms with Mapgears and will be glad to help with the transition. The team is awesome and we are going to collaborate to not affect any clients and projects.

I will be actively looking for new opportunities in the following weeks. My resume is available if you want further information on my background and are looking for a senior software developer.

JavaScript Support in MapServer

I’ve just pushed a first implementation of the javascript support in MapServer master. We can now style our features programmatically rather than writing multiple classes. We have choosen the library V8 as javascript engine. It is an experimental feature but it looks very promising. Here’s an example:

mapfile:

1
2
3
4
5
6
7
8
9
LAYER
    NAME "my_vector_layer"
    TYPE POINT
    STATUS ON
    ...
    STYLEITEM "javascript:///path/to/my/file.js"
    CLASS
    END
END

javascript file that returns a random style:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require('./global_variables.js'); // for symbols array

// random symbol
var symbol = symbols[Math.floor(Math.random()*symbols.length)];
var style = style = "STYLE SIZE 12 SYMBOL '"+symbol+"'";

if (shape.attributes.COULEUR != '#000000') {
    style += "COLOR '"+shape.attributes.COULEUR+"' END";
} else {
    // random color
    red = Math.random()*255;
    green = Math.random()*255;
    blue = Math.random()*255;
    style += "COLOR "+red+" "+green+" "+blue+" END";
}

// return the style to MapServer
style;

result:

For more information, please refer to the RFC: Support of Styleitem JavaScript Plugin

Rendering Smooth Contour With MapServer

As part of the new features of the next release of MapServer (6.4), two of them are particularly interesting if you used to work with contours data:

Here is a small example that uses both features as demonstration purpose. I assume you already know how to create a mapfile with MapServer.

Create a Vector Contour Layer

With a contour dataset (raster), you can define a MapServer contour layer as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LAYER
  NAME "MyContourLayer"
  STATUS DEFAULT
  DATA "wind.tif"
  TYPE LINE
  CONNECTIONTYPE CONTOUR
  PROJECTION AUTO END
  PROCESSING "BANDS=1"
  PROCESSING "CONTOUR_ITEM=elevation"
  PROCESSING "CONTOUR_INTERVAL=0,0:1"
  CLASS
    EXPRESSION ([elevation] >= 0)
    STYLE
      COLOR 0 0 255
    END # STYLE
  END # CLASS
END # LAYER

you will get a contour layer rendered directly in MapServer:

You will notice that the lines are non-smooth curves and it will be worst if you zoom in. Using shape smoothing is very useful for thoses cases.

Enable Smoothing

You can enable the smoothing with the GEOMTRANSFORM directive in the layer (or style) definition:

1
2
3
...
  GEOMTRANSFORM (smoothsia([shape], 5))
...

The rendering is lot nicer with smoothing. These new features are available in the development version of MapServer. You can refer to their RFCs for more information.

Setup a MapServer Development Environment With Vagrant and Chef

A month ago, I watched a DjangoCon 2012 presentation of Julien Phalip named Boosting teamwork with Vagrant. For those who are not familiar with Vagrant, it’s a tool that allows you to create and configure lightweight, reproducible and portable development environments. In the presentation, the case study #1 shows how he built a complete development environment for djangoproject.com. I found it very interesting that a user can setup itself and hence be ready very quickly to contribute to the project.

I’ve been wanted to try Vagrant for a while now and I thought it would be useful to build something similar for mapserver. To help the setup, I also decided to use Chef Solo, which is a tool that allows you to abstract definitions as source code to describe how you want each part of your infrastructure to be built. In my case, I wanted to automate the various configuration tasks rather than doing them by hands.

Before starting the tutorial, you might be interested in learning more about:

Goal

The goal was to get a complete development environment (Ubuntu precise 32bits) with all the following requirements:

  • Configure and install mapserver (branch master, 6.2 and 6.0).
  • Configure and build mapserver docs
  • Configure mapserver msautotest
  • Install Postgresql server, create DB, load msautotest DB data
  • Install and configure web server
  • Serve mapserver as cgi and fastcgi (All versions)
  • Serve mapserver docs website

To setup these requirements, I’ve built a chef cookbook to take care of everything. You won’t have to configure the environment by hands. The tutorial has been tested on a Linux machine but should work properly on Windows and Mac with some adaptations.

Prerequisites

You need the following softwares installed before doing the tutorial.

  • Virtualbox
  • Ruby 1.9, Ruby Bundler and some module dependencies (libxslt, libxml2)

    • For Windows, you can probably find binaries easily.
    • For Mac, I would suggest that you use homebrew.
    • On a Debian/Ubuntu machine, you can use the following command:
1
2
3
  sudo apt-get install ruby1.9.1 ruby1.9.1-dev libxslt-dev libxml2-dev
  sudo gem1.9.1 install bundler

Setup

  • Download the mapserver environment config files. This contains everything you need to make the development environment.
1
2
wget http://dl.alanb.ca/mapserver-dev-1.0.0.tar.gz
tar -zxvf mapserver-dev-1.0.0.tar.gz
  • Setup the ruby environment. This will install all needed ruby modules in the working directory.
1
2
cd mapserver-dev-1.0.0
bundle
  • You might want to take a look at the Vagranfile and edit some config options:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# -*- mode: ruby -*-

require 'berkshelf/vagrant'

Vagrant::Config.run do |config|

  config.vm.host_name = "mapserver-dev"
  config.vm.box = "precise32"
  config.vm.box_url = "http://files.vagrantup.com/precise32.box"

  config.vm.network :hostonly, "192.168.33.2"

  # Modify this if port 8002 or 2202 are already used.
  config.vm.forward_port  80, 8002
  config.vm.forward_port  22, 2202

  # You can comment this if you don't want to share your home directory, or add
  # any other share folders you need in your dev environment. It is known that
  # this share method is slower than a nfs share, so you may be interested in
  # http://docs-v1.vagrantup.com/v1/docs/nfs.html
  config.vm.share_folder "v-data", "/vagrant_data", "~"

  config.ssh.max_tries = 40
  config.ssh.timeout   = 120

  # Set the virtual environment resource.
  config.vm.customize ["modifyvm", :id, "--cpus", 2]
  config.vm.customize ["modifyvm", :id, "--memory", 1024]

  # do not touch...
  config.vm.provision :chef_solo do |chef|
    chef.run_list = [
      "recipe[mapserver-dev::default]"
    ]
  end

end
  • Make the virtual environment. This will download, setup and install everything.
1
bundle exec vagrant up

This step might take several minutes to complete.

Conclusion

When the setup is finished, you should have a complete development environment for the mapserver project.

  • Basic Vagrant commands:

    • Start the virtual machine: bundle exec vagrant up

    • Stop the virtual machine: bundle exec vagrant halt

    • Destroy the virtual machine: bundle exec vagrant destroy

  • You can log in the machine with one of the following methods:

    • In the working directory of the environment: bundle exec vagrant ssh

    • ssh (user: vagrant, pw: vagrant) ssh -p 2202 vagrant@localhost

  • The source code of the different mapserver versions, mapserver doc and msautotest are in /home/vagrant/src.

  • You can run the msautotest with the usual python run_test.py command. All tests should be succeeded, including postgresql/postgis ones.

  • You can rebuild the doc using make html.

  • Mapserver executables are served by apache2:

Project

The chef mapserver dev cookbook is on github, feel free to contribute.

TODO

In the future versions of the chef mapserver dev cookbook, mapcache and tinyows will be added.