Docker Diary
Edit: https://staff.vanillaforums.com/discussion/comment/453/#Comment_453
I've been tinkering with Docker, off and on, for the past few months. I finally convinced myself to resolve the remaining issues in getting a basic stack to function in OS X. I'm documenting this here, so if anyone else is interested in getting Docker up and running in OS X, this'll hopefully save them some tears.
This is likely to be a WIP, but here's the start...
I'm not going to write an essay on why Docker is a good option for developing locally instead of using traditional VMs. If you're interested, you can take a look at this article: Why Docker?
Docker in OS X
- Grab the Docker Toolbox. This is the foundation of Docker. You need this.
- Install Dinghy. Docker was basically built for Linux. It requires some specialized OS-level capabilities that just aren't available in OS X. To get around this, Docker needs to run in a tiny Linux VM when run on OS X. This VM has some issues that make effective use of Docker an exercise in frustration. Enter Dinghy. Dinghy is a an open-source tool that wraps the capabilities of
docker-machine, the management application for our VMs, and makes them OS X-friendly. It also carries with it some additional capabilities, like a DNS server and a proxy, so you can automatically map *.docker domains to your containers. You can disable these additional capabilities. Read more about getting Dinghy up and running on its official GitHub page. - Download the attached archive and extract it. I've put together a simple web development stack. It contains three services: nginx, Percona and a PHP-FPM server. This type of multi-container setup is managed by Docker's
docker-composecommand. You can read more here: Docker Compose. - Run
docker-compose upin the extracted base directory. If all goes well, your three containers should be operational. If you didn't disable any of Dinghy's services, you can test this by visiting http://vanilla.docker. If that fails, check the console window for any errors. You can report them in this thread and I'll take a shot at helping you troubleshoot.
Useful commands
docker-compose buildThis command is useful if you change some of your config files. Running this rebuilds your containers with the updated information. If you change some of the config files without running this command, you likely won't see the updates made to your services. If you run the command and still see issues, try the following variant:docker-compose build --no-cachedocker psThis command lists all running Docker containers. If you want to see all containers, even the ones that aren't running, usedocker ps -a.docker rm [Container ID]This command removes a container from your system. Using the previous command, you'll see a container's unique ID as one of the columns. It'll be a random alphanumeric string. Use this value to target a specific container for removal.docker exec -i -t [container ID] bashIf you want to poke around in a running container, this command will help you do it. Again, the container ID can be obtained with thedocker pscommand. When you're done nosing around, justexit.docker-compose helpIt's help. For thedocker-composecommand.docker helpIt's likedocker-compose help, but for thedockercommand.
Additional Light Reading
- Compose File Reference
- Dockerfile Reference
- Images used
This is barely a "getting started", but I'd like to continue developing the doc and the stack. If you have any comments or suggestions, fire away!
Comments
-
Cleaning up after yourself
Every time you download or build an image, Docker keeps a copy of it. This log of images can gobble up disk space if you don't keep an eye on them. You can use the following command to cleanup unused (untagged) images:
docker rmi $(docker images -qf "dangling=true")
Similarly, when you build an image with volumes and leave it up to Docker to sort out mounting points, it will create a data volume and store them without a shelf life. You'll need to prune volumes that are not longer used, manually. To clean up your orphaned volumes:
docker volume rm $(docker volume ls -qf "dangling=true")
0 -
Extending docker-compose.yml
You can override settings in a
docker-compose.ymlwithout editing the file. To do this, you need to create a new file, nameddocker-compose.override.yml, in the same directory. When thedocker-composecommand is run, it will merge the values from the new YML file into the original, thus overriding any values in the original with the values fromdocker-compose.override.yml.Using this, you can add new services, update existing services or make additional configuration modifications, without the need to modify the original. This can be beneficial when you need to make temporary adjustments, including being able to customize your environment between home and the office or in making temporary image version updates (i.e. testing out PHP v7).
It'll also be swell if I ever get around to adding my Docker config to version control. You could customize the development environment to meet your specific needs, while still being able to keep current with the repo.
0 -
Establishing your directory structure
You want to be able to edit code on your host machine, most likely in a repo, and have it be accessible from your web server container. You also probably want to avoid mounting your repo directory in your container to use as your document root, since you're going to end up with a lot of junk in your repo. You don't want to copy all your files over to a new directory and mount them in your container, since constantly manually updating them is going to be a pain.
There's actually a very easy way to keep your code up-to-date in your container, without having to serve your repo, directly. Here's how I do it...
Locally, I have a single directory that houses all of my Git repos. It's basically structured like this:
Git [username A] [repo 1] [repo 2] [username B] [repo 1] [repo 2]I mount that Git directory into my Docker containers
/srv/srcdirectory. My httpd container is configured to serve documents out of/srv/htdocs. That directory is hosted on my machine, mounted into my httpd container. Most of the contents of that directory are relative symbolic links to the contents of/srv/src. There's nothing special about my cache, conf and uploads directories. They're regular directories with regular files inside them. My applications, plugins and themes directories are regular directories with relative symbolic links in them. The rest of the files in my/srv/htdocsdirectory are all relative symbolic links to Vanilla files (e.g. index.php, bootstrap.php). Doing this, I can link a new plug-in to my Vanilla install, very easily. For instance, if I wanted to add the Debug Bar plug-in, I may do so using the following command from the plugins directory under/srv/htdocs:ln -s ../../src/vanilla/internal/plugins/debugbar
It's a bit of manual work to get off the ground, but once you have the structure in place, it's very easy to manage.
0 -
Tricky Dinghy
By default, Dinghy comes with a web proxy enabled. All Docker traffic over port 80 gets funneled through this proxy container and on to its final destination at a HTTPD service container. This proxy doesn't play well with Vanilla. It slows things down and often throws gateway errors. The fix is easy enough: disable the proxy. Edit
~/.dinghy/preferences.yml. Insert or update the proxy_disabled line, under:preferences:, to the following::proxy_disabled: true
0 -
Stack v0.9
Attached is my updated Docker dev stack. It's now something better suited for actually running and developing with Vanilla. The Percona container remains the same, but the nginx and PHP containers have been updated with the following:
- nginx - Updated settings to allow for
PATH_INFOusage/pretty URLs. This new configuration is based largely on infrastructure configuration files, so there's probably a lot of room for optimization in the Docker environment. The default website should be accessible at http://webserver.docker. - PHP - Set the image tag to 5.4, so it should pull the latest available 5.4 release. Included the following extensions: gd, mbstring, mcrypt, pdo, pdo_mysql and xdebug. In order to use Xdebug, you'll need to setup the host mapping for
machinehostto your machine's actual network IP address.
Configuration files have been added for nginx, Percona and PHP to allow customizing service settings.
To work with my device, on my network and with my directory structure, I use the following
docker-compose.override.yml:version: "2" services: fcgi: extra_hosts: - "machinehost:192.168.0.11" volumes: - "/Users/ryan/Git:/srv/src"0 - nginx - Updated settings to allow for
-
PHP Mail
The current version of my Docker stack doesn't include
mailin the PHP container. This will cause Vanilla to reach a fatal error if it attempts to send any e-mails. To get around this, you can disable e-mails in Vanilla.$Configuration['Garden']['Email']['Disabled'] = true;
I may add
mailin at a later time, but if you need it for now, you can update the Dockerfile used for the PHP container. I recommend creating a new Dockerfile from the original, naming it Dockerfile-alternate and usingdocker-compose.override.ymlto use it. For example:version: "2" services: fcgi: dockerfile: Dockerfile-alternate0 -
MySQL Strict Mode and Stack v0.91
Percona 5.7, the latest version of Percona and therefore the version currently being used to build the stack, defaults to a pretty strict
sql_mode:ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
Vanilla doesn't work so well under this strict of an
sql_mode, so I updated the stack to use the following:NO_ENGINE_SUBSTITUTION
0 -
Docker for Mac was released at the end of July. Its greatest improvement (to me, anyway) is the revised implementation of hypervisors. Docker Toolbox, the previous OSX solution, required you to run a tiny VM image inside something like VirtualBox to use Docker Engine. Docker for Mac uses xhyve, a very lightweight alternative, which effectively removes the need for a separate standalone virtualization application (VirtualBox). The result seems to be a much faster experience.
I haven't been using the update for long, but I'm probably going to ditch Dinghy. That was yet another application necessary to squeeze better performance out of Docker on OSX. With the Docker for Mac update, it feels redundant.
1 -
Linc beat me to it
0