{"id":221873,"date":"2021-04-08T15:00:11","date_gmt":"2021-04-08T12:00:11","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-run-gui-applications-in-a-docker-container-cloudsavvy-it\/"},"modified":"2021-04-08T15:00:11","modified_gmt":"2021-04-08T12:00:11","slug":"how-to-run-gui-applications-in-a-docker-container-cloudsavvy-it","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-run-gui-applications-in-a-docker-container-cloudsavvy-it\/","title":{"rendered":"#How to Run GUI Applications in a Docker Container \u2013 CloudSavvy IT"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a3c57492a9d2\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a3c57492a9d2\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-run-gui-applications-in-a-docker-container-cloudsavvy-it\/#Why_Run_GUI_Apps_in_Docker\" >Why Run GUI Apps in Docker?<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-run-gui-applications-in-a-docker-container-cloudsavvy-it\/#Forwarding_An_X_Socket_to_A_Docker_Container\" >Forwarding An X Socket to A Docker Container<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-run-gui-applications-in-a-docker-container-cloudsavvy-it\/#Handling_X_Authentication\" >Handling X Authentication<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-run-gui-applications-in-a-docker-container-cloudsavvy-it\/#Another_Approach_%E2%80%93_Running_a_VNC_Server\" >Another Approach \u2013 Running a VNC Server<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-run-gui-applications-in-a-docker-container-cloudsavvy-it\/#Conclusion\" >Conclusion<\/a><\/li><\/ul><\/nav><\/div>\n<p><strong>&#8220;#How to Run GUI <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">App<\/a>lications in a Docker Container \u2013 CloudSavvy IT&#8221;<\/strong><\/p>\n<div id=\"article-content-area\">\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-9034\" data-pagespeed-lazy-src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg?width=1200&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"1602\" height=\"902\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Docker\u2019s normally used to containerise background applications and CLI programs. You can also use it to run graphical programs though! You can either use an existing X Server, where the host machine is already running a graphical environment, or you can run a VNC server within the container.<\/p>\n<p>First it\u2019s important to understand what Docker actually does. A Docker \u201ccontainer\u201d is a form of encapsulation which seems to be superficially similar to a virtual machine. Unlike a virtual machine, containers share the same Linux kernel as their host system.<\/p>\n<p>The next component is the X Window System. X Servers such as Xorg provide the fundamental graphical capabilities of Unix systems. GUI applications can\u2019t render without an X Server available. (Alternative windowing systems, such as Wayland, are available \u2013 we\u2019re focusing on X in this article.)<\/p>\n<p>Trying to run an X Server in Docker is theoretically possible but rarely used. You\u2019d need to run Docker in privileged mode (<code>--privileged<\/code>) so it could access your host\u2019s hardware. Starting the server would try to claim your video devices, usually resulting in loss of video output as your host\u2019s original X server gets its devices yanked away.<\/p>\n<p>A better approach is to mount your host\u2019s X Server socket into the Docker container. This allows your container to use the X Server you already have. GUI applications running in the container would then appear on your existing desktop.<\/p>\n<h2 id=\"why-run-gui-apps-in-docker\"><span class=\"ez-toc-section\" id=\"Why_Run_GUI_Apps_in_Docker\"><\/span>Why Run GUI Apps in Docker?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Running a GUI program in Docker can be a useful technique when you\u2019re evaluating a new piece of software. You can install the software in a clean container, instead of having to pollute your host with new packages.<\/p>\n<p>This approach also helps you avoid any incompatibilities with other packages in your environment. If you need to temporarily run two versions of a program, you can use Docker to avoid having to remove and reinstall the software on your host.<\/p>\n<h2 id=\"forwarding-an-x-socket-to-a-docker-container\"><span class=\"ez-toc-section\" id=\"Forwarding_An_X_Socket_to_A_Docker_Container\"><\/span>Forwarding An X Socket to A Docker Container<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Providing a Docker container with access to your host\u2019s X socket is a straightforward procedure. The X socket can be found in <code>\/tmp\/.X11-unix<\/code> on your host. The contents of this directory should be mounted into a Docker volume assigned to the container. You\u2019ll need to use the <code>host<\/code> networking mode for this to work.<\/p>\n<p>You must also provide the container with a <code>DISPLAY<\/code> environment variable. This instructs X clients \u2013 your graphical programs \u2013 which X server to connect to. Set <code>DISPLAY<\/code> in the container to the value of <code>$DISPLAY<\/code> on your host.<\/p>\n<p>You can encapsulate all this configuration in one <code>docker-compose.yml<\/code> file:<\/p>\n<pre class=\"yml\"><code>version: \"3\"&#13;\n&#13;\nservices:&#13;\n  app:&#13;\n    image: my-app:latest&#13;\n    build: .&#13;\n    environment:&#13;\n      - DISPLAY=${DISPLAY}&#13;\n    volumes:&#13;\n      - \/tmp\/.X11-unix:\/tmp\/.X11-unix&#13;\n    network_mode: host<\/code><\/pre>\n<p>Next, you need to create a <code>Dockerfile<\/code> for your application. Here\u2019s an example that runs the Firefox web browser:<\/p>\n<pre class=\"dockerfile\"><code>FROM ubuntu:latest&#13;\nRUN apt-get update &amp;&amp; apt-get install -y firefox&#13;\nCMD [\"\/usr\/bin\/firefox\"]<\/code><\/pre>\n<p>Now build and run the image:<\/p>\n<pre><code>docker-compose build&#13;\ndocker-compose up<\/code><\/pre>\n<p>A new Firefox window should appear on your desktop! The Firefox instance will run within the container, independently of any other open Firefox windows. The container will share your host\u2019s X socket, so the containerised Firefox still shows up on your desktop.<\/p>\n<p>This approach should only be used when you trust your Docker container. Exposing the host\u2019s display server is a security risk if you\u2019re not completely sure what lies inside the container.<\/p>\n<h2 id=\"handling-x-authentication\"><span class=\"ez-toc-section\" id=\"Handling_X_Authentication\"><\/span>Handling X Authentication<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You might need to authenticate the container to access the X Server. First get an X authentication token from your host machine. Run <code>xauth list<\/code> and note down one of the listed cookies. You\u2019ll need to copy the entire line.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10524\" data-pagespeed-lazy-src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/04\/4a47a0db.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"956\" height=\"222\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Inside the Docker container, install the <code>xauth<\/code> package. Then run <code>xauth add<\/code>, passing the token you copied in the previous step.<\/p>\n<pre><code>apt install -y xauth&#13;\nxauth add &lt;token&gt;<\/code><\/pre>\n<p>Your container should now successfully authenticate to the X Server.<\/p>\n<h2 id=\"another-approach---running-a-vnc-server\"><span class=\"ez-toc-section\" id=\"Another_Approach_%E2%80%93_Running_a_VNC_Server\"><\/span>Another Approach \u2013 Running a VNC Server<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>If you\u2019re unable to use X socket forwarding, you could setup a VNC server inside your container. This approach lets you view graphical apps in the container by connecting from a VNC client running on the host.<\/p>\n<p>Add the VNC server software to your container:<\/p>\n<pre><code>FROM ubuntu:latest&#13;\nRUN apt-get update &amp;&amp; apt-get install -y firefox x11vnc xvfb&#13;\nRUN echo \"exec firefox\" &gt; ~\/.xinitrc &amp;&amp; chmod +x ~\/.xinitrc&#13;\nCMD [\"v11vnc\", \"-create\", \"-forever\"]<\/code><\/pre>\n<p>When you run this container, a VNC server will be created automatically. You must bind a host port to the container\u2019s port 5900 \u2013 this is the port the VNC server will be exposed on.<\/p>\n<p>Firefox gets launched on startup as it\u2019s added to <code>.xinitrc<\/code>. This file will be executed when the VNC server launches and initialises a new display.<\/p>\n<p>To connect to the server, you\u2019ll need a VNC client on your host. Find the IP address of your container by running <code>docker ps<\/code>, noting down the container ID and passing it to <code>docker inspect &lt;container&gt;<\/code>. You\u2019ll find the IP address near the bottom of the output, within the <code>Network<\/code> node.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-10523\" data-pagespeed-lazy-src=\"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/04\/fb5c81ed.png?trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"\" width=\"956\" height=\"402\" src=\"\/pagespeed_static\/1.JiBnMqyl6S.gif\" onload=\"pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\" onerror=\"this.onerror=null;pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon(this);\"\/><\/p>\n<p>Use the container\u2019s IP address with your VNC client. Connect on port 5900 without authentication. You should now be able to interact with the graphical programs running within your Docker container.<\/p>\n<h2 id=\"conclusion\"><span class=\"ez-toc-section\" id=\"Conclusion\"><\/span>Conclusion<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You have the choice of two approaches when running graphical programs within a containerised environment. For <a href=\"https:\/\/buradabiliyorum.com\/en\/category\/general\/\" data-internallinksmanager029f6b8e52c=\"3\" title=\"General\" target=\"_blank\" rel=\"noopener\">general<\/a> use, sharing the host\u2019s X socket usually provides the simplest solution. You may also choose to run a VNC server within the container. This approach can be safer when you didn\u2019t create the container image.<\/p>\n<p>Containerised graphical apps are useful when you\u2019re evaluating software or need to run two versions of a package. You can use programs on your existing desktop without needing to touch your host\u2019s configuration.\n<\/p><\/div>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.cloudsavvyit.com\/10520\/how-to-run-gui-applications-in-a-docker-container\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;#How to Run GUI Applications in a Docker Container \u2013 CloudSavvy IT&#8221; Docker\u2019s normally used to containerise background applications and CLI programs. You can also use it to run graphical programs though! You can either use an existing X Server, where the host machine is already running a graphical environment, or you can run a&#8230;<\/p>\n","protected":false},"author":1,"featured_media":221874,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.cloudsavvyit.com\/p\/uploads\/2021\/01\/6dc7b5a0.jpeg","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-221873","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/221873","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=221873"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/221873\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/221874"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=221873"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=221873"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=221873"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}