In a question related to the DNS, Docker drank to me thoroughly, for there are so many different places in which they offer you to write the cherished numbers, that they just run away.
So, the task: it is necessary to raise the developer's environment for simultaneous work with several web projects hanging on domains of the form example.app. At the same time, these domains should be accessible from containers, from the host, as well as, for example, from the
Genymotion emulator. In addition, the external Internet should be accessible from the containers. All of this is compounded by the corporate Intranet with its internal DNS server.
To solve, we need:
- docker - container engine
- docker-compose - working with multi-container solutions
- dnsmasq - easy DNS (as well as DHCP and TFTP) server
- laradock (optional) - ready multi-container solution for developer
Installation of PP.1-3 skipped as obvious. Pay attention to the version of docker-compose,
we need version 1.8 or higher (at the time of writing, the old version was in the repositories).
')
For an experienced
dock dock worker, there is no problem in choosing the right images, linking them, forwarding ports, installing additional libraries — there is enough information on this topic. But if you want to start work right now, then let's use the product of the collective conscious -
laradock .
From the name laradock you can reveal a hint at the Laravel + Docker bow. So it was originally, but at the moment this focus is gone and now the project focuses on any web application.
So,
laradock is a yml file and a set of accompanying configured images for
docker-compose
, allowing you to deploy a set of containers with nginx, mysql, mongoDB and a bunch of different bunches like Memcached, Aerospike, etc. (now the set is very wide and is constantly expanding).
It is also important that the installation of some additional plug-ins or libraries is reduced to a simple editing of the yml-file, for example:
- INSTALL_XDEBUG=true
and rebuilding the image:
docker-compose build php-fpm
In addition, everything is ready in laradock to put as many projects there at the same time as your heart desires - just look at the configuration examples in
./nginx/sites
.
laradock pushes port 80 from the nginx / apache container to the host machine, so that after lifting the required containers (you choose the set yourself)
docker-compose up -d nginx mysql phpmyadmin
to see the example.app and mysite.app sites configured in advance in nginx / apache; you just need to register the local IP for them in the / etc / hosts file
127.0.0.1 example.app 127.0.0.1 mysite.app
The phpmyadmin container is pushed to port 8080, so you can see it at work at http://localhost:8080
. Well, keep in mind that the container with the muscle works for all other containers on the mysql
host to which you should connect.
In fact, if you have isolated projects and do not have a corporate intranet, then you can stop at this place and start developing already. The problem with the DNS did not touch you.If you read further, then you probably need:
- From your application, contact your own separate backend on another domain.
- From the application running in the Android emulator (iOS, etc.), contact your backend.
- From your application, access a third-party API, but you are on an intranet with a local DNS server.
So, we solve points 1 and 2. Point 3 will be solved by itself, by adding just one line - the address of your intranet DNS. Let's make our domains available from containers (in particular from php-fpm). For this we need
dnsmasq .
Install it if you have not done it yet:
sudo apt-get install dnsmasq
In order to resolve the DNS name, dnsmasq looks in /etc/resolv.conf in search of the IP of the upstream DNS server. In principle, we could write it in there, but it is clearly written in this file that you should not change it, because it can be overwritten. Therefore, we will create our own /etc/resolv.ext.conf file with the following contents:
Now you need dnsmasq to use it. In the /etc/dnsmasq.conf file, you need to find, uncomment and correct the parameter, specifying our file there:
resolv-file=/etc/resolv.ext.conf
However, not everything is so simple ... cunning dnsmasq will not use it until we perform another manipulation.
Here you need to make a small remark: you can not bother with your own configuration file, but stick the nameserver into the original resolv.conf, but stick it correctly. You need to put them in /etc/resolvconf/resolv.conf.d/head and then they will automatically be added at the beginning of resolv.conf However, keep in mind that there can only be 3 time servers, and in your file - as many as you like.
But back to our case. In order for our resolv.ext.conf to be read all the same, it is necessary to specify in the / etc / default / dnsmasq file:
IGNORE_RESOLVCONF=yes
What kind of nonsense, you say ... Ignore the file to read it? Not certainly in that way. The comment before this option clearly explains what it does. We make dnsmasq ignore the output of the resolvconf
utility if it is installed and pay attention to our file.
In general, that's all. It remains only to explain to Docker that in our little world, dnsmasq is responsible for resolving the DNS. When installing, Docker creates the docker0 interface, we define the IP of our computer in this subnet:
ifconfig | grep -A1 docker0
we get something like this:
docker0 Link encap:Ethernet HWaddr 02:82:c5:3c:31:60 inet addr:172.17.0.1 Bcast:0.0.0.0 Mask:255.255.0.0
Open / etc / default / docker and specify the found IP:
DOCKER_OPTS="--dns 172.17.0.1"
Restarting services:
sudo service dnsmasq restart sudo service docker restart
and...... hitch up again:
it only works if your system uses
Upstart or
SysVinit initialization (this is clearly written in this file). But if you use, for example, Ubuntu 15.04 or higher, then you already use a more advanced
systemd and we need additional gestures. But first, let's check what we use:
$ sudo stat /proc/1/exe : '/proc/1/exe' -> '/lib/systemd/systemd'
As you can see, it is clear from the output of the command that we use systemd.
Well, let's cure this too. The configuration of the service initially lies in /lib/systemd/system/docker.service. You can simply copy and edit:
sudo cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service
but we will act more decently - we will change only what should be changed:
sudo [ ! -e /etc/systemd/system/docker.service.d/ ] && mkdir -p /etc/systemd/system/docker.service.d/ sudo cat << 'EOF' > /etc/systemd/system/docker.service.d/docker.conf [Service] EnvironmentFile=-/etc/default/docker ExecStart= ExecStart=/usr/bin/dockerd -H fd:// $DOCKER_OPTS EOF
As you already understood, we created the file /etc/systemd/system/docker.service.d/docker.conf (the so-called drop-in) with changes to the standard parameters and transfer our dns parameters written in
/etc/default/docker
when start the service.
It remains only to restart the services:
sudo systemctl daemon-reload sudo service docker restart
and make sure everything is in order:
sudo service docker status
In the output of this command, you will see a lot of familiar: the connected drop-in, and the service that started with our dns. Now really
ALL !
Update:In
DOCKER_OPTS
it is better to specify the host IP on the docker0 subnet.
Useful links: