Mon Jun 13, 2016
Info on running linux X11 GUI apps on MacOS.
Docker for Mac doesn’t work with sharing the X11 socket. So we need to use socat, which is a command line utility that establishes two bidirectional byte streams and transfers data between them. We use this to allow the X11 traffic to occur between the linux docker host VM, and MacOS.
Installation of Prerequitsites
Kitematic completely automates the Docker installation and setup process and provides an intuitive graphical user interface (GUI) for running Docker containers on the Mac. Kitematic integrates with Docker Machine to provision a VM and install Docker Engine locally on your Mac.
Setting up the container
Execution
NOTE: next step is to add volume for zim notebook directory
NOTE: zim does not handle updates on the host filesystem well. You need to reload zim for changes to be seen.
NOTE: hugo does not have this problem and is able to detect changes as it normally would. (sporadically works and sometimes it doesn’t work)
Oct 9, 2016 - Docker network issue
Ran into an issue in which the container could no longer X display to the host.
Narrowed down the issue to the fact that the container could no longer connect to the Host on port 6000.
This was due to overlapping network ranges from Docker networks with the private RFC1928 network my laptop was on.
The Solution
Clean up your local Docker network definitions to address the possiblity that these RFC1918 ranges might overlap/conflict with the network you’re currently on.
First and foremost, Docker does not clean up network allocations. When you start a new
docker-compose
project, Docker will automatically allocate a new docker network. After you run docker-compose rm -f
the containers are removed, but the network is not touched. This is similar to how Docker images need to be manually removed independently from Docker containers.It seems that some of the networks were allocated by Docker on the RFC1918 172.16.x.x/12 space with /16 blocks, and when the 172.16.x.x/12 ranges were used up (which is fairly easy when allocating with /16 blocks) Docker allocated a new 192.168.2.x/20 network block. This network overlapped with my home network (192.168.1.x/24) - the result: the container could not reach my Host.
List current Docker networks
10/15/2016NOTE: the ipcalc shows the issue is related to overlapping network range - see below. Mystery solved.
Listing out the docker networks
Configuring a network within docker-compose.yml
NOTE: look at compose documentation on info with creating a custom network https://docs.docker.com/compose/networking/#specifying-custom-networkshttps://docs.docker.com/compose/compose-file/#network-configuration-referencehttp://stackoverflow.com/questions/35708873/how-do-you-define-a-network-in-a-version-2-docker-compose-definition-filehttps://www.linux.com/learn/docker-volumes-and-networks-compose
So to avoid this from recurring, you can provide a network definition within your
docker-compose.yml
file with a more limited network scope or one that does not conflict with the network you’re currently on.References
8/1/2016 - a new tutorial http://blog.alexellis.io/linux-desktop-on-mac/
Original post which worked prior to Docker for Mac Beta: http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
From May 21, 2016 - Explanation of why Docker for Mac Beta doesn’t work with sharing X11 socket https://forums.docker.com/t/socket-pipes-in-mounted-volumes-not-working/12861/2There’s no time line for this to be implemented - so the recommendation is to use socat for now.
You need socat, which is a command line based utility that establishes two bidirectional byte streams and transfers data between them, and XQuartz - Apples version of the X server.Reference on socat
NOTE: the reference to tweak the security settings for XQuartz is not needed.
NOTE: the reference to tweak the security settings for XQuartz is not needed.
https://forums.docker.com/t/solved-cant-run-gui-applications-under-security-constraints/13397/4This contains a snippet which can grab your primary host interface IP address and then export the DISPLAY variable to the docker container
Perhaps slightly inspired by this blog by Jessica Frazelle I started putting some of the apps that I like to run on my Mac inside a container. At first I only ‘containerized’ text-based apps, like Weechat, Mutt, fleetctl and Terraform, but more recently I decided to have a go at containerizing some GUI apps.
“Why?!”, you might ask. Well, the only true answer is: “Because. We. Can.” :-)
Things to consider
- Memory: OSX can’t run Docker containers natively. You need to use
docker-machine
which creates a (small!!) VM for you that actually runs your containers. Unless you RTFM and create that VM with a reasonable amount of memory, you’re going to have a bad time when running Chrome and Eclipse in a container. - Graphics: your containers are going to run in a headless VM, so you’re going to need a way to hook up those containers to an X-session over TCP. No easy bind-mounting of the X11 socket.
- 3D: there is no 3D accelleration in your VM. None. Nada.
- Sound: By default, your VM is not going to have support for sound, so unless you’re going to pull some PulseAudio magic, you’re not going to have sound.
If you’re serious about running GUI apps in a container, don’t run OSX. Install Linux, read Jessica’s blog, and have fun. It is a far less problematic experience.
However, if you just want to do it for sh*ts & giggles, let’s fire up some GUI containers on our Macs!
Set up your Mac: install stuff
If you’re not using Homebrew yet, you should be ashamed of yourself (and start using it). We’ll be using Homebrew to install pretty much everything we need.
Cask: Cask extends Homebrew and is aimed at delivering the Homebrew experience for GUI apps and large binaries. To install Cask, run:
Virtualbox: Runs our VM. To install Virtualbox, run:
Docker stuff: We need Docker and Docker Machine, both of which we can get from Homebrew:
XQuartz: XQuartz is an X11 server for OSX. To install it, run:
Update: as it turns out, you need to either start Virtualbox manually once at this point, or reboot your system. If you don’t, you will get some errors in the following steps because Virtualbox isn’t behaving properly.
Set up your Mac: configure stuff
![For For](/uploads/1/2/5/6/125647917/678846779.png)
Now that we’ve installed everything, let’s configure our Mac.
Docker Machine: we need to create a Docker Machine VM and configure our shell to use it. First, create our Docker VM and configure it to have a bit more memory (default is 1GB):
To actually use the VM we need to start it, and configure our shell:
![Docker For Mac Gui Apps Docker For Mac Gui Apps](http://chen54.b0.upaiyun.com/1127/c10d_bg.jpg)
Test if everything works:
XQuartz: we need to configure XQuartz to listen on a TCP port (so we can connect to it from our Docker VM), and we don’t want XQuartz to open XTerm every time we start it, so let’s fix that too:
At this point, the Docker VM still isn’t allowed to connect to the XQuartz server, but since we don’t want to disable security we need to allow it explicitly each time XQuartz runs. This is actually not as cumbersome as it sounds.
Running apps!
Basically, to make the GUI apps work, you would need to do a couple of things, in order:
- Run your Docker VM
- Set up your shell for the Docker VM
- Start XQuartz
- Set your
$DISPLAY
environment variable - Allow XQuartz connectivity for the Docker VM
- Run your app container with the right settings
OK, that’s a lot of manual stuff to run one app. Fortunately we have a shell config file we can abuse to make life easier.
First, we’re going to create a few shell functions for managing Docker Machine and Xquartz. You can add these to your
~/.bash_profile
:Now that we’ve made life easier, let’s fire up Eclipse! Again, we can do this manually, or we can create a shell function for each app so it runs the appropriate container in the appropriate way.
The function above checks if XQuartz is running (and configured properly) and starts it if necessary. Then it checks if my Docker VM is running, and starts it if necessary. Then it allows the Docker VM to connect to the XQuartz server, and runs the
fgrehm/eclipse:4.4.1
container with a 512MB memory restriction and the correct $DISPLAY
setting so it uses our XQuartz server to display the window. To persist settings and code, volume mappings are added to ${HOME}/Documents/eclipse
.Let’s do something similar for Chrome:
Chrome needs some extra settings for the networks and for sandboxing to work properly, but the result is the same.
Of course, if you actually want to persist your Chrome settings or downloaded files, you need to add some volume mappings so data is actually persisted on your filesystem. And like I said before, sound will not work. So even though you can watch some Youtube in your containerized Chrome, it will be dead silent.
Wrapping up
So now you know how to run a GUI app, in a Docker container, on your Mac. Great! Except that you don’t have 3D, you don’t have sound, and you need to create a bunch of shell functions. So why would you actually want to do this? Well, for some apps, that don’t need sound or 3D, it might actually be useful. For instance, you don’t need to actually install Eclipse (or Java) on your Mac. And it gives you a nice opportunity to play around with Docker and discover some of the stranger aspects of putting stuff in a container. And maybe, after a while, it will make you decide to switch from OSX to Linux and go with some super lightweight Linux distro (nerd creds are upon you!) and you end up being that guy or girl who can set up their Linux system in 10 minutes with a minimal graphical install, clone your ‘dotfiles’ Git repository and instantly have access to all the GUI apps you need.