Do You Have Problems With Docker For Mac
If you already have Docker Toolbox, and then you install Docker for Mac, you may get a newer version of the Docker client. Running docker version in a command shell displays the version of the client and server you have on your system. This may also happen if you use Docker Universal Control Plane (UCP). So you finally surrendered to containers and discovered that they solve a lot of problems and have a lot of advantages. First: Containers are immutable – The OS, library versions, configurations, folders, and application are all wrapped inside the container. You guarantee that the same image that was tested in QA will reach the production environment with the same behaviour.
Previously in order to run Linux containers on a Mac, you needed to install VirtualBox and have an embedded Linux virtual machine that would run the Docker containers from the Mac CLI. There would be a network endpoint on your Mac that pointed at the Linux VM, and the two worlds are quite separate.
Docker for Mac is a native MacOS X application that embeds a hypervisor (based on xhyve), a Linux distribution and filesystem and network sharing that is much more Mac native. You just drag-and-drop the Mac application to /Applications, run it, and the Docker CLI just works. The filesystem sharing maps OSX volumes seamlessly into the Linux container and remaps MacOS X UIDs into Linux ones (no more permissions problems), and the networking publishes ports to either `docker.local` or `localhost` depending on the configuration.
A lot of this only became possible in recent versions of OSX thanks to the Hypervisor.framework that has been bundled, and the hard work of mist64 who released xhyve (in turn based on bhyve in FreeBSD) that uses it. Most of the processes do not need root access and run as the user. We've also used some unikernel libaries from MirageOS to provide the filesystem and networking 'semantic translation' layers between OSX and Linux. Inside the application is also the latest greatest Docker engine, and autoupdates to make it easy to keep uptodate.
Although the app only runs Linux containers at present, the Docker engine is gaining support for non-Linux containers, so expect to see updates in this space. This first beta release aims to make the use of Linux containers as happy as possible on Windows and MacOS X, so please reports any bugs or feedback to us so we can sort that out first though :)
A couple of years ago, Will Pleasant-Ryan wrote Docker for Mac: Overcoming Slow Mounted Volumes, describing his desire to use Docker for local development. He talked about some of the filesystem performance problems that can arise when using a shared volume from the host machine on Mac OS X, along with some potential workarounds and word of some upcoming performance improvements.
In the time since that post was written, those improvements have been released. But I’ve still found it to be unacceptably slow to have the source code mounted from the host machine, at least for something like a Ruby on Rails application.
However, earlier this summer, a Visual Studio Code update introduced the ability to “attach to a running container.” Once attached, the experience when editing files that reside on a container using VS Code is nearly indistinguishable from that of editing files on the local filesystem with VS Code!
1. Docker Compose
I’m using Docker Compose to manage the containers that make up my development environment. There’s plenty of existing documentation on how to use Docker Compose, but I want to point out a couple of things that I’ve done because I’m using a container to host the source code I’m editing.
A named volume for source code
If you just checked out a repository into a normal directory inside the container, you’d have to be careful not to lose any changes that had not been committed and pushed whenever making changes to container (updating something in the Dockerfile
, etc.). But if the source code is checked out into a named volume, the container can be re-built over and over again, with your source code being mounted exactly as it was before.
A long-running container
Similar to a database container, your “dev” container should stay running when you do a docker-compose up
so you can attach to it from VS Code. With Docker Compose, you just need to set the tty
option to true
in your docker-compose.yml
.
Here’s an example docker-compose.yml
file that has a couple of named volumes, one for the source code directory and the other for the contents of the database. I’m using this for an old Ruby on Rails project, hence the old version of MySQL.
2. Working in the Dev Container
The idea is that any developer could check out the repository on their laptop, run docker-compose up
, and have a working development environment. But you’ll still need a little customization of the container once it’s been built.
Check out the source code
Once you have your container up and running (docker-compose up
), you’ll need to check out your source code inside the container. You can’t do this as part of the Dockerfile
because we want the repository to live in the mounted volume.
If you rely on your SSH keys to authenticate with your Git server, then you’ll want to either mount your ~/.ssh
Autodesk revit architecture 2017 download. directory in the container or copy your private key into the container manually. I needed to do the latter because my ~/.ssh/config
has some things that aren’t compatible with the Ubuntu version running in the container.
These examples assume the container will be run as a user called “dev.”
I also like to have my normal Git configuration available as well:
Now you just check out your source code, but inside the container instead of on your host machine.
At this point, you can open a shell in the container and run tests, start the development server, etc.
3. Editing in VS Code
With the “dev” container running, inside of Visual Studio Code, run the “Remote-Containers: Attach to Running Container” command and select your “dev” container. VS Code will attach and install everything it needs to run on the container.
If you select the File Explorer, you’ll see an “Open Folder” button that, when clicked, will display folders on the container. Select the location of the source code that was checked out previously, and click OK. You’ll now be able to edit files as if they were hosted on the local filesystem.
You can even open an integrated terminal in VS Code, and it will automatically open a shell in the attached container!
Conclusion
I’ve only recently started playing with hosting my entire development environment, including the source code, inside Docker containers, but the experience using VS Code as an editor has been fantastic.
With the Mac OS X filesystem integration performance improvements that have been made, many projects will be just fine using shared volumes mounted from the host system. But in cases where that just won’t cut it, hosting the source in the container and using VS Code to attach to the container is a really, really nice solution.