Wow it has been a long time since I did a blogpost. However I had this one coming as I got asked about how I used Docker in my current workflow. I used to be – and still am – a big Vagrant fan, however Vagrant is not very suited for development. It is great for managing and provisioning vboxes. But a vbox is sluggish and a resource hog. Vboxes weren’t meant for development, they were meant to run a complete OS on top of yours in a contained fashion.
If you need to run your software on something other than linux, then I still hearty recommend Vagrant for managing those boxes.
If however your website is running on a linux system, then you can leverage the power of Docker.
This blogpost will show you how to quickly setup a Debian environment running Apache, PHP and a database (Postgresql).
Docker Debian Images
head over to https://github.com/NickBelhomme/DockerImages and download and extract the repo.
Alternatively for those who work with git you can
git clone firstname.lastname@example.org:NickBelhomme/DockerImages.git
Once you have the package extracted or cloned just step right into the directory and follow the README.md on how to build the images
we need for this post. https://github.com/NickBelhomme/DockerImages/blob/master/README.md
Using the Docker images
You should now be the owner of 3 images.
nickbelhomme/postgres latest 3d09510dab44 2 hours ago 271.3 MB
nickbelhomme/debianapachephp latest f6eb10d32f1c 2 hours ago 223.6 MB
debian wheezy 29853cd4f422 42 hours ago 85.19 MB
You can ignore the hashes, these are random at build time.
So how do we use it?
The first thing we need is 1 additional project or projects if you are a busy bee. In this blog post I have included one demo project.
issue the following command:
docker build -t nickbelhomme/application .
you now end up with 4 images including a
nickbelhomme/application latest 7d4f26227028 33 minutes ago 223.6 MB
If you take a look at the Dockerfile you just issued a build on, you notice we use our previous nickbelhomme/debianapachephp image
as a start.
The only thing we apply on top of this image is an extra vhost setting and we enable it.
The Magic of Apache + PHP
Now that you can spawn as much images for each project you have, it is time to at least use one.
docker run –name test1 -P -d nickbelhomme/application /usr/sbin/apachectl -D FOREGROUND
This will start a Docker container with the ports exposed and made public, in this case port 80.
Exposing a port makes it available for inter-container communication and making it public allows your host system to contact the container processes within. We have exposed port 80 in our main debianapachephp Dockerfile.
The -d tells the container to run daemonized, which just starts the process – in our case “/usr/sbin/apachectl -D FOREGROUND”
and puts it in the background. Docker -d itself needs to have foreground processes (not deamonized), hence us starting apache in the foreground.
You should just get back a hash. This means your docker container is running. Issue a
to see on which port you can access your website.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f718f791dd5e nickbelhomme/application:latest “/usr/sbin/apachectl 2 seconds ago Up 2 seconds 0.0.0.0:49159->80/tcp
this tells us the container its apache port is available through our host on 49159.
Before heading to the browser and issuing a http://local.application.com:49159 we need to add it to our /etc/hosts file.
to get the proper ip address to link to use a ifconfig and you will see the
Docker0 adapter with its IP address. Use that instead of 127.0.0.1.
On Mac or Windows you are using Boot2Docker, so you will need to use the IP of the virtualbox adapter.
Now head over to the browser http://local.application.com:49159 and you will see something such as:
The requested URL / was not found on this server.
Apache/2.2.22 (Debian) Server at local.application.com Port 49159
Success!!! you reached Debian server.
But wait this is not what we wanted. Where is my frigging site???!!!!
Patience is the mother of all things.
Let’s issue ourselves a new container this time mounted with our site:
docker run –name test2 -d -v /home/nick/vhosts/Docker/application/app:/var/www/vhosts/local.application.com -P nickbelhomme/application /usr/sbin/apachectl -D FOREGROUND
With the -v option we mount a local directory inside the container. You must provide absolute paths. The syntax is
[localDir:containerDir]. In our application.conf we have set the document root directory to /var/www/vhosts/local.application.com/public
so we mount it one level up.
Issuing a docker ps again will show us on which port to connect this time: http://local.application.com:49160
You will see:
SQLSTATE  could not connect to server: Connection refused Is the server running on host “localhost” (::1) and accepting TCP/IP connections on port 5432? could not connect to server: Connection refused Is the server running on host “localhost” (127.0.0.1) and accepting TCP/IP connections on port 5432?
This is normal as we haven’t spawned our database container yet.
Lets do that now!
The magic of the Database Postgresql
docker run -d -P –name postgres nickbelhomme/postgres
As you saw we didn’t have to specify a foregound process with this docker run. That is because we have specified the default command to run when starting the container in our postgres Dockerfile.
once this is up and running we can use it to connect it to our application container
docker run –name application -d –link postgres:postgres -v /home/nick/vhosts/Docker/application/app:/var/www/vhosts/local.application.com -P nickbelhomme/application /usr/sbin/apachectl -D FOREGROUND
We connect 2 containers with the –link param. [containerName:alias]
Now you see why we use the –name param when doing a docker run. More use cases you’ll see later.
Going to the browser again on the new port we will see:
SQLSTATE  FATAL: password authentication failed for user “nick” FATAL: password authentication failed for user “nick”
Which is rather awesome because that means you made a connection. We didn’t setup the user nor the database yet but that we can arrange soon.
Let me first explain why the connection worked out of the box.
Docker uses exposed ports for inter communication it also uses ip addresses between containers. These settings are made available through the –link [containerName:alias] system. The linked container now has access to ALIAS ENVS such as:
and you can use them in your application. You can find such envs by issuing a
docker run –rm –link postgres:postgres -P nickbelhomme/application env
here you are not running a container in deamonized mode but just issue an env command against the container and when finished you
throw the container away (–rm)
We however want to go inside a postgres container so we can create a user and database.
docker run –rm -t -i –link postgres:postgres nickbelhomme/postgres /bin/bash
This opens an interactive (-i) / pseudo-tty (-t) bash in container throw away mode
Inside we can issue postgresql specific commands
createdb nickdb -h $POSTGRES_PORT_5432_TCP_ADDR -p $POSTGRES_PORT_5432_TCP_PORT -U docker
psql -h $POSTGRES_PORT_5432_TCP_ADDR -p $POSTGRES_PORT_5432_TCP_PORT -d docker -U docker –password
CREATE USER nick WITH PASSWORD ‘1234’;
ALTER database nickdb owner to nick;
Again here you can see the env variables being used. You can also type them yourself, but as long as you use
the postgres alias the environment variables naming will remain the same.
The postgresql password for the user docker is docker. We have set this up in our postgres Dockerfile.
You can leave this terminal by leaving psql by typing
and then the terminal by
After you have created the DB and granted the user access it is time to visit the application again.
go to your browser tab of the container named application and refresh.
“no couples table” is displayed on the screen.
Lets populate it.
head over to
and then go back to http::local.application.com:[application PORT]
you should see:
male: nick woman: chanie
male: pixel woman: cookie
to stop working we simply stop the running containers
you do not need to remove the images
you do not need to remove the containers, however you can stop them to safe resources
docker stop application/postgres
docker stop application
docker stop application/postgres application
or if you want to stop the entire postgres (shared with other applications)
docker stop postgres
Start working on the project again
docker start application/postgres
docker start application
docker start application/postgres application
each time you stop and start a container you will get new values for POSTGRES_PORT_5432_* so
if you hardcoded the ip instead of using the getenv technique you have to use the trick I showed
you on how to get the env variables.
Removing Images and Containers
When you do not need a project or container anymore you can remove containers by name or hash
docker rm application/postgres
docker rm application
Or the image
docker rmi nickbelhomme/application
docker rmi nickbelhomme/debianapachephp
docker rmi nickbelhomme/debian
docker rmi nickbelhomme/postgresql
when remove the postgres containers you also remove all database data. To see where the data is stored issue an
docker inspect postgres and see the volumes part.
Creating a clean slate
remove all containers and all images
docker rm $(docker ps -aq)
docker rmi $(docker images -q)
Windows or OSX
Mac and windows use boot2docker.
As stated above in the post, you need to use instead of 127.0.0.1 the vboxnet adapter used for the virtualbox.
You need to install a custom build someone put on the internet or create it yourself:https://medium.com/boot2docker-lightweight-linux-for-docker/boot2docker-together-with-virtualbox-guest-additions-da1e3ab2465c This enables Guest additions needed for sharing host folders in your vbox. The same way as vagrant makes available its shared folders within the box. (vbox/settings/shared folders). After you mounted the folder you can use the vbox path to mount it to the container.
Happy Dockering ,
This copy paste functionality is however smart adaptive powered by a strong AI. It adapts to your needs.
If you need to copy the key, value and storage type to a string of text it is sufficient to right click on a storage, select copy from the context menu and paste the string into your favorite text-editor. Nothing new right?
Wrong. Try to paste the same copy in the FireStorage Plus! panel and you will get a duplicate storage key added with a counter suffix to avoid collisions. However if you paste the storage into the panel on a different host the exact same storage will now be set on the new domain / website.
This is very useful to transfer storages between different environments by the means of a simple copy paste.
This is an excellent feature to maximize your development regarding web storage.
Go ahead try to copy paste the storages within the panel accross different sites / environments.
Thanks for reading and I wish you nice adventures with HTML5 Web Storage.
What is the Firefox Add-on “FireStorage Plus!” all about?
First It is about you!
Secondly it is about HTML5 Web Storage mechanisms.
Where can I find it?
First you need the Firebug addon: https://addons.mozilla.org/en-US/firefox/addon/firebug/
Then you need the FireStorage Plus! addon: https://addons.mozilla.org/en-US/firefox/addon/firestorage-plus/
The FireStorage Plus! addon is an extension to the wonderful tool Firebug.
Why would I need it?
You cannot imagine how many companies – such as Google, Facebook, Twitter, and so many more – use HTML5 web storage to store information about your usage and their interface. With this tool you can inspect that storage and know exactly what they are storing.
Does it work for developers?
For developers it goes even further by showing you the storage mechanism that has been used to store the info. With a quick glance you will be able to spot whether it has been stored in sessionStorage – in which all information will be removed when you close your browser – or in localStorage – in which the information stays infinite or till the site decides it can drop the info.
What kind of improvements can I expect in the near future?
This is off course the first version (V1.0) and it provides all basic information you need with nice JSON formatting.
However we (Me and the contributors) are working hard to also provide in order of importance:
- real time editing and deleting of this information.
- a JSON tab – which will let you unfold different parts of information from the stored JSON object instead of seeing it as a big chunk of text.
- some layout improvements
- indexedDB support
It this addon safe?
Yes it is. The plugin has had a FULL review by members of the Mozillas review committee. Which means they had a look at the code and found it to be clean and ready to be featured in their addons-gallery. Take a look at the source code yourself if you want to check: https://github.com/NickBelhomme/firestorageplus
How do I contribute?
- If you are non-technical you can email me with great ideas and who knows maybe your idea will popup in the next version.
- If you are a developer you might take it a step further and send me code patches / improvements. This can be done through Github, but I also accept regular files through email. I do not care how you submit your implementations I only care about the final result.
What do users say about this addon?
I submitted this addon towards the Mozillas review committee and somebody must really like me or understand the importance of this plugin as it was FULLY reviewed under 24 hours. The first 5 stars review(s) came pouring in shortly after that.
I hope you take the time to try it and give me your feedback,
This weekend (27-28 January 2012) I spoke again at the PHPBenelux Conference and what a sweet conference this is.
An excellent line-up, great organizing and a wonderful networking opportunity. You should attend in 2013, if you are still doubting here are the reasons what made 2012 so special.
Purpose of the entry
Writing about this conference makes my heart jump and grin from ear to ear. I am obliged to write about this event just to vent all the positive feelings I have about this conference. I hope I will be able to give you just a taste of what I am feeling.
- What is #phpbnl12?
- My talk PHP traits, treat or threat
- Who was attending?
- Pros and Cons of this year
What is #phpbnl12?
The PHPBenelux Conference is a two day event organized by PHPBenelux which is a non profit PHP usergroup oranization for the Benelux. They organize meetings and conferences for PHP developers and companies using PHP. These events contain technical talks, workshops and best-practice sessions to share and improve the knowledge among developers. And that is exactly what this yearly conference is about: workshops, best-practices and sharing knowledge among developers.
This year was the third installment of many more to come and was perfectly organized by the PHPBenelux Crew (professionalism for the win).
They managed to get together an excellent schedule full with talks ranging from beginner to advanced. Found some killer sponsors which in turn threw some spectacular after socials. Ibuildings organized a Belgian beer tasting – without the spit-bucket, so you can imagine how that went – and combined that with real Belgian fries. They tasted soooooo good. You had the opportunity to play the Kinect but also could get your hands dirty on some good old Bowling. I kicked the ass of Derick Rethans, David Zülke, Stefano Oldeman and Jeroen Keppens. Unfortunately got my ass kicked by (the lucky cheating bastard ;)) Juozas Kaziukenas in the last round. That was so exciting 123 – 116. Maybe next year dear reader you can challenge me!
The other great sponsor was Engine Yard (Orchestra) and they arranged a BBQ. Those guys know how to entertain and luckily for me they also thought about the vegetarians. I scored a free Engine Yard scarf – which was needed because it was a blistering cold – and scored couple of drinks from some awesome people.
Talking about these social events is important because a conference is soo much more than learning. Hell there is tons to learn but also tons of interesting people to meet.
My talk PHP traits, treat or threat
This talk is an invitation for you to finally embrace PHP5.4. Normally you should already master all the 5.3 features. Heck it has been around for ages to play around with in production. The stable release of PHP5.4 is just around the corner so you should already have been testing all your apps against it. If you haven’t come and see this talk why. It will throw in some new PHP5.4 features / syntax but will of course mainly focus on traits.
The talk in itself was packed with information based on real world examples. This made the slidedeck sometimes spill with code, which I will filter down to a more readable and thus understanding level (got some complaints about too much code confusing it all). The reason why real world examples are chosen is simple: the attendee gets immediate feedback on how and potentially where to use it. He/She sees the possibilities of the feature instead of some academic foo bar examples, for which they can read the manual on php.net. However even if they are more into academic examples they found my slides and presentation far exceeding that. Lets be honest the manual is lacking a lot of information on what is possible with traits. For this you need to really invest in the mailing lists and talk to the PHP core team. That information is in the slides. The talk doesn’t say traits are the holy grail nor that it is evil, I let the attendee decide. I show what is possible with this new language feature without any judgement, but do focus on some best practices and pitfalls.
- I think Nick did a great job and I learnt a lot of new stuff.
- I liked the fact that it was “real code” and not just hello world examples.
- I really enjoyed this talk. Really looking forward to give 5.4 a try
- This was a talk I was really looking forward to. Nick did a good job at explaining traits.
- Very interesting talk; I learned a lot of new stuff and I’m definitely going to play around with traits a bit more
Who was attending?
Approximately 300 attendees with the “open source state of mind” at heart joined the conference. People who love to learn or lecture on everything programming related. It is about so much more than PHP. I urge you to join even if you are programming into a different language like .net or java. There is a wealth on information at this event and you feel the positive vibe of each and every attendee. The sponsors gave away some cool gifts too. ibuildings gave several tickets to DPC12 -another high rated conference- and an iPad2. Enrise raffled several Zend exam vouchers and an Apple Macbook Air (how f* awesome is that??).
Pros and cons this year
- As always excellent venue
- lots to learn at great lectures
- lots of awesome people who are happy to meet you
- sponsored conference social drinks at the hotel => FREE DRINKS for everyone.
- the food really went up a notch this year. This year warm meals were also available and they were Yummie.
- 2 small rooms and 1 main room doesn’t cut it anymore for this conference. At times some of the small rooms were packed. I had to stand at some presentations and during my talk people litterly sat on the floor. I do not know the proportions, but if the room at a seat capacity of 100, then at least 40 extra sat on the floor in front of the chairs.
Great value for money and in general a conference you should attend, no excuses.
See you next year at The PHPBenelux Conference 2013
Thx for reading and feel free to comment,