- Ref [1]: https://cntnr.io/running-guis-with-docker-on-mac-os-x-a14df6a76efc
- Ref [2]: http://fabiorehm.com/blog/2014/09/11/running-gui-apps-with-docker/
Docker is a set of platform as a service products that use OS-level virtualization to deliver software in packages called containers.
Basically, Docker container is a slim version of a virtual machine. With docker, we can run application that can not usually run on Mac.
Since compiling p4vasp on Mac has gradually became a pain in the a** and apple has decided to go ARM. I decided that using docker container is probably easier to both run and manage it.
If you use homebrew, simply use command:
brew cask instsall docker
Alternatively, you can install it manually, check out Docker's official guide HERE.
An Docker image is similar to a system image but simpler. To build an image, you need a file called Dockerfile
#!/bin/bash
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y p4vasp
RUN export uid=501 gid=20
RUN mkdir -p /home/developer
RUN echo "developer:x:${uid}:${gid}:Developer,,,:/home/developer:/bin/bash" >> /etc/passwd
RUN echo "developer:x:${uid}:" >> /etc/group
RUN echo "developer ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
RUN chmod 0440 /etc/sudoers
RUN chown ${uid}:${gid} -R /home/developer
USER developer
ENV HOME /home/developer
ENTRYPOINT ["/usr/bin/p4v"]
To build the p4vasp image, type in the following command in the directory of Dockerfile
.
docker build --rm -t p4vasp .
Now, we have created a Docker image called p4vasp
and it's ready to go!
Since p4vasp is a GUI application, we need means to access its GUI. To do so, we need to create a tunnel between our p4vasp container and our host machine. [1]
To do that, we need to install socat
pakcage:
brew install socat
and run it as:
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
Note that this command will continue to run in your terminal since you instructed it to listen on port 6000. It will continue to do so until you kill it.
To run p4vasp, type the following in your command line:
docker run -e DISPLAY=host.docker.internal:0 --volume=$(pwd)":/root/data:rw" -w "/root/data/" --name="p4v_tmp" p4vasp```
Now let's break this command down and see what it does:
-e DISPLAY
gives our Docker container access to your monitor.--volume
gives our Docker container access to our current working directory.-w
sets the working director to/root/data
name
gives our container a namep4vasp
the name of our Docker image.
Running the docker image requires us to firstly open a terminal and use socat
command, then open another window to run docker container which is kind of redundant. To make it easier, save the following commands as a script p4v.sh
and give it 755
privilege.
#!/bin/bash
kill -9 $(lsof -n -i | grep 6000 | head -1 | awk '{print $2}') > /dev/null 2>&1
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" &
docker run -e DISPLAY=host.docker.internal:0 --volume=$(pwd)":/root/data:rw" -w "/root/data/" --name="p4v_tmp" p4vasp $1
kill -9 $(ps | grep "socat" | awk '{ print $1 }')
docker rm p4v_tmp > /dev/null 2>&1
Now you can run this script anywhere you want with simply one command:
p4v.sh vasprun.xml
Neat!