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 main.py file.
3:55
With the app function from it, in the next lesson will build this image.