Modern Python Projects Transcripts
Chapter: Deployment
Lecture: Let's write a Dockerfile

Login or purchase this course to watch this video and the rest of the course contents.
0:00 Docker uses a configuration file called Docker File. Inside of it, you have to define all the steps to create your image.
0:09 So let's create this file and let me copy paste some code, Let's see what we have here. First, we have to define what image we want to start with.
0:22 You could start with a completely empty image and then install everything yourself. But that's too complicated. On the other hand,
0:28 since we are using FastAPI, you could search for an image that is more appropriate to FastAPI. If you go to the documentation,
0:36 you will see a section deploy of Docker and here you can see that there is an oficial image that will include Uvicorn- gunicorn-fastapi,
0:46 which is pretty much what we want to have. But maybe you're not using FastAPI So instead I want to show you how to start with,
0:54 like a generic basic image. That's why I decided to use a Python image. It's built on top of the DB ambassador,
1:03 and it has the Python installed inside, in general when you're building a Python project using the oficial Python image is a good idea.
1:12 So first we define the image we want to start with. Then we copy just the requirements files inside of it.
1:19 That's because we want to leverage docker caching. Each instruction that you define here creates an intermediate container,
1:26 and if nothing changes, then this container is being reused by Docker caching. So if the requirements.txt file remains unchanged,
1:37 Docker is going to. Reuse the cache container that contains all the installed packages.
1:43 Installing Python dependencies will usually take a couple of seconds, or maybe even a couple of minutes,
1:48 so it's a really good idea to leverage cache in here. Next to create a new user called app.
1:53 This step is completely optional, but it's a good practice from the security point of view, by default. If you don't define a different user,
2:02 Docker will run your container as the root user. If by any chance your container gets hacked and, someone can ssh to it. If they have the root user,
2:12 they will also be able to compromise other containers in the same network and in general
2:17 do bad things. If you are the new user and you run docker containers
2:23 This user, you really limit what potential hacker can do with your Docker container So once we have this appuser,
2:30 we tell Docker that now the working directory is the home directory of this appuser, That way, when we copy something,
2:38 we don't have to add the full path, /home/app /whatever. And then finally, we tell Docker to use this app user from now on.
2:48 So when we run the entry point command at the end, we will be doing this with the APP user.
2:53 Next we expose port 80. This step is actually optional because we'll have to anyway expose some ports when we run Docer,
3:01 run Command. But it's a good idea to list which ports your Docker image is
3:07 going to expose. So people who will be using this image can immediately see that And then finally, we copy the rest of the code inside the container.
3:15 At this point, usually the caching will stop working. So whenever you change, something in one of the files, inside this chapter and you run
3:25 Docker build again, we will use the cache containers all the way up to the step and then from now on Docker will be rebuilding the containers again.
3:35 And the final instruction in our Docker file is the entry point where we specified that we want to run the gunicorn Command with three workers.
3:45 We want to use the Uvicorn worker type. We want to bind the 000 ip with the Port 80 and then we want to run the file.
3:55 With the app function from it, in the next lesson will build this image.

Talk Python's Mastodon Michael Kennedy's Mastodon