DjangoCon 2019 - Creating a containerized Django + React + PostgreSQL... by Dan Taylor

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] good afternoon everyone thank you for coming to my talk today so I'm a program manager on our Python developer tools at Microsoft and today's talk is about how you set up a development environment that's running inside of a container and for this talk we'll be building a sample application that's that uses a somewhat common configuration where you have Django rest framework API with a react front end and a Postgres database and to build this application we're going to use just two dependencies I will be using docker and Visual Studio code now if you don't use Visual Studio code you'll still get a lot out of the talk about all the other pieces that here you'll learn a lot about containers and and react and things like that but the neat part because we're using containers you just need these two dependencies if you want to follow along now please don't try and follow along in this room with me that you follow along with the video afterwards I'm going to be live coding here and I don't need we don't need gigabytes of docker downloads to be happening during the talk so appreciate that so what why you know why are you all here that's the talk today many of you who have adopted are thinking about adopting containers in your development or production environment and one of the key benefits of using containers that we hear often is that if it works locally it should work in production because what a container allows you to do is run kind of like a mini operating system with all of your applications dependencies in sort of the containerized environment it's kind of like a lightweight VM running on your machine and that's typically defined with a docker file and you have some tools that will build this container from a docker file put your app inside of that and then run it and then when you run that app it does some things right and then if you deploy that container to production hopefully it will do the same things because all of the environmental factors around your app have been put inside the container now an additional benefit that comes with containers you can use containers to acquire development dependencies so if you need a database a Redis cache or you know a celery worker or a bunch of other micro services that your application depends upon you can throw a bunch of those into a docker compose file and you can use docker to build a set of containers that you can have locally so it makes it really easy to create a lot of the complex development environments that we have to work with today now one of the one of the problems that gets introduced when using containers is that boundary that container boundary it's a different operating system it causes many issues for tools it's really hard to actually productively edit debug tests do all the things that you normally want to do when you're working on code so for example you you have to typically you might need to rebuild the container every time you make a code change autocomplete might not work if you don't have the Python packages installed on your host operating system which I'll call the local machine and then you know your debugger might not be set up to run the app in the container and you know for example your testing framework not might not be in the container because these are the things that your app doesn't need during production to run so typically what what you would do is you'd create a different container definition for local development and the thing that I'm going to be talking about today is actually developing fully inside of the container where some portion of your IDE is actually running inside the container environment where you'll have like your editor UI talking to some back-end running in the container and that backends working directly with the code the app in the development of dependencies so that allows you to work a lot a lot faster more productive without sacrificing all the tools that you're used to when you're developing so to make this concrete I'm just going to start off with a very low-tech example I'm gonna create a new containerized dev box just from scratch here by running some docker commands so with darker you can you can pull down a container just by typing duck or run and we'll say I want to run a bash prompt so I'll type - IT is a run interactive and we'll give this new container a name Python dev box and we'll base it off of the standard Python image that's available on docker hub so you can use any in the image here if you wanted a different version of Python you could say Python 3.6 and then when that container starts up we just want to run bash so there we go I've got you know I've got a development container I can I'm running on a Windows machine but I've got a bash prompt here so let's actually install some tools it's just for fun let's so we can run apt-get and then apt-get install vim so I'll put some BIM in here well we were having some serious fun so it's going to pull the packages down and then we'll install them and then we'll let's write a little simple piece of code we'll go and create a new folder for our app and then we'll then hello dot P Y and then press I to insert some code here let's say hello jinguk on and then we'll print that message and then escape : w enter : Q I love him okay so we can we can run that with pythons installed in this container we can get a little python Ruppel if we wanted to done that I don't know what I typed yeah good thing I've got a backup this is like the one part of my talk that never messed up when I practiced all right we'll just restart that hello Django Khan and print that message and we can actually even debug this running inside of the container we can use P DB which is the command line debugger built into Python so I'll run Python - MP DB so that will start the PDB module and we'll debug the file hello PA so there were stopped on our line of code hello Jango Khan we can step over we can inspect that variable and we can step over and we can see it prints out the message all right so that's our nice little deaf container however there's some problems with that right so we have to remember all these docker commands I'm not really much of a command-line person and so we're limited only to command-line developer tools and in this case with this simple primitive setup the the code will disappear as soon as the container stops because containers are kind of immutable they get created one way and then right with with just how configured this if I got a website running in the container the ports aren't exposed so those are all additional things that I would need to do to make this better so to solve a lot of those problems I'm going to show you how we can use the Visual Studio code to get a full-featured development environment without sacrificing all the things that were used to so if you're not familiar with with Visual Studio code it's a free cross-platform and open source editor for Microsoft and it's fast in light-weight and it's has support for multiple languages that are enabled through a rich extension ecosystem and it has built-in support for JavaScript and typescript and you get the standard features that you would expect from an editor within telephones debugging source control and then for Python there's a Python extension that's developed by my team that adds the Python support for those same features like intellisense debugging linting testing refactoring and this is the the most popular extension for the views code marketplace so there's a lot of Python developers that that are using this tool and just so you know it's developed in the open on github and we put out a new release every month if you if you follow our blog if you you can stay up to date with all the new stuff that's coming out so the the key reason I'm talking about Visual Studio code it has some unique benefits for this particular scenario there's a it has a unique architecture that actually enables a fully featured just like local development experience so Visual Studio code is built on top of electron and it's written in JavaScript and HTML so it's always had this inherent client-server model where the back end all the guts of the escola ran as a server in the UI ran as a separate process that's what makes it nice and fast so for we we announce remote development for 4 vs code at PyCon back in May and this in this case what we do is we take that back-end we run it in a different machine so it can run on a remote SSH VM and in this case it's running inside of the container so you have all of the UI just kind of transparently works and we'll show what that means in a second so one of the benefits of this approach is that you can quickly create or switch between development environments you just clone something open it with vs code and then you could just start working because all of your dependencies are encoded in sort of that docker container environment and so others can really quickly replicate your environment on a different machine and then other tools do have similar features I showed you what vim looked like and then there's a PI tremor also has a remote development support but for this talk I'm gonna be walking through vs code like I said so that's one background so for the rest of the talk what I'm going to walk through is attaching to an existing container and then creating a new development container and then adding a react front-end to the application and then finally building the production version alright so we just created this command-line development environment for from the command prompt let's actually attach to this this dev box that we created with vs code so I'm gonna open visual studio code here so the first thing we need to do is install some extensions alright so if I go to my extensions tab here the first extension that we'll need is we'll need docker which I've already got that installed and this allows us to create and manage docker containers and then for remote development we want to install the remote containers extension so this allows remote development to work with the docker container scenario that I was talking about so once we have those installed there'll be a docker icon on this left activity bar here and that allows us to see all of the containers that we have on our machine the images that we have built locally and any registries that container registries that we're connected to so I can see that there's the two containers my primary and backup one I can just right click on this container and say attach visual studio code so this will start a new instance of visual studio code a new UI and it will install the remote server into that container that I'd built if we look at the details here it's showing us all of the docker commands that it's running it's copying there the server into the container it's gonna I don't know all the things that's doing but it's doing a lot of stuff and but the point is that this is all stuff that you know I didn't really have to think about setup and manage and then once it's finished now this instance of Visual Studio code is fully running inside of this container so anytime I do anything I would normally do with Visual Studio code like open a terminal and now I get a bash prompt because that's that's running in that same container now I don't have any files open because I actually need to open a folder and I also need to install the Python extension so that I can start working with the Python code in this app so I'll go back to my extensions and null search for the python extension this time it's saying install it's asking if I want to install the extension into the container so when I when I click this install button it will install the Python extension like I said into the the container environment and then once that's finished I'll actually open up and now I need to reload vs code but I'm gonna open the folder on the on the container using this open folder button so there's the app folder where I wrote that simple hello dot py script I'll click that and I'll open and so reload will then be escoba then refresh and open that application that folder so when it opens I'll be able to see my files here and I can actually start start coding just give it a second here it's a little bit faster the second time because it doesn't have to do as much so there's that file I wrote from the command line um I can open it I can select my Python interpreter I can I can run this piece of code by going right click run the Python file in terminal I can debug so I can set a breakpoint I can click there and I can go debug start debugging I'll select a Python file and you know I can expect variables and everything just kind of works as I would expect right but it's all running in that that container environment so I've got a bunch of slides here that are more for reading off lines go through them fairly quickly but just a quick recap we installed the docker and remote containers extension and then we right clicked from the docker tab and then attached to the container that we had we installed the Python extension into the container and then we opened a folder and then some debugging so we can run the Python file or or debug the code ok so there's still a few problems with this I attached to an existing container but again I haven't solved the problem where my code will disappear or that I haven't set up port forwarding so I can access websites so the next step we're going to take is we're actually going to use Visual Studio code to create a new development container and and configure it with you know more features that we need to be productive so let me just go back here so to do this I'll I'll close out this container and I'll make a new container folder and what I like to do I like to do code dot from the command line to open this folder up it just runs vs code in the current location so now I'm in this new container folder and to create a new development container I'm going to run a command in vs code so to run a command u you use ctrl shift P or command shift P if you're on a Mac and then then like all of the all the extensions add various commands to this menu so this is where a lot of functionality shows up so I can search here and say add development container configuration files and now that will let me pick from a set of predefined containers that that the vs code team is built so if I search for Python I have a few different versions of Python that I can start with I could use anaconda or mini Conda and then for this talk obviously I want to use the one that has a Python image and a Postgres database so I'll select that and what that's going to do it's going to add a bunch of files to my workspace now this is going to take a minute so I'm going to click the reopen in container as soon as those files exist vs code says ah this is a development container do you want to open this in a container environment so I'll click that reopening container button there and while that's opening I'll just open a new instance of vias code just to walk through some of the files that we created so this dev container dot JSON this defines this tells vs code what it's supposed to do with this development container it tells it you know it's it it tells it which file it should use to build the container in this case it's going to use a docker compose file because it's going to build multiple services and then it says which service do you want vs code to attach to vs code will only attach to one of the containers that I'm running and then you know where do you want them out the workspace and then you can include additional settings that only apply to this development container so for example you know it's that's where the Python path is do I want to turn linting on and then most importantly what extensions do I want to install into the container when it starts up and then and then so if I look at the docker compose file and this is just a pre-built image that that the vs code gives you it has an application service here so this defines the different services that docker compose will build and then so it's my app is defined by this docker file right here and so that's the image that's going to be built when my docker file runs and then that connects to a database which is going to be available on with the name DB on my local network inside of this container and that's just built from a standard Postgres image and I set up a simple password that I can connect to the database with so this container just finished opening well I don't know when it finished opening but it's finished opening and so now I can start working with it I've already got Python installed let me hide some of these so I can get more space back okay that's fine so now I can now let's start scaffolding our django application so first I'm going to create our requirements txt file that's going to include all the Python dependencies I want and I'll put Django in that and then I will install those requirements from my command line um so that will install Django and you notice that was super fast I'm pretty sure that these containers been mapped to two volume mount my my Python package cache so that that doesn't need to be recreated for every container I open so now that we've got Django installed we can run Django admin start project and we'll create a new site in this current folder and then that will give me my my Django application and then I can I can run that but in this case what I want to do is actually when I'm running this because it's running inside of the container and I want to talk to it from outside of the container I need to bind to 0.0.0.0 so that the site is available to external incoming requests so I'm gonna run that on port 8000 I'll get to the migrations in a minute and when I run so this one actually browse yet but I need to because I need to forward a port so I'll run I did ctrl shift P again and I'll say forward port to the container and it will it detected that port 8000 is being listened on so I'll select port 8000 and then I can open the browser and my new Django application will come up so we're off and running okay so next I want to configure this to actually talk to my Postgres database that I have if I actually go back to this container here my Postgres image is running there and just a quick tip you can actually attach a shell to this Postgres container so that if you want to run p sequel commands you can just type p sequel - you Postgres and then this will allow you to describe the tables and you know run your sequel queries so now to connect to my Postgres back-end i just need to change some of my settings here let's collapse that will use the Postgres QL engine and to use that we actually need to install the post crash driver it put that in a requirements that txt and then the database name to use is just Postgres that's the default and then user is also default Postgres and then the host is DB remember that was in our docker compose file as the name of the image or the name on the network that our database will be available on and then finally our super secret password and if someone manages to hack into my machine there welcome to my sample data ok so now when we run this I'll just do a quick so typically if this database didn't already exist you'd have to do a manage py migrate but the migrations have already been applied my data is created and now now I can run server again I'm however this time I'm going to set up the debugger so to set up the debugger with django we want it to always run that manage py migrate or manage people i run server command when we start so i'll go to the debug tab here and i'll click add configuration so this will create a debug configuration that i can use over and over again I'll start with this Django configuration and then I will select so this is just tells it how to launch Django and I'll just add an argument on here that specifies that that local port so now when I start debugging it'll automatically debug my Django app and my development server should be running so we'll go look a host there and if we go to our admin panel I previously ran the create super user command and there we go this is all set up with a Postgres database we have our back-end now I want to add some api's to this so you notice there's some models already built in with django users and groups i'd like to expose those as api's that i can access as a REST API I'll call those from my node back in later so I'm going to switch to a different container that I've already added some code to so I'll close this out and if you're switching between multiple containers you may want to come in here and just stop your old ones just because they'll be using the ports that you want so I'll just stop those and then I'll go to a deaf container back-end open this with vs code and then I'll select reopen in container and while that's opening we'll just let's make sure it's actually opening and then I'll go back to some slides I've had enough failure modes on this presentation that I know where it likely to fail okay so just a quick recap of where we are at so far so we created a new dev container using vs code and we did that by running the ad development container configuration files command we selected a pre-existing Python 3 and Postgres container and then we used the Django admin command to start a new site and we ran it on the local IP address and then set up port forwarding and I didn't cover this but one thing that that I did add to the docker compose file was to set up that port forwarding automatically just by adding this this list of ports here said every time I open the container those ports are always exposed and all right come back here I forgot to cover get but I'll get to that later so I've opened this this new dev container here and so to add the API code what I've just done is I followed the Django rest framework tutorial that's that's available at this link and I added the Django rest framework package and I'll just walk you through what that code looks like so I also did Django admin start app back-end to create the back-end so basically what what code we added here first we added some serializers that take those users and groups and tell Django rest framework how to serialize those into JSON objects and then we added some views that expose those users and groups as a set of REST API so this defines multiple endpoints for all your different HTTP verbs your get update post put those things and then finally we added those views as we've mounted those views at URL path of API and we've defined this router and registered it so again that's following the standard rest framework tutorial stuff so once we've done that let's go ahead and run the app again and we'll just see what that looks like now and so now if I go API oops now we get the Django rest framework browsable api we can go in here and we can click around look and look at the existing users that we have we can even create users and things like that so if I wanted to create a new user I'll just name them Jeff for whatever reason that's just what I'm feeling right now and we'll click post and then now that users added to the user list okay so we have an API and again that's the code we went through I'm just skipping through it for now and so let's just do while we're here let's just play around with a few more features of us code so first I'll configure tests so if we want to configure tests again I can run another command in my back-end I just have a few tests I've written you using unit tests so ctrl shift P or command shift P will run the configure test command and we support unit test PI tests and nose and unfortunately we don't support Jango unit tests but it's it's on our backlog so I'll select unit tests I'll tell it where those tests are there in the backend folder and they're named test start py so once I do that I can get the testing features of es code running here I can run tests or debug tests from here in code and I can also use a test Explorer to view and and run all of my tests so getting all this all that like I said all of the kind of features that that you have with vs Co they just and currently work here so now was just just for fun let's run the Django rest framework code through black to format it just to see what black things of this code so we'll run the format document command you can also right-click and do format document it will ask me what format I want to use I'll select black net will install black into the the container and now I actually have to run the format document the command again now that I've installed it so black just added some spaces and it changed the the single quotes double quotes okay that's interesting and then like I said I've got my source control here so I can see those changes and and I can actually commit these and and push them when vias code set up the container actually copied my git config file from my desktop so anything that I have on my local machine I can implicitly push to an access from the get with inside the container that's another nice thing that I didn't have to set up alright so let's go ahead and quickly add the react front-end here so let's close out all these files so inside of my docker file I have actually added to this one I've added just some apt-get commands that install node I'm pretty sure I got these from the node website just pasted those in here and then so now this container actually has node installed in it so I can use that to build the react front-end to do that I'm going to use a tool called create react app so create react app is is you know this isn't your your father's react anymore like create so I used to work with react a long time ago before we had create react app and it was just a mess but create react app makes things a lot easier because it packages all of the things that react needs into a very small package so we'll just run the npx create react app command to build a new front-end folder now again this actually takes I think like 10 minutes so I'm just going to cancel out of that and switch to a different container where I've already set this up this is a get up and go get coffee moment so let me close that and then we'll switch over to deaf container front end and then do the same code dot and then we'll just go ahead and reopen that in the container and while that's opening this take about 30 seconds or so I'll just start to look at some of the files that we have so after create react out ran it it created this front-end folder and that basically has my input source for react so react is a say I got to stop those old containers I already will try it again like I've confused myself alright so also a neat tip your recent files lets you pick between whether you want to open something inside of the container if you just want to open the folder normally so I think so this one I'll select I'll reopen this in the dev container okay so that's building so while that's building this one so basically the file is in this source folder those are all compiled into basically from the react syntax into this build folder that we have up here so this is like the this is JSX which is a mix of javascript in HTML it's a it's a react concept it's very divisive a lot of people don't like it but I personally find it really fun to work with but basically this is a new function that just returns a piece of HTML code I've got my CSS here I've got some tests and other things so like I said all this stuff gets compiled into you know mangled JavaScript and things like that and how this works is that there's an index.html which you can't really read here but basically this index dot HTML is a static indexed out HTML that includes all the JavaScript that got built by react and so that's the the page the page that we need to return for our users to be able to view the site and then I think okay so this is started so the first thing I'm going to do is start the node development server with NPM start and so this is going to give me a development server that I can use where I can edit my code on the fly and then the changes will be immediately reflected in the browser and but it won't this one actually build those files that I was talking about this is just for for local development and this also takes a minute to get kicked off so while that's running I'll just do a quick recap so we added the note to the image by adding these lines to the docker file we ran the create react app command which which generated that folder structure over there and our server is almost ready I'll get my browser going so this server is going to start on port 3000 and in this case this right now this isn't connected at all to my Django application this is just a node development server that's going to serve up some HTML for me so and the reason that I want that is that I can come in to my source folder my app KS and I can say well this changed some of this HTML code that says you know hello Django Khan I'm not very creative today and if that's all working correctly it should its recompiling and then the updates show up in my browser ok so I'm gonna switch this code over to another branch where I've written a little bit of code to call my back-end API the users API ok just throw away my changes before I switch branches so I'll switch over to that branch which has added a little bit of code to this API call hopefully ok so walking through this code a little bit so we just added a few things here so the way reactor works it's a unidirectional rendering thing you have some state and you have a render call that will just generate your HTML based on what that state is so for what we're gonna do here we're going to define a user's variable so we're gonna get the users from our API we're going to store it in this users variable so this initializes users and asset users call by the way this is I'm using the new react hooks that were recently released so this doesn't look like react has in the past it's actually a little bit cleaner so then I'll have this use effect call which which will get called when the page loads and that will fire off an API call to the backend to get my API users that will then return JSON and with that JSON I'll execute the set user's call which I've defined up here so that will update the state of my app and then when that state gets updated this render call will happen and it will use the users state here to generate a list of paragraphs which will show the users and the user email alright so that so this is these curly braces allow you to insert a little bit of JavaScript code and then that JavaScript code can generate HTML it's kind of confusing but I I like it so with that update this time let's go ahead and do NPM run build ah this is my favorite bug that I've come across and prepping for this talk to fix this bug I just go CD dot dot and then CD back into the folder and then it works cool so that's that's going to build with that's going to build the HTML and JavaScript that I have up in this build folder here and it should finish in a second oh and so while that's building I actually need to add a URL and endpoint they'll return the index.html so so now Django is going to serve up my react app I'm not going to use the note development server so to make that work what I do is I have I define a new index view and that basically just returns the the index.html from my front-end folder and in my settings the other important thing that I have to do in my settings is add this front-end folder to my static files list so there's so there I define the react app der and then I add the build static folder to the static files lifts that Django is able to find and the reason I do that is because this front-end folder has no Python code in it there's no Django application or anything associated with that so we just need to tell our back-end to return it so now that we've got that we can again we can run our back-end and we should see a new updated app and I'm apologize for the text wrapping okay so there we go we are react app it gets the API called it's showing us the list of users that we have in our database so that's kind of the basic application so again for the dev server we needed to add port 3000 to the map mapping and then we were able to edit code and reload and then another thing that that we that I've done here is in the package.json file i've i added this proxy command so that when i'm using when i am using the development server if there's any API calls that it doesn't recognize it'll just forward those on to the backend the django back-end API so that's just something you need to do for local development to make this setup work okay and then that's the code this is all for reading offline if you want it to follow through okay so now let's build a production version of this application so as I've said before this is all for purposes of making my life easier as a developer I can edit code and do all those things when I published a production I want to remove all these things that I have from the container and build something that's production ready in particular when I'm running manage Pui run server this web server won't handle production workload if you throw a load test at this it might actually just like hang and you know things like that so - so now I actually want to exit the development container and to do that I'm going to run another command called reopen locally so when I run reopen locally that just takes me outside of the dev container and actually I'll hit close here so before I do this I'm going to stop my my container so that the ports don't get used up okay and so I'm going to switch to another branch where I've added a new set of docker file isn't docker compose file so I'll switch to the production branch here and so here I've got these files the Ducker compose and docker file that I'm going to use to build my production image now there's a few small differences here so in this case I still have a local database I can use for testing but in this case I've tagged the image with the name of the container registry that I want to push it to when I'm done and then also I have it pulling environment variables from a dot M file and so this allows me to put passwords and connection strings into a file that is in my get ignore and will not get checked in and so I'm not putting any of that information into code and I have this repo comes with sample M sample where it's got you know here's the the template to fill out and I can use this I can just say CPM sample to dot F and then I'll start I'll start to build this I can actually right click and just say compose up and that will build that docker compose file and it will it will run the the containers in it so while this is building I'll keep explaining some of the different things that I've put into these darker files so in this case for the docker file before I just put everything into one image I installed node into the actual container in this case I'm actually going to to use node just to build the front end and then I'm going to take note out of the container and I'm going to do that using a concept called multistage builds so whenever you see multiple from declarations in a docker file it's using a multi-stage build so this first stage it takes a standard node container then it runs this weird-lookin command to apply all the variables in my den file and it runs the build and then I create a new Python container from from this pre-built image on docker hub in this case I'm using an engine X web server for serving the static files and it uses you the server for hosting the jingle application there's some configuration files but the key thing here is that it actually copies the output of the node build from that front end from the first stage and puts it into the second container so I've got the output of the node build but then I don't end up with a node runtime or any of that stuff in the production application and then the last step that I do is I run a Python manage py collect static so this will take all the static files and put them into a static files folder in my application and this is the static this is the folder that my nginx web server will serve and again I apply the data and file when I'm running that command so that it has the the various variables and I'll explain why in a minute okay so this is probably finished building by now alright so if I'd go to my local host 8,000 of the container that I have so that that's good that that works and then again this is hosted using an engine X web server so if I look at the nginx configuration I've got it says okay hosts all static files basically put slash static to serve static files from the static files folder this is the output of the build and then host my Django application I'm using risk yet the root on port 8000 now I actually have my production secrets in a different end file that I have saved here and I'm not going to show you this file because that's the point and then that one actually defines if you look at the sample file here it actually defines a place to upload static files to using the Django storages library because for production typically I want my files to be available as my static files to be available on a CDN somewhere so I'll start this building again so now that I've changed my data file I have to rebuild everything so what these environment variables will do is while this is building it'll actually when it runs this collect static command it will actually take all the static files and upload them to a natural storage account that I have and that's connected to a CDN and when that's finished I'll just reload the container and to show you what that means so we're almost done here so right now when I'm loading these files all the static files come from my local host so after this is finished building and I also remove the dead end file from the container afterwards because it has my passwords so now that this is finished building when I reload this all of the static files are now surged served from Azure edge net and so that will make those files available distributed all over the world so that it's nice and fast for people who browse my website ok so just quick recap we reopen the folder locally we added some production docker files and we stored our secrets and a dot M file that's an example of what that dot n file looks like with my passwords and key removed and I walked you through what those production docker files and there's the configuration for the U whisky server and that's what picks up the whisky app for Django and then I also have once we have this container built you can easily just deploy it up to Azure just by using the azure app service extension that we have but that's a bonus I don't have time to walk through that today okay so that was a tour of attaching to an existing create container creating a new development container adding a react front-end and then building it for production the slides and code are available at the AKMs link up there that's HTTP colon slash slash akms follow our Python blog for any updates and follow us on Twitter thank you so much all right thank you tin [Music]
Info
Channel: DjangoCon US
Views: 12,970
Rating: undefined out of 5
Keywords: django, djangocon us, djangocon, python, containerized Django, container, React, PostgreSQL, develop
Id: hwHRI59iGlw
Channel Id: undefined
Length: 47min 19sec (2839 seconds)
Published: Fri Oct 18 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.