Docker è una piattaforma di distribuzione delle applicazioni che isola l'ambiente in cui vengono eseguite, un po' come fa virtualenv per i programmi scritti in Python. A differenza di questo il "contenitore" che viene creato è capace di simulare un intero sistema operativo senza essere però una macchina virtuale.
Per impacchettare una applicazione basta scrivere un "dockerfile"  che specifica a partire da una immagine di base (ad esempio Ubuntu 14.04) quali comandi eseguire per configurare l'ambiente ed installare l'applicazione desiderata. I dockerfile prodotti dalla comunità sono raccolti su un sito chiamato Docker Hub.
Su Ubuntu basta semplicemente caricare lo script di installazione
wget -qO- https://get.docker.com/ | sh

ed inserire il nostro utente nel gruppo docker
sudo usermod -aG docker stefano

A questo punto avremo un eseguibile chiamato "docker" che possiamo usare dal terminale per lanciare le istanze delle applicazioni che ci interessano.
Per costruire un container bisogna lanciare nella cartella dove è presente il dockerfile il comando
sudo docker build -t <nome> .

L'applicazione che ho installato è Wekan (https://github.com/wekan/wekan), un clone di Trello, il cui dockerfile è qui.
L'immagine di base da cui parte per generare i container è una derivata di Ubuntu costruita ad hoc per le applicazioni Meteor chiamata Meteord.
Innanzitutto scarichiamo l'immagine con il comando pull
docker pull mquandalle/wekan

Avviamo il database (MongoDB), che è presente in una immagine separata:
docker run -d --name wekan-db mongo
Con il comando run scarichiamo l'immagine e creiamo un nuovo container, a cui diamo il nome "wekan-db"; con il flag -d diciamo di avviare il processo in background (detached). Adesso creiamo il container dell'applicazione:
docker run -d --name wekan --link "wekan-db:db" -e "MONGO_URL=mongodb://db"  -e "ROOT_URL=https://example.com" -p 8081:80 mquandalle/wekan

Oltre a creare il nuovo container come prima, passiamo due variabili d'ambiente con il flag -e, associamo il container creato in precedenza con il flag --link (dando anche l'alias 'db' ad esso) e redirigiamo la porta 80 'interna' sulla porta 8081 del nostro host.
A questo punto entrando con il browser su http://localhost:8081 vediamo (se è andato tutto bene) l'applicazione.

Altri comandi utili:

docker images (mostra tutte le immagini scaricate, con la loro dimensione)
docker ps -a (mostra tutte le istanze; con il flag -a anche quelle non attive)
docker stop <name> (ferma una istanza in esecuzione)
docker start <name> (avvia una istanza)
docker rm <image> (cancella l'immagine dal sistema)

La differenza fra run e start è che il primo crea un nuovo container dall'immagine, mentre il secondo avvia quello già esistente (utilizzando il nome che gli abbiamo dato, se non abbiamo specificato il flag name ne viene assegnato uno random).

Servizi web via Docker

Abbiamo una macchina virtuale da qualche parte tra le nuvole, che risponde sull'indirizzo example.com, e vogliamo usarla per installarci una applicazione web complessa. Perché non proviamo ad installarci Docker ed avviare qualche servizio? Scopriamo presto che le istanze che girano in un container Docker per loro natura non sono accessibili da reti esterne, pertanto ci vuole qualcosa nel mezzo che permetta di passare il traffico che vogliamo: è il momento di aggiungere un proxy ad Apache!
Innanzitutto abilitiamo il modulo (a2enmod proxy_http) e riavviamo Apache (service apache2 restart).
In /etc/apache2/sites-available/ creiamo un file vuoto, chiamandolo test.example.com e ci scriviamo

<VirtualHost *:8081>
ProxyPreserveHost On
ProxyRequests Off
ServerName wekan.example.com
ProxyPass / http://localhost:8081/
ProxyPassReverse / http://localhost:8081/
</VirtualHost>

A questo punto, collegandosi a https://wekan.example.com:8081 dovremmo accedere all'applicazione.

Questo è solo un esempio di come usare Docker per non "sporcare" il proprio sistema quando si vuole usare una applicazione web. Giocando con le variabili d'ambiente (-e), con l'assegnazione dei volumi (-v) e delle partizioni dell'host (--device) si riesce perfino ad avviare applicazioni desktop senza bisogno di installarle (vedere ad esempio questo articolo per usare Firefox, Libreoffice ed altri tramite Docker).