Delivering Desktop Apps in Containers
Hi everyone and welcome to delivering, desktop. Apps with, docker, containers, I'm pretty excited about doing this particular, session. On this particular topic it's a little bit more esoteric than what you might expect from a typical docker, talk on using. Containers which, are typically related to things like web apps and things, that you can put in a container that are what we call headless, but, this one is going to use a particular use case that I have found to be an interesting, use case and might have some implications on modernizing. Old. Apps that you might have sitting around in your data center somewhere and you've got to figure out how that you're gonna put. Those on to new and modern platforms, such as things that you might go into the cloud a little, bit about me I'm blaze Stewart i'm architect. At winter, black i'm also an azure MVP. And i specialized, a lot in modular. Infrastructure, as well as docker. Containers, on adders, my niche is really kind of the intersection, of containers. And Microsoft, Azure and I really do spend a lot of time and dusting, in all, the technologies, on Azure that do run containers, but I'm also a little bit broader than that and actually do development and infrastructure, as well, enough. About me let's get, right into what we're here for which is the, talk. That we're going to be looking at how to use containers, to deliver desktop. Applications. Now. One of the main, reasons that we like to use containers, is for application, consistency, and application. Delivery so application, consistency what we're talking about there is figure out a way to consistently. Deliver apps, across. Any number of different infrastructure. That could be docker swarm docker on. My desktop it could be kubernetes, on the cloud kubernetes, on premise regardless. Of what infrastructure, I deploy that app on to it's gonna run the same because, it's running in a container because all the dependencies, and everything is packaged in that containers, and then there is the possibility of using that for desktop, apps as well where I can package everything I need to run an application, including. All the frameworks I have for my desktop app and deploy that in a container and also, with application, delivery what we're trying to do here is figure out a way to get applications onto desktops. Or into, the cloud regardless, of which way I choose to do that for, not, only headless apps but, GUI based applications. And that we're really gonna be looking at today is how I can deliver these applications, in a consistent way that, I could use, for my desktop, applications, and I'm going to show you a couple different methods.
That You could use to employee, application, consistent. Application. Delivery using. Desktop. Applications, on most Linux systems you need something called a Windows, server to, render, the display, for. A given, application so, I have something called X server which is a Windows server that can interact with applications in, most cases X is the case for the. Window manager on most, given. Linux based systems, and the. Application will interact with that X server writing, and reading, input, from it X, is then responsible for receiving input, from your peripherals, things like your mouse and your keyboard and, it, sends that information back, to your application, and then the application will, send, some kind of out but typically, in the form of a graphical, user interface. And then, X receives that and then it writes it to some kind of display which, could be in a local context, monitor, but, it's not always the case that it's a local, display it can be a remote display so. Over the container what I can do then is wrap up my application, inside. Of a container, and then I can use something like TCP, to, relay, that information from. My application to a remote, X server and then, have that remote X server display, it on a remote display so. In a demo I'm going to do here in just a minute we're going to set up an X server on Windows and, then I'm going to use a Linux based app inside. The container to relay that information back, to and X Server on Windows and then I'm going to use my keyboard mouse and monitor on, Windows, to display that application, so it's going to feel more like a native Windows application, however it's actually going to be running, in a Linux space container, on another. System which in this case would be a virtual, machine created, by docker, desktop. For. This demo I'm gonna start with this docker file and it's an a bunch of based image, that, I'm using a couple of object commands in this run command here to install, a B word which is a word, processor, and I can start having word with, the simple command a B word and that will launch this word processor, so, I chose, this app because it's very easy to install on a bun too and it makes perfect clean docker file too and I, can use this for this demo so I need, an X server to, communicate, with though because this is an installing, an X server I need, that X over to be available so I'm going to start the next server down here in, my windows, host, and to.
Do That I'm gonna launch, VC xserve which is a project, on SourceForge that you can go out and download and install it just like any other windows application, it's pre built binary you, don't have to compile it and I'm, gonna use x launch here and, I'm going to walk through this wizard and basically take the defaults in the first two screens use multiple windows start. A new client, and then I'm going to check, this box disable, access control because I'm running in a local context if I was running this in a network. I didn't trust I'd probably want to enable, that and then. Setup my container, to use secure connections, but for this local context this should be fine and then I'm gonna click Next and then click finish and, then, that's going to start my X server which is down here my tool tray now now. With this particular docker file I can then, launch a command prompt, to build it so simply run docker build. And. Tag. The image happy, word and then. Use the local docker file it's using cached images here. So I don't have to sit here and wait for it to build but. Then I can use docker, run and I'm, going to specify a few options. On the docker run command so that it makes it more, realistic, so, first, of all I'm gonna use as a volume, so I'm gonna basically mount, my C Drive into. This container so that I can access the files inside. Of this word processor, that will be written to my hosts. File system here so, to put that I'm just, going to use C, dash Drive and the root of my container, and then. I'm going to specify an environmental, variable now I need to do this so that my application, knows, where to write, the, actual output to, whatever. Server I'm doing so in this case I'm going to use the TCP, be a base output, that, is supported, by most, X servers and I'm. Going to specify my IP address for this particular virtual machine now, the thing. After the colon is the index of the display, server which in my case is, 0. So I'm going to use the first available. X. Server I can actually run multiple X servers in this context, if I wanted to but I'm gonna use this, this, one right here which is the only one I have running and then, I need to specify the image which, is a B word and that. Should be everything I need to actually, launch this application and, so, if this right works, we'll see it to start my application here, which looks like a more, or less a native Windows application, now because, this is something I can maximize minimize, move, around and. Because the X server is being managed by Windows and, now if I wanted to open up a file for instance I can then browse out to my C Drive which is mounted here come, down here to my users Blaze and.
Maybe I had something in my documents, there's, there's a file. Here that I used, in another demo is doing with the same takwa file and I can save that you know and save it out and, where I can and save. As or something like that and. Save. It as this one sure override, it and. Then, I can exit this application. I can quit and then it's going to exit my container, so, it's, actually waiting for a B word to exit, and so my container terminates, and it's no longer running so this, is a very basic demo, of how you can set up a, application. Like a B word to run on a remote next server which, is very very. Convenient for running a lot of Linux apps inside, of a docker, context. There's. Another possible, architecture, that you can use for this and it looks something like this where you have a application. That is running in some, kind of context, and it's communicating, with a local, X server so this local exer is running on the same post as your application and then, the output, and input for, that X server is encapsulated. In some kind of network protocol and a, remote client, attaches, to it in the previous example, we looked at how you can have a remote X server which is actually simpler, to set up because. To, get a remote X server, setup you simply just install that you point your output, to that remote X server in this case we're actually involving, another, application, or, another kind of client, that connects to the output from the next server and that client. Then is actually. Taking the output from your peripherals, or your. The output from, the actual application. And putting it on to a local display and, this, is the, approach that things, like B and C take or expert, take extra, as a project, that is designed. To do this very same thing and BNC, has been doing this for years as well and in this case the, boundaries of our container would be around, the actual X server and the application, so in this case we, would actually containerize.
X As well, as the, application, and then, we would use some kind of remote, client, to connect to that but, what, I can do with a application. That's set up in this fashion is once this starts it does take a little bit to start because it's bootstrapping, all, of the actual. Components to run the X server and then, once it's actually up and running I should, be able to launch a browser and, then. Pulled this up so this would be running on my local host on a, port 10000, so if I go to localhost, colon. 8080. This. Is going to start X bruh and then, there's a B word running on extra, inside of a browser context, now and this. Is a nice little window. Base X, system, that they created for extra, that, that works fairly well, it. Can't get laggy at times I'm not gonna say it's perfect, but it is it's, certainly usable, for most the time and I'm going to show you a demo in a minute how you can accelerate this if, you need some better performing, applications, but it doesn't have a nice window chrome and the ability to drag and drop windows. Inside, of a browser context, and this. One I can then browse you can see there it's timing, out so that's because the, actual. Container the, protocol is is trying to adjust, based. On the demands of what I'm actually trying to do here and so this is a little laggy for most. For some application, so it's not my preferred way to do this but. It, is functional even. If it, is trying. To reconnect to it and, sometimes you end up giving those kinds, of, warnings. And I. Can open up files just like I did before, where. I have, my. Documents. Full, here, and at. A document, right inside of our browser now and this. Particular one will, should open up my, file. Here and there it is so it is a little slower than what I would hope it to be but expert. Does work and it's simple to use I want to show you another approach, to what we just saw with extra, and extra. Is an all-in-one package so it does basically everything, for you and all, you need to do is set it up this, approach uses B, and C to do basically, the same thing but it's more piecemealed and that it uses a bunch of different projects, to ultimately render, the actual, application, in a browser and, this. One is a lot more performant, though because I can take advantage of things like OpenGL and, the animation, ends up being a lot more smoother, in the browser than.
It Was with ex-brother I don't get the kind of lag that I get with extra. So, this stack looks like this and I'm going to show you this stack because it is not, exactly clear when you when, you see the docker file so, basically, it starts with at the app and that could be any, application. That is a GUI based application, in Linux and then, on top of that you have something called a window, manager which. In the context of the x-ray demo. That we saw that was the window chrome and in, this case I'm gonna be using a window manager called rat poison, which is actually designed for a, keyboard, based window, manager that allows me to use keyboard commands the maximize minimize move, around windows and things like that and, so it's very bare-bones, and very minimal so it's very lightweight, and which is more, ideal for containers, and then, the rat poison along with the app interact, with the act server and the, X server is what, export, was providing for you when we seen xx, server outside the container already. As well and then was I have the X Server, external. As installed. What along with rat poison in my app I can actually write. The output from, my X server to something called a virtual frame buffer which is essentially, like a virtual. Video card, so it has a virtual, memory that it uses to be. The output for, the actual graphics. That get written. By the, X server and the compositor, and all of those things that are below in the stack and. Then what, I can do then is take the output, from the X server and read, that output to actually. Have a VNC, server, look. At that and encapsulate, it into, some kind of network, protocol in this case it would be the dnc protocol, which is used very widely in the the Linux context, for connecting. To remote. Desktops, and then, getting access, to remote ads over networks, in the Linux context it works on Windows and mennick as well but, once I have turbo VNC I can't, natively, run a VNC, client in, a browser so I need to wrap. That with something and that's where the next piece comes in which, is something, called with Sox if I which did basically can take any kind of TCP stream. And then, wrap, it up in a WebSocket, which, then can be used to, serve up to, a browser, application. Which, then can be consumed, by some kind of, html5. Client which, in this case is going. To be a product, called no, VNC which. Is an html5 VNC. Implementation. That, doesn't, require that I have any, kind of happen. Stalled I can actually use VNC you right inside, of my browser so, this fact is actually what, you have to install to get an application to, render in the browser using VNC now. This is actually much more performant, that's why I went to the process, and the painstaking effort, of actually making all this work and I think you'll see the difference when I actually containerized an application using this one in another demo now. Here's, the docker file for the stack. That we just looked at and the reason we looked at the stack so that, you didn't have to parse that all out by just looking at this docker file again, it's a bun to base docker, file it's. Got, some parameters, here that I'm setting that are used by the docker files and, this is some that are used to automate the deployment, of deb packages, with, the, actual app gets and the deep deep EEG, installer.
Here And now, what this is actually doing is again, using a heavy word right, here, but it's installing, all the third-party repositories. It's setting up things like rat poison, Novi see web sock safai and then, some OpenGL. Support. Libraries, down there here, it's doing some configuration. Here. It's installing OpenGL here Salling turbo V and C which it's used by so. I can get that acceleration, and get some better compression. Using. Turbo V and C and for the protocol and then. It's configuring. Rat poison, right here. To. Actually do some of the things. That I need to have. This thing set up so whenever I launch rat poison it actually launches, my application, a B word and then. Down, here it's creating a certificate, which I'm really not using in this case and. Then down here it, sets the command to, start B and C turbo. B and C and then it calls whips ox if I, to. Wrap around a, folder, for no V and C which is the html5 client, to access this and then. It's. Using port 80 and, then it's exposing. Localhost. 5901, which. Is the port, for the actual. VNC. Server so web, sock supply is wrapping around that, so that it can actually display that in a browser and. Then use the VNC client inside, the browser so this, is much. More involved docker, file so, let's go ahead and build this guy and, then. Run it and I'll show you why this one, is much more performant, when we see it in action so. Let's go ahead and run this one and do a darker build on it it's probably already cached. Inside. Of my local. Images here and I'm, going to call this one V and C and then use the local docker file and it's, already cached so, let's do a docker, run, let's do our dash V here and, do C colon backslash. Again. Put that at slash, C, Drive and the root and, then. Call, my. I'm. Gonna do a port here so I need to do another port forward here let's, do this one 80 81. But the port I'm exposing in this case is port 80 and then. I need to specify the image which. In this case is V and C and that. Should run my actual, VNC. Demo here and this, is going to start all of the things. I need for, my, actual, app to be running inside of this, container using VNC and all this other stack that we looked at here so, I can come over here launch, up and open, a new tab and. This. Case go to localhost. 881. And. This. Is going to pull up a list of files I'm, gonna click on VNC here and then. I'm going to make sure that my port and my host. Name match what is up here my browser and then, I'm going to type in password, 1. Let's make sure that that is the right password, password. 1 right, there and then I'm going to connect to this and this is again, using, a B word and now this one doesn't have the ability to move the window around or resize it but this one does perform, a lot better I'm not getting any kind of lag on this, my. Menus are much more responsive, I can, go and browse this the animations, much smoother, there's. A lot of advantages to doing it this way because.
The. Performance is just a world, of difference here I'm not seeing any kind of lag on this at all that. I was getting with the other approach, now, I want to show another demo, that's that, I've used this very similar docker file but this one I'm actually going to use Chrome inside. Of a container and I'm going to show you how that works I'm not going to show you all the gluten integrity details but it will give you some animation, on the. Chrome, browser that. Will show you that it's actually using OpenGL to render that. So, here is the dockerfile for Google, Chrome it's basically the same one that I had before but instead of installing, a B word I'm actually installing. Google. Chrome here, to do the actual. So. Here's the docker file for Google Chrome it looks a lot like the one we just looked at the main difference is that this one is installing, Google Chrome instead, of installing, a B word so I'm doing some additional steps. To get the repository. For Google and, then the. So. Here's the docker file for chrome and this one is a little, bit different than the one we saw just a minute ago but basically the same flow this, one I'm actually downloading. From, and then installing, it here. Using, up getting commands and then I and, then configuring. This particular. Container. To use. Google Chrome here in a node 10 box move because I'm running as root I publish it and do that I mean that we're world application, I'll probably want to run something that, is more secure but in this case I'm running it as root and then I'm doing the, actual, launch just, like I did before everything. Is pretty much identical in, this, particular docker file as the one we saw with a B word the main difference is this one is running from-- so, again, i can build this one asko docker, clean. Run docker build, and. Do. Dash T and this call it Chrome and then you run this one it's gonna use all cache because I just built this and then, I can then run this using, docker run just, like I did before in, this case the -, port forward, -. People report forward and then I'm gonna put it on 8080 - to, port 80 I'm, not gonna use a buy, any, kind of volume, on this one I don't really need that because this is just an internet browser I guess if I wanted to say. Things like favorites and that kind of thing or history I could do that but I'm not going to in this case and let's, just call it Chrome and this, is going to start the Chrome on port 8080 - and.
Then, I can launch a new tab here my browser and connect. To this localhost, so. 8080. - VNC. Let's just skip right to the actual. Page and then I can type in the password right. Here and connect. And this is the launch, screen for, Chrome so it's gonna ask me a make, forum your default browser etc. Click, OK here and this, is going to take me to the actual page here. Notice this animation, on this home page is pretty. Smooth and that's because, it's, to take advantage of some of the OpenGL, rendering that, is provided, by way of chrome and using. CSS, animation, to do that so I can pretty much go to any website. That I want to go to and, it's going to pull up further quickly, as well. So again here is a animation. That is using, CSS, ng OpenGL, to accelerate, it and it feels almost native, the speed not quite but this pretty close for, running a desktop application stream. Back to a browser. There. Are two caveats I would like to point out - this is for Linux only, based. Implementations. Windows containers, do not have the support for UI, based applications, in Windows containers, and there, were some early attempts at this but most of them were hackish and today, they don't really work in the newer versions, the second one I would make is this really isn't going, to be useful for, GPU. Intense, applications, that have graphical, outputs now you can use GPUs, in containers, for things like AI big. Data for video, ordering and those kinds of things but you, need you really need a way to capture the output and for display, and you. Can mount a GPU into a container. And take advantage of it for GPU workloads, but, you really need to be able to capture that display, output, and then stream it to something that can actually display it like a monitor, and that, doing, that all in a container would probably, take, you outside of, the context, really what a container would be useful for this is really more oriented, towards line-of-business, applications that's. Someone, which, will take advantage of OpenGL or GPU acceleration, and those generally, will work okay as we've seen with chrome. Demo but. There is the question of old windows apps they're not they're not out, of the question there, are ways to make whole windows apps work on Linux and therefore. Make them work in Linux containers, and some examples might be like bb6 WinForms java gtk, old browsers, like IE five six and seven or, even flash based applications. And you. Can use some, kind of either. Porting. The code to a new framework or wrapping. It up in something like wine so some possible approaches would, be to migrate, something like a WinForms app to mono which has an open-source implementation. Of dotnet, and they have the WinForms implemented, more or less not everything's implemented, but you could maybe port that dotnet. Application, using, WinForms to mono you, you take advantage of cross-platform, frameworks, like gtk and java for those kinds, of applications so if the morning to forge Windows you, can probably, compile, the code to run in, Linux. As well and take advantage of those cross-platform, UI. Builders, like swing and AWT for. Java or gtk which is used, widely inside, of the. Leg space already or. You can use wine which is a emulation, environment, for windows-based, applications. On Linux and what it attempts to do is provide a compatibility, layer that translates, witness Windows, system calls in a POSIX calls and then, you can then run, your Windows applications, on top of that now, this application. Or. Emulation, is not a virtualization, so it's more of a compatibility, layer and it's, not 100%, compatible. With all Windows applications, some apps work great some don't work at all some of them work okay some, of them work in pieces. But if you click on this button it crashes, so one is one approach and I do want to do a demo of how you can take an old app and port it to wine so, let's go ahead take a look at that now. This. Demo I want to look at this docker file and this docker file it installs wine in a container and also installs wine tricks which is an automation tool for doing a lot of things in wine I'm, gonna go ahead and launch this I've already built this container so this docker, run and, I'm.
Not Gonna do, anything real fancy here I'm just gonna do -. IT to get an interactive, mode and then I needed to - II and. Then set a display so it knows where to write the output for the X, server that I have running on Windows here and I'm. Gonna use display 0 unless use the, container the, container image is called wine and then I'm gonna go to bin slash bash, so. I can interact with this interactively. Using a. Command, prompt or shell, and then I'm going to launch wine tricks and this will take a second to set up so we'll come back when this finishes so. Wine picked is up now now with wine tricks you can select, the default context. Here and then come into wine tricks it's going to throw up a bunch of little, dialog. Boxes and this, is where you can actually set up things inside, of wine. In your container and once you have everything set up you can do that by selecting dll's or framework. Such as.net in, this case i would saw net or dll if I was using a specific, version. Of a DLL I can select that like DirectX, or whatever it might be and I have everything set up then I would then, get. Out of wine, tricks and then, I would copy, my file from my mounted. Volume into, my application and. I've, already done this so what, I'm going to look at now is another, little example here of a, docker file, so once I've copied everything over and what. I would do is exit the container do a docker commit, against that container, and convert that container, into, a docker image, and then, I would write a docker file against, it that would look something like this and with. This particular one I basically, did. A docker commit, called it net 5 net, 3 5 and then set the command, to do wine against my app which. Is the name of the EXCI that I would otherwise use for. Copying. Something over from wine so, once I have that I can I can very easily run this and, I think I've already built this one as well so I can use this particular docker, container. Here and. If. I go docker. Images, I think it's called my app, and let's, see what that looks like and it's. Called not, net 3/5 TextPad. I think is the one I call it simple pad that's what it's called so if I go docker. Docker. Run and then, I do -, II and, that dude my display variable, again and I, do. 192.168.255.255. That's running in wine and this. Is a dotnet but, not, done at 35 that's a WinForms application that. Is running in wine but now it's in a Windows can that what's in a container that I can then open a file and edit text file it's very basic application, but, this allows me to have something, inside of a docker container, that's actually a Windows application so, this is one way that you could do Windows.
Applications. Inside, of docker containers, and then have everything. Streaming, back to EDX server or you could use the, VNC or, the expert approach that, we've seen already thanks. For coming to my session today there's a few things we can do is follow up of course you can always follow me online at, the one you'll interact, constantly post, there and interact with folks you check out my youtube, channel youtube.com. Slash, one luck now I post, a lot of content related ocker there, including some extended demos for what we've seen already today, you can check out my blog at. Www.andyjenkins.com. At, github comm slashed the one mule splash docker, Khan - demos, so thanks for coming to my session I look forward to seeing you around the conference and in future conferences, related to docker or wherever that might be.