By the time this talk starts, ASP.NET 5 and DNX should be at Release Candidate state, and .NET Core should be working too. All this means that you can run your ASP.NET MVC 6 applications in Docker containers on Linux machines, which is a brilliant way to run anything. So come and find out all about how to embrace this brave new world, up to and including running your own little platform-as-a-service within Azure, AWS or other cloud or traditional hosting environments. I'll also show you how to have a cluster of applications running in Docker and live-reloading while you edit the code on the host machine. Yes, you read that right.
 Hello, and welcome to all of the people who don't care about immutability in C-sharp. Thank you for coming. So yes, we're going to talk about something that's actually useful. If you want to mutability, use F-sharp. There you go. That's that talk done. Summarize that for you. Hi. So we're talking about ASP.net5 on Docker. And I've been doing this. I have been building this thing for the last year, which is I've taken a monolithic ASP.net Windows.net framework, MVC5 Web API2 application that has been running in Azure on, when I put it up, it was called Azure websites. We've completely changed the branding and everything, but the site's still running. But yes, it's a single, big monolithic application, and it runs in Azure websites. And it runs in every Azure data center in the world. And that is a number that gets bigger every month. Microsoft opened a new data center. They just opened three in India. They're opening one in Canada soon. There's actually going to be one here in the UK so that the banks and the government can put their data in it without worrying about it. So yes, it's getting expensive. And I have been looking for ways to try and keep my costs down. And I looked at the prices of the various hosting options inside Azure, and it turns out that when you use Azure Web Apps, it's fantastic. It is a really, really good platform, and I love it. But you pay for it. And actually what you pay, a single small VM, which is a single core, and 1.5 gigs of RAM, I think, on Azure Web Apps costs double what the same size VM costs just running Linux. And so I thought, can I get this to run on Linux? And then ASPNet5 came along. And so that was great, but I wanted the same experience running my app and deploying my app and managing it and supporting it and monitoring it and everything. Wanted the same experience with Linux VMs that I was getting with Azure Web Apps. And at the same time, my side job, which is the thing that actually pays my rent and school fees and things like that, we've been doing a lot of stuff with Docker and Node and some.NET and all this sort of stuff. And so I started learning about Docker, and I thought, this sounds great. I can use Docker and some of these orchestration systems and so forth to do what I'm doing now, but do it on Linux and with more control over it, and I can have my hosting costs. And when your hosting costs are over 1,000 pounds a month, halving them is actually quite a worthwhile activity, particularly when you're hoping to scale up anytime soon. So the first thing that you have to mention is that Docker obviously is a Linux platform at the moment. Windows is going to support it. We're getting Windows Server 2016 nano images, and you'll be able to run Windows containers on a Windows platform. But for the time being, we have ASP.net on Linux. And this works, and it's worked to some extent for over a year now, and it's just getting to the point now where it's actually reasonably stable. It's actually supported Microsoft, despite it all being open source and on GitHub, Microsoft announced it. It's got a go live license, and you're kind of going, cool, I'll stop worrying about the fact that I've been live on it for the last nine months. But yes, we can run ASP.net on Linux, and we have a choice of run times. We can either run on.net core, and we can run on Mono 4.0 something. Current stable version of Mono, I think, is 4.2. And core is, yeah, core is unstable. And the problem is that there are a lot of moving parts with.net core, and with ASP.net 5, not least of which is the name, it started out as K, then it was DNX, now it's ASP.net 5, possibly more changes coming, I don't know. But the core stuff has been a real problem. They've basically had to take the CLR and extract as much as possible from that, but then write a Linux kind of layer for it and a Darwin layer for the Macs, and make it work on Windows at the same time. So that's been challenging. And they've also taken the entire.net framework, ripped out the bits that are Windows specific, like WPF and Windows forms and system.web and anything to do with IIS. And what's left is called the core framework, and that's on GitHub. And we've got the command line tooling as well. And at the moment, the command line tools on Linux and on Mac don't work if you're using the core runtime. You have to be using the monoruntime, even though when you launch your application, it can be running on core. And the other thing is that when you port a framework from one system to the other, you kind of start with system.object, then you implement system.void and system.string and system.int32, and you gradually work your way up, which means that things like system.data and system.net.http are the last things that get done, which means that the rest of the ecosystem that's out there, people who do things like the PostgreSQL ADO.net libraries or anything that runs on top of HTTP, have been sat there twiddling their thumbs, waiting for Microsoft to catch up to this point where they can start migrating their projects. And that's just started happening. So for most of the demos I'm doing today, I'm going to be using Mono, just because I don't want to get bitten by something not working. But pretty soon, we'll be able to use core all over the place, and that will be very nice. So, yes. Well, hang on. Before I jump into doing the Docker stuff, let's just jump across to a different screen. That's the doctor's name in the original Gallifreian script. Because, yeah, why wouldn't it be? Okay. So, let's just cd into talk-ndcaspnet. Right. And I'm going to... Hello. Right. So, you're all.NET developers. You're all Visual Studio guys, yeah? Visual Studio 2013, maybe 2015, maybe 2010 if you work at one of those places. If you do, then someone will give you a hug. I'm not a tactile person myself, but we can make you feel better. But no. This is Linux. This is Arch Linux. It's proper hardcore Linux, although it's running the Cinnamon desktop, which is the most like Windows you can get. But we don't have Visual Studio. We have Visual Studio code, but despite having the VS moniker on it, it is a text editor. It's not an IDE. There is an IDE coming. JetBrains announced yesterday, Ryder. It's actually a full-blown cross-platform IDE based on IntelliJ, but with Resharper running in a separate process. And then IntelliJ talks to Resharper across just IPC. And it's going to be awesome. And I said, Hadi, can I have it for my demo thing? And he said, no, because I don't trust you to delete it afterwards. Which is completely reasonable, because I wouldn't have done. Why would you? So yes. Anyway, we're going to be using VS Code today. VS Code doesn't have that file-new project and wizards and stuff. And it doesn't need it, because we're Linux and we're Mac guys and we use the command line and we're hardcore. And we don't need wizards. We can do everything from scratch. So we do everything from scratch. So we go yo, ASP net. And then this happens. Eventually, come on. There we go. Yes. It's not a wizard. It's ASCII. Don't call it a wizard. So I choose web application basic without membership and authorization. And I hit enter. And then, what do you want to call it? I'm going to call it hello, NDC. And then look, it's gone and created a whole bunch of stuff and it's given me lovely instructions for what I need to do next down at the bottom there. So that's Yo-man, which is basically a multi-purpose scaffolding project. You install Yo-man. It's a node application, node package. And then you install a generator in generator-asp net, which is done by Microsoft. And then it basically gives you a wizard that you can pretend isn't a wizard, because you're using it from the command line. So let's do what it says here. We'll cd into hello NDC and we'll do a denu restore like this. And hopefully that's going to get everything from the cache, because otherwise it could take a while. There we go. And then we're not going to do the denu build, because you don't build ASP net five applications. You just push the code and you run them. And nobody say, oh, so it's like websites in Visual Studio 2003, because it's not. It's completely different for some reason. And then we just say dnx web. And then that will spin up. And that's used the Roslin open source C-sharp compiler to compile all my code into in memory assemblies. And then we're going to go back over to here, get rid of the terminal window. I'm going to go to a new tab here. I'm going to go local host 5000. And there you go. That is a brand new ASP net application created with don't call it a wizard running on Linux. And you can sort of tell it looks exactly like a Microsoft starter website. OK? So that works. That's nice and easy. And then we can jump into the code for that just by... So let's stop that. And we'll just go code dot. And that's going to open the Visual Studio code editor. And that's on my monitor. And you can't see it. So there. No, let's put it over here so you can. And we'll maximize that. If I can... There we go. And one thing I do like about Visual Studio code, it's a HTML, CSS, JavaScript application running inside the electron shell. Same thing that Atom runs in. But basically because it's inside there, it's Chrome, effectively. And they've just left Chrome's zoom functionality switched on. So you know, in Sublime Text or Visual Studio, when you press Control plus, it makes the editor font bigger. But for us as presenters, that's not hugely helpful when you're trying to show something in Solution Explorer. Dude on the other hand just scales the entire user interface, which I think is awesome. So yes, and you can see here we've got various bits and pieces in here. We've got our project.json. This replaces the CS Proj files. And we've got our startup, which basically replaces web.config and IIS and the integrated pipeline and a whole bunch of good stuff. And the rest of it, controllers and views all look pretty much the same. Okay. And then the other thing you notice is there's a Docker file in here. And that's generated by the wizard as well. Because obviously if you're doing this on Linux, you're going to want to run it in Docker. And actually that is true these days. People in Linux, deploying anything, pushing anything into production, you pretty much just run it in Docker unless it's like a database or a cache or something like that. Okay. So let's talk about Docker briefly. Control shift tab. There we go. So has anyone done anything with Docker with Node or Ruby or Python or Go or any of those sorts of things? Or are you all complete Docker newbies? Mostly Docker newbies? Yes. Anyone's arms work. Anyone paralyzed from the neck down? I said that once and somebody was. Don't laugh at that. It was terrible. I felt awful for seconds. So yes, Docker, the thing is it's not very small virtual machines, but the easiest way to think of it is as very small virtual machines. So the difference is that a virtual machine spins up an entire operating system and gets a chunk of memory assigned to it and it never lets go. A Docker container is a process that's running on your operating system. So it's just a process except it's got kind of fences around it to stop it from talking to other processes and everything. And it can have its own file system. And you can run Ubuntu in a Docker container even though your underlying operating system is Arch or Red Hat or CentOS or whatever. The urge to say something is just a not something nice. He's going it's not very small virtual machines. I'm not standing here to listen to this inaccurate nonsense. So yes, but that is the easiest way to think of it. Before I go any further, it does get a bit confusing. So Docker has these two concepts. You have images, which is like your virtual machine kind of configuration and your VHD file. And then you have containers, which is things that are running. So when you're creating your setup and configuring it and preparing it, you're preparing an image. And then when you run that image, it starts running in a container. So that's what those two words mean. There's lots of other words that we could talk about, but I'm not going to. Okay. So if we go and look at this Docker file that was created for us here, there are actually two things wrong out of the box. If I were to build this, it would not work. And the first one, the first one's really inexcusable. Microsoft, as I say, created the YoMoon plugin for this. So they created this Docker file and they got the name of the base image wrong. So that top line there, the from says, what's the base image that I want to use to inherit for my image? And in the same way as its turtles, all the way down, its images all the way down. So Microsoft's ASP net image that they maintain on the Docker hub, that is derived from the official mono base image that is maintained by the mono team on the Docker hub. And that is derived from one of the Debian images, Debian Linux. And that is derived from scratch. So when you create a totally base-level Docker image with the actual Linux distribution on it, you say from scratch at the top there. And then we carry on down and we say, okay, so we're going to copy the current folder into a folder on the image called app. And then we're going to CD into that and we're going to run denu restore to download all the packages. And we're going to expose port 5000. And then we're going to specify our entry point, which is DNX. The minus pproject.json is the default. You don't need the minus pproject.json. They've just put it in there in case they change the default. And can't be bothered to update the Docker file. But that says when the Docker container starts, this is what I want you to run. And then when this exits, the Docker container will close. Okay, the other reason that this won't work is slightly more obscure. And earlier on today, I was making sure that my demos worked and I was getting massive demo fail all over the place. And I was going, why doesn't this work? And then I suddenly realized that I'd written a blog post about the thing that was stopping it from working two months ago. And it's a very simple fix. The problem is that by default, if we go down and look, when I say DNX web, what the DNX command line tool actually does is it looks at this line here and says web, and then it runs the command microsoft.aspnet.server.questral. And what that will do is start the application running, listening on port 5000 on localhost. And if you listen on localhost inside a Docker container, it listens inside the Docker container. It doesn't listen outside the Docker container. We need to tell it to listen on the other address. So we say dash dash server dot urls. HTTP colon slash, let's close that so you can see, 0.0.0.0.0, colon 5000. Okay. And that says listen on all IP addresses. So if you've ever wondered what the difference between for zeros and localhost is, because they appear to do the same thing, actually the for zeros is also listening on all your IP addresses. So your Wi-Fi IP address and your internal IP address and your VMWare IP addresses and everything. So we have to add that in as well. Now we've done that, I can bring this back down and I can, let's just clear the screen here and we'll say Docker build. So this is to create our image. I've installed Docker already. You've installed Docker on your Linux box or if you've got Mac or a Windows box, you install Docker toolbox, which will put virtual box and a whole bunch of other stuff on your machine. But you'll still be able to run all the Docker commands from the Mac terminal or PowerShell or wherever you want to run this from. But I do recommend just put Linux on your box and do things on there. Or maybe not just yet, but as soon as Project Rider, as soon as JetBrains thing comes out, I literally, the only reason they will have left to run Windows is iTunes. I'm so losing my MVP award. It's just gone. Right, Docker build, I need to specify a name for the image. So I'm going to say, I'm going to call this local slash hello dash NDC. And it needs one argument, which is to tell it where the Docker file is. That's the current folder. So I'm going to say dot. Okay. Now. Did I not save that file? No, I didn't save my change to the Docker file. That always helps. Right. Let's try that again. There we go. So yes. Now what that's doing is it's going off, when Docker builds an image, what it does is it starts the base image up in a container and it runs the first command. And then it saves that as a temporary image, so it commits the changes that have been made to that container as a temporary image. And then it starts that image as a container and it runs the next command. And so it creates a whole bunch of temporary images as it's going along until eventually it runs the last command, commits that and gives it the name that you told it to give it. And one of the commands that we had in there is denourestore. And so as part of the build, it's actually running denourestore inside a running Docker container. Those files are coming down, being written onto that images container's file system. And then once it's done, we should see the rest of it go through fairly quickly. Fortunately, I have wired internet in here because otherwise this would basically take the next 45 minutes and we could just kick back and go and get some early beers. Come on. The other thing that you might notice that's going on here is that it is pulling down an awful lot of very basic stuff. If you look for long enough, you'll see it brings down system.runtime. If you don't have system.runtime installed, then your application will fail with type system.void not found. At which point you go, I've never really thought about it, but yes, I suppose system.void is a type. It's what Fsharp people call unit. So, yes, but it is pulling down the entire framework, system.io.filesystem.primitives and reflection.type extensions and the whole thing is coming down. And part of the reason for that is that despite the fact that I'm using mono, Danoo Restore uses project.json to decide what it's got to pull back down. And in project.json, we've got this framework section here. That's currently, this is going to change very soon and I think it's going to become.NET Core 50 and.NET 45 or something like that. But basically, at the moment, DNx451 on Windows translates to the.NET framework and on Mac and Linux translates to mono. And then DNx Core is the.NET Core. How are we doing? Still going. I'm going to let this go through to completion because otherwise it leaves a mess all over your hard disk. But before I forget, I'm just going to take that out because we're running on mono so we don't need it to install all those packages and stuff. That's just ridiculous. We'll just take that off like that. Don't worry. Part of the point of doing this is to show you how to avoid having to do this ever again. But you kind of need to make it do this just to kind of get the point across about how you don't want to. Maybe I could just have told you. It would have been quicker. So yeah, this is possibly a downside of working with Docker at first. The same thing happens. It doesn't matter. Pretty much anything you use these days that runs on Linux is going to have a package manager. So you could be writing something in Ruby. It's going to have to go and install a bunch of gems. You could write something in Node. It's going to have to do an NPM install. Whatever it is, you're going to have to bring on a bunch of packages. Although this is taking longer. This is the longest it's taken so far today. I'm guessing this wired internet is not all it's cracked up to be. Come on. 20 or 30 megabytes. It's nearly done. You can sort it as it goes through. So yes, system.io.file system and system.txt.encoder. You can see it getting down to the more primitive stuff. Because essentially what it's done is it's gone and it's looked in my project. There we go. That's it. It's done. Come on. Right. So it commits that to another image. This is what's taking a minute now while it writes that image. But yes, just to talk about what it's actually been doing, it's gone through this set of dependencies here. So this, what is that? 12 lines of JSON. Has replaced the whole XML and a.cs. Prog file that's telling you what to install. But it looks at each of these and then it finds their dependencies using their project.json files or their new get packages. And then it finds their dependencies and then it finds their dependencies and eventually it downloads the entire.net framework. But you don't have to specify all that stuff there. So yeah, that's the intermediate image ID that's being written out there. And we will get there in the end. It's like a whole new kind of demo. It's not fail. It's just I'm demonstrating something that takes a very long time. So I'll just go through some slides while we're talking about that. So the official image for ASP.net on Docker is that one, Microsoft slash ASP.net slash colon 1.0.0. So the parts of this are, Microsoft is the namespace. Think of it like the GitHub organization. And then ASP.net is the name of the image. And then after the colon is the tag of the image, usually the version number. But you also get colon latest. So whenever you do a build of your image, you push it to the registry and you give it its actual version number and you also overwrite latest. So you get that down as well. And what official image actually means is if I go to hub.docker.com slash r slash Microsoft, there we go. So Docker.com is where images live. Everything is going slowly. And laptop is just not, I know why it's bad. I'll plug it in and get it to turn the CPU on. That always helps. Is there a plug around here anywhere? There it is, good. That's all right, I found it. It's an SSD if you believe it. And yes, I have just run trim. Debian. I think it might even still be weasy. It sort of depends what the mono image is on. So hub. And it's usually slash underscore slash mono because it is an official, official image. So yeah, when you go to the page on each of these things, you can go there and you can see they have the Docker files here. So the 4.2.1 is the latest. And if we go here, yeah, you can see there, if I close that down and just zoom in a bit, it is actually Debian weasy, which has never been a more appropriate name. Debian weasy is like four years old. The current version is Jesse, but the mono guys haven't updated their image yet. It's fine, it works. The only real issue with Debian weasy is if you're actually running it, it's got a very old kernel. It's like 3.2 or something. But when you're running in Docker, everything that's running on it is running on whatever the kernel for the host machine is, which in my case is 4.2. So that's okay. Oh, there's dozens. So Debian is the most commonly used because it's fairly small but still a complete operating a complete distro with a decent package manager. If space is really a premium, the Debian base image is nearly 100 megabytes, I think. There is a distro called Alpine, which is five megabytes for the base image. And you can actually get an Alpine mono, but when you get Alpine mono, it's 130 megabytes, which tells you something about mono. It's quite big. But yeah, the problem with mono is it includes LLVM, for example, and LLVM is 60 megabytes, so things do get quite big quite quickly. Right, how are we doing here? There we go. Right, so I now have, if I do Docker images, we can see up at the top there, let me highlight that, we've got local slash hello NDC. Okay, and I can start that by saying Docker run, and I'm going to say minus TI. Minus T says attach a terminal, a TTY, to the process, and I says make it interactive, which means I'm going to see the standard output and standard error from any processes as the image runs. The other thing I need to do is tell it that I want to link a port from the Docker container to a port on my actual network bridge, so I'm going to say colon 5000, so that's the host port that I want to bind, and I'm going to bind that to port 5000 on my Docker container, and then I just say local slash hello NDC, and that's just going to start that up, and that's now running inside a Docker container there. Okay, and I can go back over to here, and I can go control T local host 5000, and there is the same application running inside a Docker container. Yay, we've achieved so much, we've gone to exactly the same address, and exactly the same thing has happened. Don't worry, it does get better, I promise. Right. So, first thing, I don't want to have to run that whole build process every time I do a build. Okay, I don't want it to have to do the Danoo restore, and people who do node applications and so forth have found ways around this, and one of the things you can do is you can copy project.json into your app directory, and then run Danoo restore, and then copy the rest of the files on, and then build the application from that. When you say Docker build, it works out what's changed, and so if project.json hasn't changed, it will start from the image where it had already done that last time. Okay? That makes things a lot quicker, but it doesn't make them particularly quick all the time. And the thing is, if I can just find, there we go, that's the official core CLR image, so at the moment it's got dash core CLR on the end. By the time this goes actual 1.0 final, final, final, I suspect that the default will be core CLR, and you'll have to expressly say you want mono. But yeah, so you've got your Docker file there, which looks like that. We've already looked at that. But to save time, the thing is, when you write a node application, everything has to go into your node modules folder inside the actual application itself..NET, ASP.NET 5 doesn't work like that. It actually puts the packages into a shared location, which is common, so across all the different things. It's versioned. It's sort of a bit like the GAC, but it's not. For a start, it doesn't write a whole bunch of GUIDs into the registry as part of putting a file in there. It is just a folder. But if I say install Microsoft.asp.NET.MVC and all its dependencies, it goes into a shared location. The next time I say to new restore, it just goes, I've got it cached. What I've got is CloudLens images, dnx Docker, and so I've grabbed myself a project.json from a Yeoman output. I've taken out the dnx core 50 line there, and then I've basically just got a Docker file here that goes from Microsoft's base image, copies my project.json file into the temp directory, and runs to new restore. That pulls all those packages down into the images slash root slash dot dnx slash packages, and then I delete the project.json files and I set the work to back to slash where it should be, and I've created an image that has already got the most common packages and all the system dot run time and everything else pre-installed into it. If I go back to my Docker image here, and I'm just going to change this, so I have a Docker repository as well. It's called CloudLens, and I have published my pre-restored image up there as just ASP.NET colon 1.0.0-rc1. If I save that, and we'll go back to here, so you can see that was showing the output from my application there, and I'm going to just come down here. Docker build. This is going from this Docker file, but this is using my pre-restored image. This is on the Docker hub, and you are perfectly free. There's no clever licensing or everything. If you want to use cloudlens slash ASP.NET as your base image, feel free to do that. If you want to copy the Docker file from my repo on GitHub and adapt it, or maybe add like newtonsoft.json or something to the project.json file, you're absolutely free to do that as well. But now, when we do... oh, God. I'm pretty sure that's what I called it. Never mind, we'll just say latest because it's the same thing. There you go. That's pulling that down. That's pulling my thing from the image there. I almost don't want to let that finish. Right. You come here, hub.docker.com slash cloudlens. Build details. Oh, no, I did put... I left final on there. There we go. That'll make life a lot easier. Right. 1.0.0-rc1-final. Okay. And we'll start that again because I do already have that on my machine. There we go. And so you see, that's just used the cache built into that Docker image. So that runs incredibly quickly. And I don't have to worry about that taking ages every single time. So that's quite cool, right? That saves a lot of time. And then I could run that and we'd still be at exactly the same point as before. Okay. Let's not do that because that's not a good use of anybody's time. And whilst I might not care about yours, I do care about mine. No, wait, I got that the wrong way around. Sorry. So, yeah. When you're actually sat at your desk, when you go back to work and say, we need to do everything in ASP and F5 and Docker, because Mark Rendell said so. And they say, right, there you go. And you sit down. If you, you know, even with a kind of pre-filled image, that process has gone from F5 Internet Explorer opens, you close Internet Explorer, you go back, you change the browser to Google Chrome and you press F5 again, and it just launches and you get that nice flow there. This is going to slow that flow down a lot. And generally, even if you're not working on Docker, you still have to kind of go out and stop the process and restart it every time you change some code. Node has something called Nodemon and various other things that just check to see if any of the files change. And if they do, it restarts the process. And now on ASP and F5, we have DNX-watch, which is almost certainly going to change to.NET-watch, but never mind. And that does the same thing. You say DNX-watch in a folder, and it watches the code that's running. And if you change anything and save it, it just stops the process and restarts it. And so you go back to the browser and hit F5, and it reloads the page using the new code. And so as well as creating a preloaded ASP-NET container, I created a DNX-watch container, and that looks like... Where are we? I quite clearly closed that. Right. So the image for that is here. And again, this is on, so you can just do cloudlens slash DNX-watch and pull this down as well. But if I do the cat docker file... So yeah, this is a bit more interesting. So what we've got here is the same thing up at the top there to save it having to do the actual reload every single time. But then I've added some extra variables in to say what the DNX version is and what the user home is, and then we're going to install the DNX-watcher there. So that's... It's a Microsoft package. And in the same way as you can do NPM install minus G, you can say Danoo commands install to install something that's actually supposed to be run from the command line. Then, and this is the fun bit, we declare a volume in our docker container. So a volume is a mount point, effectively, in the docker container. It's saying I am exposing this volume and you can mount something onto it, and also, if you want to, you can see it from other containers. So to run my application, my HelloNDC application, using that, I say escape-dnx-watch. Yeah, there we go. I love bash. So this is my new docker run command. So I'm not actually... I don't need a docker file at all to use this. It doesn't need its own docker file because that DNX-watch image will work with anything. And you can see that I'm using dash e to set an environment variable. That's telling it where my project is. And then I've got dash v and I'm setting the present working directory and mounting that to the slash project volume inside this container. That won't actually work because I've broken some rules on there, but it's time to jump in to the project that I prepared earlier. So let's just shut that down and we'll go out of here and into demo. All right, and we'll start from here. Okay. So here is the demo application that I prepared earlier. This is called micro stuff. And this will work perfectly if I run this here. And okay. Hopefully. This is having to install. So part of what it does as it starts up is it runs an install. And I'm just going to make sure that I can see. Nope. Okay. Sometimes, you just have to restart your entire network stack. There we go. That would have been so much harder on Windows. That would have been please bear with me while I reboot Windows. Okay. So let's go back over to where I was doing that and we'll try that again. Right. There we go. That's done the restore properly now. And that's going and it's getting newtonsoft.jsonassystem.net.http, which are the additional dependencies that I have in this application. And now that's running there. So the fun thing now, okay, is if I go to here, if I hit F5 again. That's just going to display exactly the same stuff. But if we go and look in my home controller, what I've done here is I have parameterized all those banners in that carousel at the top so that they're data driven in this application. I didn't manage to get this uploaded to GitHub because I don't know if you've used WiFi and tried to do a Git push. It's not good. It doesn't like it. But I will push this and do the thing. But yes, you can see here that I have put the text and everything for these banners into code rather than into the CSHTML. If you change CSHTML in here, F5, it will just rebuild it because RAZER is good like that. But if you change your code, then things are different. So if I go learn, that's it. We'll do that. I'm going to go up to here and I'm going to say learn how to run ASP.NET apps or learn how to ASP.NET apps. Run ASP.NET apps in Docker. Okay? Save that. If we go back to here, you can see that you've got the file changed. This is inside the Docker container. The DNX has picked up the fact that my mounted folder, which is mounted on a volume in the Docker container, something's changed and it's restarted the application. If I go back to here and do that and hit F5 and it refreshes and it says, there you go, learn how to run ASP.NET apps in Docker and for the people at the back, yes, it does. Okay? So that's good. We can start our application running in Docker and we can make changes to it and we can save it and we don't need to keep rebuilding our Docker container. So we're getting somewhere. This is already quite good. There's my slides. Okay. But the question is, why would you want to have the application running inside Docker if you're on your local machine and you don't need that? So there are various reasons why you might do this. One of the reasons I do it is because the new.NET stack, the stuff that they were talking about, David Fowler and Damian Edwards have been talking about, where the DNU and DNX have been replaced by.NET. At the moment, you can run it on Windows and you can run it on Mac and you can run it on Ubuntu 14.04 and you can't run it on any other flavor of Linux at all, which means I can't run it on my Arch Linux laptop and I'm buggered if I'm putting Ubuntu 14.04 as the actual operating system on my laptop, but I can use the Ubuntu 14.04 base image and I can run the.NET stuff inside that. So that's one use for it. But the other use for it is that, oh, don't ask about debugging inside Docker. It always goes, what's the debugging story inside Docker containers? And I just say it's a very short story and it doesn't end with and they all lived happily ever after. You can't do it yet. You probably will be able to at some point, if you ask that question, I will rip your arm off and beat you to death with a bloody end. So yes. What is the story outside of Docker? Actually at the moment, off Windows, it's the same very short story with an unhappy ending, but they are working on it. The problem is that.NET and Mono and.NET Core had a completely different set of ideas about what a PDB should look like. And then they all got together and went, how about we standardize on this? And funnily enough, it was the Mono people who had to do the most work. Odd that. So yes, they have come to an agreement and it's going to get better and you can do remote attaching and so forth. It's going to get there. Once you can do remote attaching, you should be able to just open an additional port on your Docker container and you should be able to debug stuff running in Docker containers. Okay. So that's kind of fun. But the other thing that I've done, when you get into Docker, when you start thinking in terms of running stuff in containers, deploying becomes a lot easier. Making your stuff becomes a lot easier and all that crap that Martin Fowler has been coming out with about microservices suddenly makes a lot more sense. When something is literally just a matter of building an image, pushing it up to your machine and starting it and then taking the old one down, you kind of go, it's not such a big thing. So I'm going to make lots of microservices. So CloudLens, which, so Zudio, it works with Azure Storage. It works with blobs and tables and queues and files and analytics and all these different things. What's one big application? It's now, there are like two applications for each area. So I have a blobs container and a tables container and a base container and all sorts of stuff. And so the thing runs and it uses multiple domains and cores and it's all great. And if you make a request against blobs, it sends it to a specific service in that data center and everything else. Which is an absolute sod, the problem with microservices is that they're really difficult to develop because you have to have all these microservices running on your machine or you have to have a kind of set of development shadow microservices that you can run against. Microservices with Docker is a lot easier and I've been working on something during the day for my customer at the moment where we are using Kafka, the kind of distributed Java message bus thing and we're using a Mongo database and there's lots of different pieces and it's like eight Docker containers that we drag up in order to do this. And you don't bring them all up one at a time and you don't write shell scripts. We have something called Docker compose and compose, you define your entire setup in a YAML file and then you say Docker compose up and it just brings up however many Docker containers you specified and sticks them all together. And so I can put all the different projects that make up all the different backend services for Cloud Lens into a Docker compose.YML file and I can make that run all at the same time and I can take it all down at the same time and I can clean them all up at the same time and everything else. So let's take a look at what a Docker compose file looks like. Right. So this is Docker compose, I'll make that as big as I can. That's it. Can you see at the back? I can go probably one more and do a bit of scroll. You're all right. Good. So what we've got here, ignore that top one just for a minute. We've got microstuff and within that I've said build. So my first property there is build and that's saying to Docker compose, use Docker to build the Docker file that is in SRC slash microstuff. When you run the container, give it the name microstuff and link it to carousel and then down at the bottom we've got carousel here which is building something else and giving it a different name. And these are both ASP and net applications. I haven't changed anything at all. They both run on port 5000 and I can't bind port 5000 from two containers to the same port on my local box and actually I've got sub-domains and all sorts of stuff going on here. So what I really want to do is to get these things working with proper domains. The other reason that's incredibly useful is when you're doing Windows Live or Microsoft account authentication which refuses to let you put a local host URL as the callback. So I have microstuff.io that's just pointing to local host and star.microsoft.io, microstuff.io is pointing to local host. The thing up at the top is possibly the single most useful Docker image since the DB and Weezy base image. It's magical. What that does, so that's using an image, J wilder is this guy who just does amazing Docker-y things. And that, it runs Nginx and it's exposed so we would link port 80 inside there which is what Nginx is running on to port 80 on the local machine. You normally couldn't do that but the Docker demon service that's running on Linux and taking care of all this is running with super useful permissions so it can bind stuff to port 80. And then the volume that we're mounting there, we're taking our Docker.soc which is the Unix domain socket that the demon uses to accept commands and push his events out on and we're mounting that into a Docker container. So the container is actually talking to the Docker process that is running the container which is just wonderfully meta. And once we've done that, it just sits there and it says to the Docker process, tell me when a container starts and the Docker process, oh, I started a container and it's called carousel. And it goes and it says, can I see the details for that carousel? In particular, I would like to know what ports it exposes and I would like to know, does it have a virtual underscore host environment variable that I can see? And Docker says yes, it does. And he regenerates the nginx.conf file to point carousel.micrustuff.io host header requests to that Docker container. And it does the same thing with micrustuff.io. So the effect of this is that I can say Docker-compose up. So recreating carousel, restarting proxy, recreating microstuff. And once that's up, we'll see the output there. So Docker-compose, one of the things it does that I love is it colors the output from the different things, different colors. And it's random every time. There may be a parameter you can pass in that controls it. But yes, so microstuff is green, carousel is blue, and proxy is yellowish. And now I can go back to my browser thing here and I can say control T and I can type in microstuff.io and we'll get that pop up there like that. Oh, look at that. It's still doing that thing. It shouldn't be doing that. Let's just jump back over to here. We'll shut that down. So what's happened is that the last time I ran Docker-compose, it built that. I've kind of ruined my big kittens moment now. Never mind. So yes, I shut this down like that. So I'm going to do Docker-compose build, which will force it to rebuild those images there like that. And I haven't gone yellow on this thing yet. I don't know if I've got like an extra five minutes at the end or you're just really enjoying the talk or something. Okay. It's good. He's really enjoying the talk. Right, and then we'll do Docker-compose up again. Okay. And let's go back over to here and we'll try doing control F5 on that. There we go. Right, back to normal. Hurry. So yes, I forget the kittens. The kittens never happened. Look into my eyes. Look into my eyes. Look around my eyes. Look around. Yes. So yeah, we're back to there. Right. Now, so I could change it and I could do Docker-compose build and Docker-compose up and everything, but that would take far too long. So let's jump back out to here as well and we'll stop those things like that. So we're going to MV Docker-compose.yml to Docker-compose.yml.slow and boring. Okay. And then we're going to MV Docker-compose.yml.watch to Docker-compose.yml. Okay. And then we're going to open this up and we're going to look in here. So this, I think I might have a slide for this. Putting it all together. Yes, there we go. This is the really good bit. This is the kind of piesta resistance of the entire talk. So I showed you DNxWatch, which allows you to do a live reload inside Docker container. Yeah. And I showed you Docker-compose, which allows you to bring multiple things up at the same time. And so now I'm going to put those two things together. So in my Docker-compose file, I am saying use the cloud lens slash DNx-watch image. I'm using the Docker information here to set the DNx project environment variable and I'm using the virtual host thing there to tell engine x proxy what to call stuff. And I'm mounting my current folder. So I've got my volume section there and I'm mounting that into the DNxWatch image container. And also, I've added a link entry there to say that microstuff needs to be linked to carousel. And what that's going to do is it's going to add an entry to the et cetera hosts in the microstuff container pointing to the IP address of the carousel container. So I don't have to worry about what its IP address is. If I say ping carousel from inside microstuff, it will just ping it automatically. So I can do Docker-compose up there. Don't have to worry about rebuilds and everything there. And there you can see that's doing a little bit more work as it brings those up. But pretty soon we should see it started and it's listening on port 5000 things going there. So yeah, running DNx-watch, listening on 5000. And we should see another quick one of those going past there as that one starts up. Okay. So I now have my SRC project, all my code is mounted into two Docker containers that are running on two different URLs into completely separate processes isolated from each other, only able to communicate over TCP and HTTP and so forth. And if I go back to my screen here, don't want that one. That's the one I want. Right. So that's still doing basically the same thing. If I now go into my hello controller here, right, and go back up to the top here, you can see I've got my var banners equals banners. I'm going to comment that line out and I'm going to uncomment this line here. All right. And this is talking to the carousel microservice. So there it's using carousel and it knows it's running on port 5000 because it's a dot net application and they all run on port 5000. And it's consuming carousel as a microservice. Okay. And it's going, I need your API, give me a list of all the banners that I should display in here. Okay. And if I save that and we jump back out and look here, we can see that that's restarting there and that started. And then I can go back to my page here and I can say F5. And it switched across to using the stuff that's sourced from the carousel microservice because you might have, you know, a content management site or something. You don't necessarily want to have to redeploy your entire site just because you want to add a new banner into the carousel or something. So you have a kind of microservice that drives your carousel from a database or something and you can switch that around. But yes, learn how to build lightsabers that kittens can use. And we do have, we have more links on there as well. So yes, there are powerful new features in the dark side of the force. Darth kitten. So yes. And that's coming through from there. And the other fun thing that's happening with that is that if we go to the banners controller, so this is the API controller in the carousel application. Okay. And you can see here that we specified a host at this point, which is carousel.microstuff.io. And then we're just using, if you haven't done C sharp 6, that image URL there is using string interpolation to just put that host property in. And so this is why I need, although carousel is being consumed internally as a microservice, it's also exposed with the carousel.microstuff.io domain so that it can serve those static images out as well. So I've got the images and the data coming from this microservice, which I can switch around. And so this is how I have been working on my application. When I do Docker compose up, when I'm working with Cloud Lens, it brings up up to a dozen Docker containers. I'm running on a fairly old dual core laptop with eight gigs of RAM, and it works, and it's not painfully slow. And I can still keep Visual Studio code running at the same time, and I can debug it, and everything is nice. So you get this running on something with a bit more oomph. If you're going to do this on Windows, if you want to use Visual Studio on Windows, then you can use Visual Studio, mount the directory that you're running into a Linux VM, and then run all this stuff inside the Linux VM, but use Visual Studio to edit the CS files and the CS HTML files. That works great as well, but you do need a quad core machine if you want to do that. So yes, that is basically the story for running ASPNet 5 on Docker at the moment. I got the timing just about right. So that's it. I hope that gave you a good introduction. I hope it gave you a taste of what we can do now, now that Microsoft have decided to open things up and join the rest of the world, and go off and try it. I will push all the code from this Microsoft service up to GitHub when I get a decent internet connection. Any questions? I think we have run out of time. So we need to stop, but do feel free to come up and we'll go and sort of grab something. You can get me on Twitter, markrendl, or mail me mark at rendl.io. I've got some cards if you want those. Thank you very much for listening to me enjoy the rest of your conference.
 Hello, and welcome to all of the people who don't care about immutability in C-sharp.  Thank you for coming.  So yes, we're going to talk about something that's actually useful.  If you want to mutability, use F-sharp.  There you go.  That's that talk done.  Summarize that for you.  Hi.  So we're talking about ASP.net5 on Docker.  And I've been doing this.  I have been building this thing for the last year, which is I've taken a monolithic ASP.net  Windows.net framework, MVC5 Web API2 application that has been running in Azure on, when I  put it up, it was called Azure websites.  We've completely changed the branding and everything, but the site's still running.  But yes, it's a single, big monolithic application, and it runs in Azure websites.  And it runs in every Azure data center in the world.  And that is a number that gets bigger every month.  Microsoft opened a new data center.  They just opened three in India.  They're opening one in Canada soon.  There's actually going to be one here in the UK so that the banks and the government can  put their data in it without worrying about it.  So yes, it's getting expensive.  And I have been looking for ways to try and keep my costs down.  And I looked at the prices of the various hosting options inside Azure, and it turns  out that when you use Azure Web Apps, it's fantastic.  It is a really, really good platform, and I love it.  But you pay for it.  And actually what you pay, a single small VM, which is a single core, and 1.5 gigs of  RAM, I think, on Azure Web Apps costs double what the same size VM costs just running Linux.  And so I thought, can I get this to run on Linux?  And then ASPNet5 came along.  And so that was great, but I wanted the same experience running my app and deploying my  app and managing it and supporting it and monitoring it and everything.  Wanted the same experience with Linux VMs that I was getting with Azure Web Apps.  And at the same time, my side job, which is the thing that actually pays my rent and school  fees and things like that, we've been doing a lot of stuff with Docker and Node and some .NET and all this sort of stuff.  And so I started learning about Docker, and I thought, this sounds great.  I can use Docker and some of these orchestration systems and so forth to do what I'm doing  now, but do it on Linux and with more control over it, and I can have my hosting costs.  And when your hosting costs are over 1,000 pounds a month, halving them is actually quite  a worthwhile activity, particularly when you're hoping to scale up anytime soon.  So the first thing that you have to mention is that Docker obviously is a Linux platform  at the moment.  Windows is going to support it.  We're getting Windows Server 2016 nano images, and you'll be able to run Windows containers  on a Windows platform.  But for the time being, we have ASP.net on Linux.  And this works, and it's worked to some extent for over a year now, and it's just getting  to the point now where it's actually reasonably stable.  It's actually supported Microsoft, despite it all being open source and on GitHub, Microsoft  announced it.  It's got a go live license, and you're kind of going, cool, I'll stop worrying about  the fact that I've been live on it for the last nine months.  But yes, we can run ASP.net on Linux, and we have a choice of run times.  We can either run on.net core, and we can run on Mono 4.0 something.  Current stable version of Mono, I think, is 4.2.  And core is, yeah, core is unstable.  And the problem is that there are a lot of moving parts with.net core, and with ASP.net  5, not least of which is the name, it started out as K, then it was DNX, now it's ASP.net  5, possibly more changes coming, I don't know.  But the core stuff has been a real problem.  They've basically had to take the CLR and extract as much as possible from that, but  then write a Linux kind of layer for it and a Darwin layer for the Macs, and make it work  on Windows at the same time.  So that's been challenging.  And they've also taken the entire.net framework, ripped out the bits that are Windows specific,  like WPF and Windows forms and system.web and anything to do with IIS.  And what's left is called the core framework, and that's on GitHub.  And we've got the command line tooling as well.  And at the moment, the command line tools on Linux and on Mac don't work if you're using  the core runtime.  You have to be using the monoruntime, even though when you launch your application, it  can be running on core.  And the other thing is that when you port a framework from one system to the other, you  kind of start with system.object, then you implement system.void and system.string and  system.int32, and you gradually work your way up, which means that things like system.data  and system.net.http are the last things that get done, which means that the rest of the  ecosystem that's out there, people who do things like the PostgreSQL ADO.net libraries  or anything that runs on top of HTTP, have been sat there twiddling their thumbs, waiting  for Microsoft to catch up to this point where they can start migrating their projects.  And that's just started happening.  So for most of the demos I'm doing today, I'm going to be using Mono, just because I  don't want to get bitten by something not working.  But pretty soon, we'll be able to use core all over the place, and that will be very  nice.  So, yes.  Well, hang on.  Before I jump into doing the Docker stuff, let's just jump across to a different screen.  That's the doctor's name in the original Gallifreian script.  Because, yeah, why wouldn't it be?  Okay.  So, let's just cd into talk-ndcaspnet.  Right.  And I'm going to...  Hello.  Right.  So, you're all.NET developers.  You're all Visual Studio guys, yeah?  Visual Studio 2013, maybe 2015, maybe 2010 if you work at one of those places.  If you do, then someone will give you a hug.  I'm not a tactile person myself, but we can make you feel better.  But no.  This is Linux.  This is Arch Linux.  It's proper hardcore Linux, although it's running the Cinnamon desktop, which is the most like  Windows you can get.  But we don't have Visual Studio.  We have Visual Studio code, but despite having the VS moniker on it, it is a text editor.  It's not an IDE.  There is an IDE coming.  JetBrains announced yesterday, Ryder.  It's actually a full-blown cross-platform IDE based on IntelliJ, but with Resharper running  in a separate process.  And then IntelliJ talks to Resharper across just IPC.  And it's going to be awesome.  And I said, Hadi, can I have it for my demo thing?  And he said, no, because I don't trust you to delete it afterwards.  Which is completely reasonable, because I wouldn't have done.  Why would you?  So yes.  Anyway, we're going to be using VS Code today.  VS Code doesn't have that file-new project and wizards and stuff.  And it doesn't need it, because we're Linux and we're Mac guys and we use the command  line and we're hardcore.  And we don't need wizards.  We can do everything from scratch.  So we do everything from scratch.  So we go yo, ASP net.  And then this happens.  Eventually, come on.  There we go.  Yes.  It's not a wizard.  It's ASCII.  Don't call it a wizard.  So I choose web application basic without membership and authorization.  And I hit enter.  And then, what do you want to call it?  I'm going to call it hello, NDC.  And then look, it's gone and created a whole bunch of stuff and it's given me lovely instructions  for what I need to do next down at the bottom there.  So that's Yo-man, which is basically a multi-purpose scaffolding project.  You install Yo-man.  It's a node application, node package.  And then you install a generator in generator-asp net, which is done by Microsoft.  And then it basically gives you a wizard that you can pretend isn't a wizard, because you're  using it from the command line.  So let's do what it says here.  We'll cd into hello NDC and we'll do a denu restore like this.  And hopefully that's going to get everything from the cache, because otherwise it could  take a while.  There we go.  And then we're not going to do the denu build, because you don't build ASP net five applications.  You just push the code and you run them.  And nobody say, oh, so it's like websites in Visual Studio 2003, because it's not.  It's completely different for some reason.  And then we just say dnx web.  And then that will spin up.  And that's used the Roslin open source C-sharp compiler to compile all my code into in memory  assemblies.  And then we're going to go back over to here, get rid of the terminal window.  I'm going to go to a new tab here.  I'm going to go local host 5000.  And there you go.  That is a brand new ASP net application created with don't call it a wizard running on Linux.  And you can sort of tell it looks exactly like a Microsoft starter website.  OK?  So that works.  That's nice and easy.  And then we can jump into the code for that just by...  So let's stop that.  And we'll just go code dot.  And that's going to open the Visual Studio code editor.  And that's on my monitor.  And you can't see it.  So there.  No, let's put it over here so you can.  And we'll maximize that.  If I can...  There we go.  And one thing I do like about Visual Studio code, it's a HTML, CSS, JavaScript application  running inside the electron shell.  Same thing that Atom runs in.  But basically because it's inside there, it's Chrome, effectively.  And they've just left Chrome's zoom functionality switched on.  So you know, in Sublime Text or Visual Studio, when you press Control plus, it makes the  editor font bigger.  But for us as presenters, that's not hugely helpful when you're trying to show something  in Solution Explorer.  Dude on the other hand just scales the entire user interface, which I think is awesome.  So yes, and you can see here we've got various bits and pieces in here.  We've got our project.json.  This replaces the CS Proj files.  And we've got our startup, which basically replaces web.config and IIS and the integrated  pipeline and a whole bunch of good stuff.  And the rest of it, controllers and views all look pretty much the same.  Okay.  And then the other thing you notice is there's a Docker file in here.  And that's generated by the wizard as well.  Because obviously if you're doing this on Linux, you're going to want to run it in Docker.  And actually that is true these days.  People in Linux, deploying anything, pushing anything into production, you pretty much  just run it in Docker unless it's like a database or a cache or something like that.  Okay.  So let's talk about Docker briefly.  Control shift tab.  There we go.  So has anyone done anything with Docker with Node or Ruby or Python or Go or any of those  sorts of things?  Or are you all complete Docker newbies?  Mostly Docker newbies?  Yes.  Anyone's arms work.  Anyone paralyzed from the neck down?  I said that once and somebody was.  Don't laugh at that.  It was terrible.  I felt awful for seconds.  So yes, Docker, the thing is it's not very small virtual machines, but the easiest way  to think of it is as very small virtual machines.  So the difference is that a virtual machine spins up an entire operating system and gets  a chunk of memory assigned to it and it never lets go.  A Docker container is a process that's running on your operating system.  So it's just a process except it's got kind of fences around it to stop it from talking  to other processes and everything.  And it can have its own file system.  And you can run Ubuntu in a Docker container even though your underlying operating system  is Arch or Red Hat or CentOS or whatever.  The urge to say something is just a not something nice.  He's going it's not very small virtual machines.  I'm not standing here to listen to this inaccurate nonsense.  So yes, but that is the easiest way to think of it.  Before I go any further, it does get a bit confusing.  So Docker has these two concepts.  You have images, which is like your virtual machine kind of configuration and your VHD  file.  And then you have containers, which is things that are running.  So when you're creating your setup and configuring it and preparing it, you're preparing an image.  And then when you run that image, it starts running in a container.  So that's what those two words mean.  There's lots of other words that we could talk about, but I'm not going to.  Okay.  So if we go and look at this Docker file that was created for us here, there are actually  two things wrong out of the box.  If I were to build this, it would not work.  And the first one, the first one's really inexcusable.  Microsoft, as I say, created the YoMoon plugin for this.  So they created this Docker file and they got the name of the base image wrong.  So that top line there, the from says, what's the base image that I want to use to inherit  for my image?  And in the same way as its turtles, all the way down, its images all the way down.  So Microsoft's ASP net image that they maintain on the Docker hub, that is derived from the  official mono base image that is maintained by the mono team on the Docker hub.  And that is derived from one of the Debian images, Debian Linux.  And that is derived from scratch.  So when you create a totally base-level Docker image with the actual Linux distribution on  it, you say from scratch at the top there.  And then we carry on down and we say, okay, so we're going to copy the current folder  into a folder on the image called app.  And then we're going to CD into that and we're going to run denu restore to download all  the packages.  And we're going to expose port 5000.  And then we're going to specify our entry point, which is DNX.  The minus pproject.json is the default.  You don't need the minus pproject.json.  They've just put it in there in case they change the default.  And can't be bothered to update the Docker file.  But that says when the Docker container starts, this is what I want you to run.  And then when this exits, the Docker container will close.  Okay, the other reason that this won't work is slightly more obscure.  And earlier on today, I was making sure that my demos worked and I was getting massive  demo fail all over the place.  And I was going, why doesn't this work?  And then I suddenly realized that I'd written a blog post about the thing that was stopping  it from working two months ago.  And it's a very simple fix.  The problem is that by default, if we go down and look, when I say DNX web, what the  DNX command line tool actually does is it looks at this line here and says web, and  then it runs the command microsoft.aspnet.server.questral.  And what that will do is start the application running, listening on port 5000 on localhost.  And if you listen on localhost inside a Docker container, it listens inside the Docker container.  It doesn't listen outside the Docker container.  We need to tell it to listen on the other address.  So we say dash dash server dot urls.  HTTP colon slash, let's close that so you can see, 0.0.0.0.0, colon 5000.  Okay.  And that says listen on all IP addresses.  So if you've ever wondered what the difference between for zeros and localhost is, because  they appear to do the same thing, actually the for zeros is also listening on all your  IP addresses.  So your Wi-Fi IP address and your internal IP address and your VMWare IP addresses and  everything.  So we have to add that in as well.  Now we've done that, I can bring this back down and I can, let's just clear the screen  here and we'll say Docker build.  So this is to create our image.  I've installed Docker already.  You've installed Docker on your Linux box or if you've got Mac or a Windows box, you install  Docker toolbox, which will put virtual box and a whole bunch of other stuff on your machine.  But you'll still be able to run all the Docker commands from the Mac terminal or PowerShell  or wherever you want to run this from.  But I do recommend just put Linux on your box and do things on there.  Or maybe not just yet, but as soon as Project Rider, as soon as JetBrains thing comes out,  I literally, the only reason they will have left to run Windows is iTunes.  I'm so losing my MVP award.  It's just gone.  Right, Docker build, I need to specify a name for the image.  So I'm going to say, I'm going to call this local slash hello dash NDC.  And it needs one argument, which is to tell it where the Docker file is.  That's the current folder.  So I'm going to say dot.  Okay.  Now.  Did I not save that file?  No, I didn't save my change to the Docker file.  That always helps.  Right.  Let's try that again.  There we go.  So yes.  Now what that's doing is it's going off, when Docker builds an image, what it does is it  starts the base image up in a container and it runs the first command.  And then it saves that as a temporary image, so it commits the changes that have been made  to that container as a temporary image.  And then it starts that image as a container and it runs the next command.  And so it creates a whole bunch of temporary images as it's going along until eventually  it runs the last command, commits that and gives it the name that you told it to give  it.  And one of the commands that we had in there is denourestore.  And so as part of the build, it's actually running denourestore inside a running Docker  container.  Those files are coming down, being written onto that images container's file system.  And then once it's done, we should see the rest of it go through fairly quickly.  Fortunately, I have wired internet in here because otherwise this would basically take  the next 45 minutes and we could just kick back and go and get some early beers.  Come on.  The other thing that you might notice that's going on here is that it is pulling down an  awful lot of very basic stuff.  If you look for long enough, you'll see it brings down system.runtime.  If you don't have system.runtime installed, then your application will fail with type  system.void not found.  At which point you go, I've never really thought about it, but yes, I suppose system.void is  a type.  It's what Fsharp people call unit.  So, yes, but it is pulling down the entire framework, system.io.filesystem.primitives  and reflection.type extensions and the whole thing is coming down.  And part of the reason for that is that despite the fact that I'm using mono, Danoo Restore  uses project.json to decide what it's got to pull back down.  And in project.json, we've got this framework section here.  That's currently, this is going to change very soon and I think it's going to become .NET Core 50 and.NET 45 or something like that.  But basically, at the moment, DNx451 on Windows translates to the.NET framework and on Mac  and Linux translates to mono.  And then DNx Core is the.NET Core.  How are we doing?  Still going.  I'm going to let this go through to completion because otherwise it leaves a mess all over  your hard disk.  But before I forget, I'm just going to take that out because we're running on mono so  we don't need it to install all those packages and stuff.  That's just ridiculous.  We'll just take that off like that.  Don't worry.  Part of the point of doing this is to show you how to avoid having to do this ever again.  But you kind of need to make it do this just to kind of get the point across about how  you don't want to.  Maybe I could just have told you.  It would have been quicker.  So yeah, this is possibly a downside of working with Docker at first.  The same thing happens.  It doesn't matter.  Pretty much anything you use these days that runs on Linux is going to have a package manager.  So you could be writing something in Ruby.  It's going to have to go and install a bunch of gems.  You could write something in Node.  It's going to have to do an NPM install.  Whatever it is, you're going to have to bring on a bunch of packages.  Although this is taking longer.  This is the longest it's taken so far today.  I'm guessing this wired internet is not all it's cracked up to be.  Come on.  20 or 30 megabytes.  It's nearly done.  You can sort it as it goes through.  So yes, system.io.file system and system.txt.encoder.  You can see it getting down to the more primitive stuff.  Because essentially what it's done is it's gone and it's looked in my project.  There we go.  That's it.  It's done.  Come on.  Right.  So it commits that to another image.  This is what's taking a minute now while it writes that image.  But yes, just to talk about what it's actually been doing, it's gone through this set of  dependencies here.  So this, what is that?  12 lines of JSON.  Has replaced the whole XML and a.cs.  Prog file that's telling you what to install.  But it looks at each of these and then it finds their dependencies using their project.json  files or their new get packages.  And then it finds their dependencies and then it finds their dependencies and eventually  it downloads the entire.net framework.  But you don't have to specify all that stuff there.  So yeah, that's the intermediate image ID that's being written out there.  And we will get there in the end.  It's like a whole new kind of demo.  It's not fail.  It's just I'm demonstrating something that takes a very long time.  So I'll just go through some slides while we're talking about that.  So the official image for ASP.net on Docker is that one, Microsoft slash ASP.net slash  colon 1.0.0.  So the parts of this are, Microsoft is the namespace.  Think of it like the GitHub organization.  And then ASP.net is the name of the image.  And then after the colon is the tag of the image, usually the version number.  But you also get colon latest.  So whenever you do a build of your image, you push it to the registry and you give it  its actual version number and you also overwrite latest.  So you get that down as well.  And what official image actually means is if I go to hub.docker.com slash r slash Microsoft,  there we go.  So Docker.com is where images live.  Everything is going slowly.  And laptop is just not, I know why it's bad.  I'll plug it in and get it to turn the CPU on.  That always helps.  Is there a plug around here anywhere?  There it is, good.  That's all right, I found it.  It's an SSD if you believe it.  And yes, I have just run trim.  Debian.  I think it might even still be weasy.  It sort of depends what the mono image is on.  So hub.  And it's usually slash underscore slash mono because it is an official, official image.  So yeah, when you go to the page on each of these things, you can go there and you can  see they have the Docker files here.  So the 4.2.1 is the latest.  And if we go here, yeah, you can see there, if I close that down and just zoom in a bit,  it is actually Debian weasy, which has never been a more appropriate name.  Debian weasy is like four years old.  The current version is Jesse, but the mono guys haven't updated their image yet.  It's fine, it works.  The only real issue with Debian weasy is if you're actually running it, it's got a very  old kernel.  It's like 3.2 or something.  But when you're running in Docker, everything that's running on it is running on whatever  the kernel for the host machine is, which in my case is 4.2.  So that's okay.  Oh, there's dozens.  So Debian is the most commonly used because it's fairly small but still a complete operating  a complete distro with a decent package manager.  If space is really a premium, the Debian base image is nearly 100 megabytes, I think.  There is a distro called Alpine, which is five megabytes for the base image.  And you can actually get an Alpine mono, but when you get Alpine mono, it's 130 megabytes,  which tells you something about mono.  It's quite big.  But yeah, the problem with mono is it includes LLVM, for example, and LLVM is 60 megabytes,  so things do get quite big quite quickly.  Right, how are we doing here?  There we go.  Right, so I now have, if I do Docker images, we can see up at the top there, let me highlight  that, we've got local slash hello NDC.  Okay, and I can start that by saying Docker run, and I'm going to say minus TI.  Minus T says attach a terminal, a TTY, to the process, and I says make it interactive,  which means I'm going to see the standard output and standard error from any processes  as the image runs.  The other thing I need to do is tell it that I want to link a port from the Docker container  to a port on my actual network bridge, so I'm going to say colon 5000, so that's the  host port that I want to bind, and I'm going to bind that to port 5000 on my Docker container,  and then I just say local slash hello NDC, and that's just going to start that up, and  that's now running inside a Docker container there.  Okay, and I can go back over to here, and I can go control T local host 5000, and there  is the same application running inside a Docker container.  Yay, we've achieved so much, we've gone to exactly the same address, and exactly the  same thing has happened.  Don't worry, it does get better, I promise.  Right.  So, first thing, I don't want to have to run that whole build process every time I do a  build.  Okay, I don't want it to have to do the Danoo restore, and people who do node applications  and so forth have found ways around this, and one of the things you can do is you can  copy project.json into your app directory, and then run Danoo restore, and then copy  the rest of the files on, and then build the application from that.  When you say Docker build, it works out what's changed, and so if project.json hasn't changed,  it will start from the image where it had already done that last time.  Okay?  That makes things a lot quicker, but it doesn't make them particularly quick all the time.  And the thing is, if I can just find, there we go, that's the official core CLR image,  so at the moment it's got dash core CLR on the end.  By the time this goes actual 1.0 final, final, final, I suspect that the default will be core  CLR, and you'll have to expressly say you want mono.  But yeah, so you've got your Docker file there, which looks like that.  We've already looked at that.  But to save time, the thing is, when you write a node application, everything has to go into  your node modules folder inside the actual application itself. .NET, ASP.NET 5 doesn't work like that.  It actually puts the packages into a shared location, which is common, so across all the  different things.  It's versioned.  It's sort of a bit like the GAC, but it's not.  For a start, it doesn't write a whole bunch of GUIDs into the registry as part of putting  a file in there.  It is just a folder.  But if I say install Microsoft.asp.NET.MVC and all its dependencies, it goes into a  shared location.  The next time I say to new restore, it just goes, I've got it cached.  What I've got is CloudLens images, dnx Docker, and so I've grabbed myself a project.json from  a Yeoman output.  I've taken out the dnx core 50 line there, and then I've basically just got a Docker  file here that goes from Microsoft's base image, copies my project.json file into the  temp directory, and runs to new restore.  That pulls all those packages down into the images slash root slash dot dnx slash packages,  and then I delete the project.json files and I set the work to back to slash where it should  be, and I've created an image that has already got the most common packages and all the system  dot run time and everything else pre-installed into it.  If I go back to my Docker image here, and I'm just going to change this, so I have a  Docker repository as well.  It's called CloudLens, and I have published my pre-restored image up there as just ASP.NET  colon 1.0.0-rc1.  If I save that, and we'll go back to here, so you can see that was showing the output  from my application there, and I'm going to just come down here.  Docker build.  This is going from this Docker file, but this is using my pre-restored image.  This is on the Docker hub, and you are perfectly free.  There's no clever licensing or everything.  If you want to use cloudlens slash ASP.NET as your base image, feel free to do that.  If you want to copy the Docker file from my repo on GitHub and adapt it, or maybe add  like newtonsoft.json or something to the project.json file, you're absolutely free  to do that as well.  But now, when we do... oh, God.  I'm pretty sure that's what I called it.  Never mind, we'll just say latest because it's the same thing.  There you go.  That's pulling that down.  That's pulling my thing from the image there.  I almost don't want to let that finish.  Right.  You come here, hub.docker.com slash cloudlens.  Build details.  Oh, no, I did put... I left final on there.  There we go.  That'll make life a lot easier.  Right.  1.0.0-rc1-final.  Okay.  And we'll start that again because I do already have that on my machine.  There we go.  And so you see, that's just used the cache built into that Docker image.  So that runs incredibly quickly.  And I don't have to worry about that taking ages every single time.  So that's quite cool, right?  That saves a lot of time.  And then I could run that and we'd still be at exactly the same point as before.  Okay.  Let's not do that because that's not a good use of anybody's time.  And whilst I might not care about yours, I do care about mine.  No, wait, I got that the wrong way around.  Sorry.  So, yeah.  When you're actually sat at your desk, when you go back to work and say, we need to do  everything in ASP and F5 and Docker, because Mark Rendell said so.  And they say, right, there you go.  And you sit down.  If you, you know, even with a kind of pre-filled image, that process has gone from F5 Internet  Explorer opens, you close Internet Explorer, you go back, you change the browser to Google  Chrome and you press F5 again, and it just launches and you get that nice flow there.  This is going to slow that flow down a lot.  And generally, even if you're not working on Docker, you still have to kind of go out  and stop the process and restart it every time you change some code.  Node has something called Nodemon and various other things that just check to see if any  of the files change.  And if they do, it restarts the process.  And now on ASP and F5, we have DNX-watch, which is almost certainly going to change to.NET-watch,  but never mind.  And that does the same thing.  You say DNX-watch in a folder, and it watches the code that's running.  And if you change anything and save it, it just stops the process and restarts it.  And so you go back to the browser and hit F5, and it reloads the page using the new code.  And so as well as creating a preloaded ASP-NET container, I created a DNX-watch container,  and that looks like...  Where are we?  I quite clearly closed that.  Right.  So the image for that is here.  And again, this is on, so you can just do cloudlens slash DNX-watch and pull this down  as well.  But if I do the cat docker file...  So yeah, this is a bit more interesting.  So what we've got here is the same thing up at the top there to save it having to do the  actual reload every single time.  But then I've added some extra variables in to say what the DNX version is and what the  user home is, and then we're going to install the DNX-watcher there.  So that's...  It's a Microsoft package.  And in the same way as you can do NPM install minus G, you can say Danoo commands install  to install something that's actually supposed to be run from the command line.  Then, and this is the fun bit, we declare a volume in our docker container.  So a volume is a mount point, effectively, in the docker container.  It's saying I am exposing this volume and you can mount something onto it, and also,  if you want to, you can see it from other containers.  So to run my application, my HelloNDC application, using that, I say escape-dnx-watch.  Yeah, there we go.  I love bash.  So this is my new docker run command.  So I'm not actually...  I don't need a docker file at all to use this.  It doesn't need its own docker file because that DNX-watch image will work with anything.  And you can see that I'm using dash e to set an environment variable.  That's telling it where my project is.  And then I've got dash v and I'm setting the present working directory and mounting that  to the slash project volume inside this container.  That won't actually work because I've broken some rules on there, but it's time to jump  in to the project that I prepared earlier.  So let's just shut that down and we'll go out of here and into demo.  All right, and we'll start from here.  Okay.  So here is the demo application that I prepared earlier.  This is called micro stuff.  And this will work perfectly if I run this here.  And okay.  Hopefully.  This is having to install.  So part of what it does as it starts up is it runs an install.  And I'm just going to make sure that I can see.  Nope.  Okay.  Sometimes, you just have to restart your entire network stack.  There we go.  That would have been so much harder on Windows.  That would have been please bear with me while I reboot Windows.  Okay.  So let's go back over to where I was doing that and we'll try that again.  Right.  There we go.  That's done the restore properly now.  And that's going and it's getting newtonsoft.jsonassystem.net.http, which are the additional dependencies  that I have in this application.  And now that's running there.  So the fun thing now, okay, is if I go to here, if I hit F5 again.  That's just going to display exactly the same stuff.  But if we go and look in my home controller, what I've done here is I have parameterized  all those banners in that carousel at the top so that they're data driven in this application.  I didn't manage to get this uploaded to GitHub because I don't know if you've used WiFi and  tried to do a Git push.  It's not good.  It doesn't like it.  But I will push this and do the thing.  But yes, you can see here that I have put the text and everything for these banners  into code rather than into the CSHTML.  If you change CSHTML in here, F5, it will just rebuild it because RAZER is good like  that.  But if you change your code, then things are different.  So if I go learn, that's it.  We'll do that.  I'm going to go up to here and I'm going to say learn how to run ASP.NET apps or learn  how to ASP.NET apps.  Run ASP.NET apps in Docker.  Okay?  Save that.  If we go back to here, you can see that you've got the file changed.  This is inside the Docker container.  The DNX has picked up the fact that my mounted folder, which is mounted on a volume in the  Docker container, something's changed and it's restarted the application.  If I go back to here and do that and hit F5 and it refreshes and it says, there you go,  learn how to run ASP.NET apps in Docker and for the people at the back, yes, it does.  Okay?  So that's good.  We can start our application running in Docker and we can make changes to it and we can save  it and we don't need to keep rebuilding our Docker container.  So we're getting somewhere.  This is already quite good.  There's my slides.  Okay.  But the question is, why would you want to have the application running inside Docker  if you're on your local machine and you don't need that?  So there are various reasons why you might do this.  One of the reasons I do it is because the new.NET stack, the stuff that they were talking  about, David Fowler and Damian Edwards have been talking about, where the DNU and DNX  have been replaced by.NET.  At the moment, you can run it on Windows and you can run it on Mac and you can run it on  Ubuntu 14.04 and you can't run it on any other flavor of Linux at all, which means  I can't run it on my Arch Linux laptop and I'm buggered if I'm putting Ubuntu 14.04  as the actual operating system on my laptop, but I can use the Ubuntu 14.04 base image  and I can run the.NET stuff inside that.  So that's one use for it.  But the other use for it is that, oh, don't ask about debugging inside Docker.  It always goes, what's the debugging story inside Docker containers?  And I just say it's a very short story and it doesn't end with and they all lived happily  ever after.  You can't do it yet.  You probably will be able to at some point, if you ask that question, I will rip your  arm off and beat you to death with a bloody end.  So yes.  What is the story outside of Docker?  Actually at the moment, off Windows, it's the same very short story with an unhappy ending,  but they are working on it.  The problem is that.NET and Mono and.NET Core had a completely different set of ideas  about what a PDB should look like.  And then they all got together and went, how about we standardize on this?  And funnily enough, it was the Mono people who had to do the most work.  Odd that.  So yes, they have come to an agreement and it's going to get better and you can do remote  attaching and so forth.  It's going to get there.  Once you can do remote attaching, you should be able to just open an additional port on  your Docker container and you should be able to debug stuff running in Docker containers.  Okay.  So that's kind of fun.  But the other thing that I've done, when you get into Docker, when you start thinking  in terms of running stuff in containers, deploying becomes a lot easier.  Making your stuff becomes a lot easier and all that crap that Martin Fowler has been  coming out with about microservices suddenly makes a lot more sense.  When something is literally just a matter of building an image, pushing it up to your  machine and starting it and then taking the old one down, you kind of go, it's not such  a big thing.  So I'm going to make lots of microservices.  So CloudLens, which, so Zudio, it works with Azure Storage.  It works with blobs and tables and queues and files and analytics and all these different  things.  What's one big application?  It's now, there are like two applications for each area.  So I have a blobs container and a tables container and a base container and all sorts of stuff.  And so the thing runs and it uses multiple domains and cores and it's all great.  And if you make a request against blobs, it sends it to a specific service in that data  center and everything else.  Which is an absolute sod, the problem with microservices is that they're really difficult  to develop because you have to have all these microservices running on your machine or you  have to have a kind of set of development shadow microservices that you can run against.  Microservices with Docker is a lot easier and I've been working on something during the  day for my customer at the moment where we are using Kafka, the kind of distributed Java  message bus thing and we're using a Mongo database and there's lots of different pieces  and it's like eight Docker containers that we drag up in order to do this.  And you don't bring them all up one at a time and you don't write shell scripts.  We have something called Docker compose and compose, you define your entire setup in a  YAML file and then you say Docker compose up and it just brings up however many Docker  containers you specified and sticks them all together.  And so I can put all the different projects that make up all the different backend services  for Cloud Lens into a Docker compose.YML file and I can make that run all at the same time  and I can take it all down at the same time and I can clean them all up at the same time  and everything else.  So let's take a look at what a Docker compose file looks like.  Right.  So this is Docker compose, I'll make that as big as I can.  That's it.  Can you see at the back?  I can go probably one more and do a bit of scroll.  You're all right.  Good.  So what we've got here, ignore that top one just for a minute.  We've got microstuff and within that I've said build.  So my first property there is build and that's saying to Docker compose, use Docker to build  the Docker file that is in SRC slash microstuff.  When you run the container, give it the name microstuff and link it to carousel and then  down at the bottom we've got carousel here which is building something else and giving  it a different name.  And these are both ASP and net applications.  I haven't changed anything at all.  They both run on port 5000 and I can't bind port 5000 from two containers to the same  port on my local box and actually I've got sub-domains and all sorts of stuff going on  here.  So what I really want to do is to get these things working with proper domains.  The other reason that's incredibly useful is when you're doing Windows Live or Microsoft  account authentication which refuses to let you put a local host URL as the callback.  So I have microstuff.io that's just pointing to local host and star.microsoft.io, microstuff.io  is pointing to local host.  The thing up at the top is possibly the single most useful Docker image since the DB and Weezy  base image.  It's magical.  What that does, so that's using an image, J wilder is this guy who just does amazing  Docker-y things.  And that, it runs Nginx and it's exposed so we would link port 80 inside there which is  what Nginx is running on to port 80 on the local machine.  You normally couldn't do that but the Docker demon service that's running on Linux and  taking care of all this is running with super useful permissions so it can bind stuff to  port 80.  And then the volume that we're mounting there, we're taking our Docker.soc which is the Unix  domain socket that the demon uses to accept commands and push his events out on and we're  mounting that into a Docker container.  So the container is actually talking to the Docker process that is running the container  which is just wonderfully meta.  And once we've done that, it just sits there and it says to the Docker process, tell me  when a container starts and the Docker process, oh, I started a container and it's called  carousel.  And it goes and it says, can I see the details for that carousel?  In particular, I would like to know what ports it exposes and I would like to know, does  it have a virtual underscore host environment variable that I can see?  And Docker says yes, it does.  And he regenerates the nginx.conf file to point carousel.micrustuff.io host header requests  to that Docker container.  And it does the same thing with micrustuff.io.  So the effect of this is that I can say Docker-compose up.  So recreating carousel, restarting proxy, recreating microstuff.  And once that's up, we'll see the output there.  So Docker-compose, one of the things it does that I love is it colors the output from the  different things, different colors.  And it's random every time.  There may be a parameter you can pass in that controls it.  But yes, so microstuff is green, carousel is blue, and proxy is yellowish.  And now I can go back to my browser thing here and I can say control T and I can type  in microstuff.io and we'll get that pop up there like that.  Oh, look at that.  It's still doing that thing.  It shouldn't be doing that.  Let's just jump back over to here.  We'll shut that down.  So what's happened is that the last time I ran Docker-compose, it built that.  I've kind of ruined my big kittens moment now.  Never mind.  So yes, I shut this down like that.  So I'm going to do Docker-compose build, which will force it to rebuild those images there  like that.  And I haven't gone yellow on this thing yet.  I don't know if I've got like an extra five minutes at the end or you're just really enjoying  the talk or something.  Okay.  It's good.  He's really enjoying the talk.  Right, and then we'll do Docker-compose up again.  Okay.  And let's go back over to here and we'll try doing control F5 on that.  There we go.  Right, back to normal.  Hurry.  So yes, I forget the kittens.  The kittens never happened.  Look into my eyes.  Look into my eyes.  Look around my eyes.  Look around.  Yes.  So yeah, we're back to there.  Right.  Now, so I could change it and I could do Docker-compose build and Docker-compose up and everything,  but that would take far too long.  So let's jump back out to here as well and we'll stop those things like that.  So we're going to MV Docker-compose.yml to Docker-compose.yml.slow and boring.  Okay.  And then we're going to MV Docker-compose.yml.watch to Docker-compose.yml.  Okay.  And then we're going to open this up and we're going to look in here.  So this, I think I might have a slide for this.  Putting it all together.  Yes, there we go.  This is the really good bit.  This is the kind of piesta resistance of the entire talk.  So I showed you DNxWatch, which allows you to do a live reload inside Docker container.  Yeah.  And I showed you Docker-compose, which allows you to bring multiple things up at the same  time.  And so now I'm going to put those two things together.  So in my Docker-compose file, I am saying use the cloud lens slash DNx-watch image.  I'm using the Docker information here to set the DNx project environment variable and I'm  using the virtual host thing there to tell engine x proxy what to call stuff.  And I'm mounting my current folder.  So I've got my volume section there and I'm mounting that into the DNxWatch image container.  And also, I've added a link entry there to say that microstuff needs to be linked to  carousel.  And what that's going to do is it's going to add an entry to the et cetera hosts in  the microstuff container pointing to the IP address of the carousel container.  So I don't have to worry about what its IP address is.  If I say ping carousel from inside microstuff, it will just ping it automatically.  So I can do Docker-compose up there.  Don't have to worry about rebuilds and everything there.  And there you can see that's doing a little bit more work as it brings those up.  But pretty soon we should see it started and it's listening on port 5000 things going there.  So yeah, running DNx-watch, listening on 5000.  And we should see another quick one of those going past there as that one starts up.  Okay.  So I now have my SRC project, all my code is mounted into two Docker containers that are  running on two different URLs into completely separate processes isolated from each other,  only able to communicate over TCP and HTTP and so forth.  And if I go back to my screen here, don't want that one.  That's the one I want.  Right.  So that's still doing basically the same thing.  If I now go into my hello controller here, right, and go back up to the top here, you  can see I've got my var banners equals banners.  I'm going to comment that line out and I'm going to uncomment this line here.  All right.  And this is talking to the carousel microservice.  So there it's using carousel and it knows it's running on port 5000 because it's a  dot net application and they all run on port 5000.  And it's consuming carousel as a microservice.  Okay.  And it's going, I need your API, give me a list of all the banners that I should display  in here.  Okay.  And if I save that and we jump back out and look here, we can see that that's restarting  there and that started.  And then I can go back to my page here and I can say F5.  And it switched across to using the stuff that's sourced from the carousel microservice  because you might have, you know, a content management site or something.  You don't necessarily want to have to redeploy your entire site just because you want to  add a new banner into the carousel or something.  So you have a kind of microservice that drives your carousel from a database or something  and you can switch that around.  But yes, learn how to build lightsabers that kittens can use.  And we do have, we have more links on there as well.  So yes, there are powerful new features in the dark side of the force.  Darth kitten.  So yes.  And that's coming through from there.  And the other fun thing that's happening with that is that if we go to the banners controller,  so this is the API controller in the carousel application.  Okay.  And you can see here that we specified a host at this point, which is carousel.microstuff.io.  And then we're just using, if you haven't done C sharp 6, that image URL there is using  string interpolation to just put that host property in.  And so this is why I need, although carousel is being consumed internally as a microservice,  it's also exposed with the carousel.microstuff.io domain so that it can serve those static images  out as well.  So I've got the images and the data coming from this microservice, which I can switch  around.  And so this is how I have been working on my application.  When I do Docker compose up, when I'm working with Cloud Lens, it brings up up to a dozen  Docker containers.  I'm running on a fairly old dual core laptop with eight gigs of RAM, and it works, and  it's not painfully slow.  And I can still keep Visual Studio code running at the same time, and I can debug it, and  everything is nice.  So you get this running on something with a bit more oomph.  If you're going to do this on Windows, if you want to use Visual Studio on Windows, then  you can use Visual Studio, mount the directory that you're running into a Linux VM, and then  run all this stuff inside the Linux VM, but use Visual Studio to edit the CS files and  the CS HTML files.  That works great as well, but you do need a quad core machine if you want to do that.  So yes, that is basically the story for running ASPNet 5 on Docker at the moment.  I got the timing just about right.  So that's it.  I hope that gave you a good introduction.  I hope it gave you a taste of what we can do now, now that Microsoft have decided to  open things up and join the rest of the world, and go off and try it.  I will push all the code from this Microsoft service up to GitHub when I get a decent internet  connection.  Any questions?  I think we have run out of time.  So we need to stop, but do feel free to come up and we'll go and sort of grab something.  You can get me on Twitter, markrendl, or mail me mark at rendl.io.  I've got some cards if you want those.  Thank you very much for listening to me enjoy the rest of your conference.
Mark_Rendle_HD_0_5591.png Mark_Rendle_HD_5592_9179.png Mark_Rendle_HD_9180_10415.png Mark_Rendle_HD_10416_13475.png Mark_Rendle_HD_13476_14807.png Mark_Rendle_HD_14808_15635.png Mark_Rendle_HD_15636_15935.png Mark_Rendle_HD_15936_16631.png Mark_Rendle_HD_16632_16763.png Mark_Rendle_HD_16764_18095.png Mark_Rendle_HD_18096_18143.png Mark_Rendle_HD_18144_18191.png Mark_Rendle_HD_18192_18395.png Mark_Rendle_HD_18396_18599.png Mark_Rendle_HD_18600_18911.png Mark_Rendle_HD_19572_19703.png Mark_Rendle_HD_19704_27875.png Mark_Rendle_HD_27876_28715.png Mark_Rendle_HD_28716_28811.png Mark_Rendle_HD_32088_33899.png Mark_Rendle_HD_34332_35447.png Mark_Rendle_HD_35448_35927.png Mark_Rendle_HD_35928_36611.png Mark_Rendle_HD_36612_36695.png Mark_Rendle_HD_36696_37271.png Mark_Rendle_HD_37272_38123.png Mark_Rendle_HD_38268_40343.png Mark_Rendle_HD_40344_40403.png Mark_Rendle_HD_40404_42659.png Mark_Rendle_HD_42660_43643.png Mark_Rendle_HD_43644_43715.png Mark_Rendle_HD_43716_43895.png Mark_Rendle_HD_43896_44231.png Mark_Rendle_HD_44232_45203.png Mark_Rendle_HD_45204_48407.png Mark_Rendle_HD_50340_50975.png Mark_Rendle_HD_50976_51095.png Mark_Rendle_HD_51096_52403.png Mark_Rendle_HD_55020_55331.png Mark_Rendle_HD_57108_57191.png Mark_Rendle_HD_57192_57599.png Mark_Rendle_HD_58224_58283.png Mark_Rendle_HD_58284_58967.png Mark_Rendle_HD_58968_59987.png Mark_Rendle_HD_59988_62483.png Mark_Rendle_HD_62484_65531.png Mark_Rendle_HD_65724_65951.png Mark_Rendle_HD_65952_66095.png Mark_Rendle_HD_66096_66167.png Mark_Rendle_HD_66168_66491.png Mark_Rendle_HD_66492_67127.png Mark_Rendle_HD_67128_68039.png Mark_Rendle_HD_68040_68447.png Mark_Rendle_HD_68532_68795.png Mark_Rendle_HD_68796_69083.png Mark_Rendle_HD_69696_71675.png Mark_Rendle_HD_71676_72107.png Mark_Rendle_HD_72108_72155.png Mark_Rendle_HD_72156_77723.png Mark_Rendle_HD_77724_78395.png Mark_Rendle_HD_78396_79619.png Mark_Rendle_HD_79620_79823.png Mark_Rendle_HD_79824_84971.png Mark_Rendle_HD_84972_86303.png Mark_Rendle_HD_86304_86471.png Mark_Rendle_HD_86472_86651.png Mark_Rendle_HD_86652_86975.png Mark_Rendle_HD_86976_87119.png Mark_Rendle_HD_87120_87263.png Mark_Rendle_HD_87264_87551.png Mark_Rendle_HD_87552_87827.png Mark_Rendle_HD_87828_89375.png Mark_Rendle_HD_89376_89615.png Mark_Rendle_HD_89616_89747.png Mark_Rendle_HD_89748_92543.png Mark_Rendle_HD_92544_92615.png Mark_Rendle_HD_92616_92687.png Mark_Rendle_HD_92688_93347.png Mark_Rendle_HD_93348_93455.png Mark_Rendle_HD_93456_93683.png Mark_Rendle_HD_93744_94691.png Mark_Rendle_HD_96468_100563.png