I’ve been following the Docker movement for quite some time now, and have seen examples of Docker-Compose passing along, so I thought, why not try and setup a nice development environment where I would develop an application that uses Docker-Compose.
For all you tl;dr’s, perform:
git clone --recursive https://github.com/dennisdegreef/blog-docker-compose-infrastructure cd blog-docker-compose-infrastructure vagrant up
DISCLAIMER: This example is just to setup a docker-compose setup for development, and is currently using Symfony’s build-in webserver, which isn’t recommended for production! This is also just a try-out.
For this example, I am creating a simple Symfony application, which needs Redis instance.
First, we need a vagrant plugin to be able to use docker-compose as a provisioner
# vagrant plugin install vagrant-docker-compose
Next, we need to set up a Vagrantfile inside our infrastructure repository, and configure it using the docker provisioner. The provisioner itself will install Docker inside the vagrantbox and build the base image, on which we ‘base’ our own Dockerfile
# Vagrantfile config.vm.provision :docker do |d| d.build_image "/vagrant/docker/base", args: "-t link0/base" end
Now, we want to create an docker-compose.yml file to provide the structure and requirements of our application. This setup explains docker-compose to build the ‘frontend’ image, start it with port 80 exposed, and the current directory linked as /srv
# docker-compose.yml frontend: build: link0/example-frontend ports: - "80:8000" volumes: - .:/srv links: - redis redis: image: redis
Now that we have the docker-compose.yml, we can instruct Vagrant to use that structure upon provisioning.
config.vm.provision :docker_compose, yml: "/vagrant/docker-compose.yml", run: "always"
But before we can run `vagrant up`, we need to add our frontend application into the infrastructure project. I like to use git submodules for this.
git submodule add email@example.com:dennisdegreef/blog-docker-compose-frontend.git frontend
Now we can try it out, see if it works
It still breaks with the following error message
Building frontend... Cannot locate specified Dockerfile: Dockerfile
This is because our frontend application has no Dockerfile to describe how it should be running. Let’s add one.
# blog-docker-compose-frontend/Dockerfile FROM link0/base:latest MAINTAINER Dennis de Greef <firstname.lastname@example.org> COPY start.sh /start.sh CMD [ "/start.sh" ]
#!/usr/bin/env bash # blog-docker-compose-frontend/start.sh cd /srv/frontend; /srv/frontend/composer.phar install && \ /srv/frontend/app/console server:run 0.0.0.0:8000
And when you now run
And point your browser to http://192.168.42.10/ You should be able to see ‘Hello Docker-Compose’.
You can check (tail) the logs using the following command
vagrant ssh -c 'docker logs -f vagrant_frontend_1'
If some things are unclear, please let me know in the comments.
Lately I’ve been playing around with the ESP8266 chipset which is an IoT (Internet of Things) platform which couples digital IO pins with a WIFI connection (I will make another post about this, and link it later on).
What I like about IoT, is that everything is connected and reacting upon each-other. The thing I dislike though, is that the trend seems to be that every piece of hardware has a callback to the mothership (the company selling the equipment).
For example, I have a Philip Hue lighting system. The Hue-bridge device provides a REST-API so you can configure your lights just the way you want automatically. On the other hand, whenever you link it to the MeetHue system, it creates a callback to Philips so you can control your lights using the app, outside your WIFI network. The Nest thermostat does something similar.
When I first came in contact with the ESP8266, it was running the alternative firmware called NodeMCU. This firmware enables you to run Lua code on the chip with a few libraries at hand, including an MQTT client.
This was the first time i’d heard of MQTT, but after a quick google found out that this is ‘just a’ Message Queue like I know from RabbitMQ. The presence of this client library opened my eyes to lots of possibilities for IoT applications inside my home without the need of passing my home internet gateway.
A few examples that I’ve been playing around with
- Controlling a WS2812B LED strip (driver included in NodeMCU :D)
- Reading a temperature and humidity sensor from different places in my house
- Reading out gas and electra readings from my Smart Meter using the P1-data port
- Controlling the air circulation system inside my house (which runs on an NRF-remote)
- Controlling 433Mhz equipment like power outlets (now controlled by a remote)
If I can use the MQTT protocol as a layer on top of all API’s and hardware, this would be kind of similar to how Microservices work.
After setting up an MQTT server (I use Mosquitto, since it supports the MQTT-3.1.1 protocol in the latest versions on my RaspberryPi2), I’ve build some small microservices to start playing with this concept:
I think i’m only at the start of everything that is possible, but i’ll post updates on the expansion of my Microservice network at home.
Please let me know what you think, if you have any questions or feedback. I’m getting really excited about the subject!
Just now, I added a vhost to my nginx configuration on a machine I administer, restart nginx, and am baffled about the following error message:
Starting nginx: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
This is weird… nginx was running just fine up until now, and suddenly won’t start. I tried checking if it was still running, which it wasn’t, tried looking at netstat to see if any other processes are bound to that port.
# netstat -platune
This is weird. Let’s see if I can bind to port 80 myself with ‘nc’.
# nc -v -l 80
It can bind to the port just fine, let’s see if I can connect.
# telnet example.com 80 Trying 203.0.113.128... telnet: connect to address 203.0.113.128: Connection refused Trying 2001:db8:c0ld:c0:ff:ee::1... telnet: connect to address 2001:db8:c0ld:c0:ff:ee::1: No route to host telnet: Unable to connect to remote host
This is weird, the port is open, but it won’t connect. This must be my firewall interfering. After stopping the firewall, the same behaviour persisted.
After trying out some of my google skills, I stumble upon the following post on StackOverflow: http://stackoverflow.com/a/15101745/359664
It seems that because of IPv6, the port is unable to bind.
After rewriting my nginx vhosts’s to the following format, nginx is willing to start and everything is online again.
This makes me wonder, what is happening with my IPv6 traffic?
My IPv4 address is assigned through a DHCP server, and my IPv6 is assigned by a similar concept, namely SLAAC.
I can ping the outside world, and I can ping the machine from the outside.
# ping ipv6.google.com
Let’s check the same things on IPv6.
This looks fine to me… oh wait… Port 80 is not allowed in here… I must have only allowed it in the IPv4 configuration.
After configuring the IPv6 firewall correctly (which you should always do, don’t forget about it is a lesson 😉
I’m still baffled why the IPv6 isn’t working…