In this blog post I want to show how to get your very own internet available object storage system using OpenStack Swift and Docker. Also it will be terminated by SSL (though with a self-signed certificate).
It's important to note that this is a special case OpenStack Swift setup--it only has one storage device and will only make one replica, which I call OpenStack Swift OnlyOne. Normally Swift installations are huge! But his one is small, which I think is cool. Or fun. But not fun and cool. That's too much.
This is what we are going to do:
Handily Digital Ocean has an image that comes with Docker 1.0 already. I'm going to use the tugboat CLI.
curtis$ tugboat images --global | grep Docker Docker 1.0 on Ubuntu 14.04 (id: 4296335, distro: Ubuntu) Dokku v0.2.3 on Ubuntu 14.04 (w/ Docker 1.0) (id: 4381169, distro: Ubuntu)
Let's boot it. 66 is the 512MB image.
NOTE: If you really plan on using this for work instead of just testing Swift, a larger droplet size will likely be necessary. I did get some out of memory errors with the 512MB size.
curtis$ tugboat create swifty-onlyone -i 4296335 -s 66 -k 118429 Queueing creation of droplet 'swifty-onlyone'...done curtis$ tugboat droplets swifty-onlyone (ip:
, status: new, region: 4, id: 1945827)
Wait until it's active, then ssh in.
curtis$ tugboat droplets swifty-onlyone (ip:
, status: active, region: 4, id: 1945827) curtis$ ssh root@ SNIP! root@swifty-onlyone:~#
Add xattr attribute to fstab for root and remount.
NOTE: Swift requires the file system support xattr. I'm not sure if it's enabled by default or not.
root@swift-onlyone:~# # vi /etc/fstab and add user_xattr root@swift-onlyone:~# grep xattr /etc/fstab UUID=050e1e34-39e6-4072-a03e-ae0bf90ba13a / ext4 errors=remount-ro,user_xattr 0 1 root@swift-onlyone:~# mount -o remount /
Pull some docker images:
root@swift-onlyone:~# docker pull busybox; docker pull serverascode/swift-onlyone; docker pull serverascode/pound
Now we have all those images locally.
root@swifty-onlyone:~# docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE serverascode/swift-onlyone latest 1b562d4e3975 3 hours ago 349.2 MB serverascode/pound latest 2bfef1fdc39d 3 hours ago 285.2 MB busybox buildroot-2013.08.1 d200959a3e91 3 weeks ago 2.489 MB busybox ubuntu-14.04 37fca75d01ff 3 weeks ago 5.609 MB busybox ubuntu-12.04 fd5373b3d938 3 weeks ago 5.455 MB busybox buildroot-2014.02 a9eb17255234 3 weeks ago 2.433 MB busybox latest a9eb17255234 3 weeks ago 2.433 MB
We're going to create three containers:
First, create a volume only container.
root@swift-onlyone:~# docker run -v /srv --name SWIFT_DATA busybox root@swift-onlyone:~# docker ps -a | grep DATA 838c68ce031b busybox:buildroot-2014.02 /bin/sh 15 seconds ago Exited (0) 14 seconds ago SWIFT_DATA
Should see a volume in /var/lib/docker/volumes now.
root@swift-onlyone:~# ls /var/lib/docker/volumes/ 1b6e87f07e2e5c0e49362bfa51f22fb8a32bca691a12d5c5872db0b90baf5241 _tmp
Now create the OnlyOne container using a volume from SWIFT_DATA. Make sure to call it SWIFT.
Please note a couple of environment variables being set:
root@swift-onlyone:~# docker run -d -e SWIFT_SET_PASSWORDS=yes -e SWIFT_STORAGE_URL_SCHEME=https --volumes-from SWIFT_DATA --name SWIFT -t serverascode/swift-onlyone
If SWIFT_SET_PASSWORDS=yes was set, then the password will be echoed to the container log.
As an example, below it's been set to: laibiibooghu.
root@swift-onlyone:~# docker logs 6807caaaaf3b | head Ring files already exist in /srv, copying them to /etc/swift... Setting default_storage_scheme to https in proxy-server.conf... storage_url_scheme = https Setting passwords in /etc/swift/proxy-server.conf user_test_tester = laibiibooghu .admin user_test2_tester2 = laibiibooghu .admin user_test_tester3 = laibiibooghu Starting supervisord... Starting to tail /var/log/syslog...(hit ctrl-c if you are starting the container in a bash shell) Jun 27 16:46:24 6807caaaaf3b object-replicator: Starting object replicator in daemon mode.
Finally create a pound container. This will be the ssl termination point and will be available from the Internet.
This container will be linked to the SWIFT container.
root@swift-onlyone:~# docker run -d --link SWIFT:SWIFT -p 443:443 -t serverascode/pound
Now we have three containers, two of them running, and the other being the volume only container.
root@swift-onlyone:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2f6dcdae1db2 serverascode/pound:latest /bin/sh -c /usr/loca 15 seconds ago Up 14 seconds 0.0.0.0:443->443/tcp naughty_turing 76d27dafa403 serverascode/swift-onlyone:latest /bin/sh -c /usr/loca About a minute ago Up About a minute 8080/tcp SWIFT,naughty_turing/SWIFT 838c68ce031b busybox:buildroot-2014.02 /bin/sh About an hour ago Exited (0) About an hour ago SWIFT_DATA
Now from my laptop I can run the swift command line.
curtis$ alias sw='swift --insecure -A https://
/auth/v1.0 -U test:tester -K ' curtis$ sw stat Account: AUTH_test Containers: 0 Objects: 0 Bytes: 0 Content-Type: text/plain; charset=utf-8 X-Timestamp: 1403882745.61961 X-Trans-Id: tx28102150d50b484a92f3a-0053ad8cf9 X-Put-Timestamp: 1403882745.61961
And upload a directory with a file in it.
curtis$ echo "hi" > index.html curtis$ sw upload www index.html index.html
Set permissions so that anyone can read the files in the www container, ie. they are public.
curtis$ sw post --read-acl='.r:*,.rlistings' www curtis$ sw stat www Account: AUTH_test Container: www Objects: 1 Bytes: 3 Read ACL: .r:*,.rlistings Write ACL: Sync To: Sync Key: Accept-Ranges: bytes X-Timestamp: 1403883848.54012 X-Trans-Id: txd858295e7d294d39bdf3e-0053ad921d Content-Type: text/plain; charset=utf-8
Make index.html the default web index.
curtis$ sw post -m 'web-index:index.html' www
Now we can access that page in a web browser, and get the index.html.
curtis$ wget --no-check-certificate https://
/v1/AUTH_test/www/ --2014-06-27 11:48:20-- https:// /v1/AUTH_test/www/ Connecting to :443... connected. WARNING: cannot verify 's certificate, issued by '/C=US/ST=Oregon/L=Portland/O=IT/CN=172.17.0.13': Self-signed certificate encountered. WARNING: certificate common name '172.17.0.13' doesn't match requested host name ' '. HTTP request sent, awaiting response... 200 OK Length: 3 [text/html] Saving to: 'index.html' 100%[====================================================================================================================================================>] 3 --.-K/s in 0s 2014-06-27 11:48:20 (109 KB/s) - 'index.html' saved [3/3] curtis$ cat index.html hi
Note that I just wanted to use that as a demonstration, not the actual use case for Swift. Swift stores unstructured data, which we, as a planet, have a lot of. It doesn't have to serve web pages.
Now for $5 a month you have a little swift install. The storage on that instance is pretty limited, at 20GB, but at any rate you can put all kinds of DevOps reactions gifs there if you want. Or, perhaps use it to create interesting, proof-of-concept scalable web systems.
I should note as well that you could deploy OnlyOne in the same fashion on any Docker host, which is one of Docker's most interesting features.