With your Dockerfile
defined, you now possess the blueprint for your containerized FastAPI application. The next logical steps are to use this blueprint to construct an actual image and then launch a container based on that image. This process involves two primary Docker commands: docker build
and docker run
.
docker build
The docker build
command is used to create a Docker image from a Dockerfile
and a "context". The context is the set of files located in the specified PATH
or URL
. These files are sent to the Docker daemon during the build process.
The most common syntax you'll use is:
docker build -t <image_name>:<tag> <path_to_build_context>
Let's break down the components:
docker build
: The command itself.-t <image_name>:<tag>
: This option, short for --tag
, is fundamental. It allows you to assign a human-readable name and tag to your image. The format is typically repository_name:tag
.
repository_name
: Often reflects the application name, like fastapi-ml-api
.tag
: Represents a specific version or variant, such as v1.0
, latest
, or a Git commit hash. Using latest
is common but should be used thoughtfully in production environments where specific versions are preferred for reproducibility.-t fastapi-ml-api:latest
or -t mycompany/prediction-service:0.1.0
. Tagging makes it much easier to manage and reference your images later.<path_to_build_context>
: This specifies the location of your Dockerfile
and the application files it needs (like your Python code, requirements.txt
, and potentially model artifacts if copied directly). Most frequently, you'll run this command from the root directory of your project, where the Dockerfile
resides, so the path is simply .
(representing the current directory).When you execute docker build
, the Docker daemon performs the following:
.dockerignore
file (similar to .gitignore
) to exclude them and speed up the build.Dockerfile
.Dockerfile
sequentially. Each instruction typically creates a new layer in the image.Dockerfile
effectively (e.g., copying dependencies and installing them before copying application code that changes more frequently).-t
flag, it also associates your chosen name and tag with this image ID.Example:
Assuming your Dockerfile
is in the current directory along with your application code (main.py
, requirements.txt
, model files, etc.), you would build the image like this:
docker build -t fastapi-ml-api:latest .
You'll see output detailing each step of the build process. Once finished, you can list your local images using docker images
to see fastapi-ml-api
with the latest
tag.
docker run
Now that you have a Docker image containing your FastAPI application, its dependencies, and the ML model, you can create and start a container from it using the docker run
command.
The basic syntax is:
docker run [OPTIONS] <image_name>:<tag>
Here are some essential options ([OPTIONS]
) you'll frequently use:
-p <host_port>:<container_port>
: This is the port mapping option, short for --publish
. It connects a port on your host machine to a port inside the container.
container_port
: The port your application is listening on inside the container (e.g., the port specified in your CMD
instruction like uvicorn main:app --host 0.0.0.0 --port 80
). Using 0.0.0.0
as the host inside the container makes it accessible from outside the container's network namespace.host_port
: The port you will use to access the application from your host machine's browser or tools like curl
.-p 8000:80
maps port 8000 on your host to port 80 inside the container. You would then access your API at http://localhost:8000
.-d
: This runs the container in detached mode, meaning it runs in the background, and your terminal is freed up. Without -d
, your terminal will be attached to the container's output (logs).--name <container_name>
: Assigns a specific name to your running container. If you don't provide one, Docker generates a random name. Naming containers makes them easier to manage (e.g., stop, remove, inspect). Example: --name ml_api_instance_1
.-e <VARIABLE_NAME>=<value>
: Sets an environment variable inside the container. This is a standard way to pass configuration settings to your application, as discussed in the next section. Example: -e MODEL_PATH=/app/models/model.pkl
.--rm
: Automatically removes the container when it exits. Useful for temporary containers or during development to avoid cluttering your system with stopped containers.Example:
To run a container based on the image we built earlier, mapping host port 8000 to container port 80 (assuming your Dockerfile
's CMD
runs Uvicorn on port 80), and running it in detached mode:
docker run -d -p 8000:80 --name my_api fastapi-ml-api:latest
After running this command, Docker will output the unique ID of the newly started container.
Once your container is running (especially in detached mode), you'll want to interact with it:
docker ps
. This lists all currently running containers, showing their IDs, names, image origin, status, ports, etc. Add the -a
flag (docker ps -a
) to see all containers, including stopped ones.docker logs <container_name_or_id>
. Use the -f
flag (docker logs -f <container_name_or_id>
) to follow the logs in real-time.docker stop <container_name_or_id>
.docker start <container_name_or_id>
.docker rm <container_name_or_id>
. You usually need to stop a container before removing it, unless you use the force flag -f
. Using docker run --rm
avoids needing to do this manually.docker run
command above, you should be able to access your API endpoints via http://localhost:8000
(e.g., http://localhost:8000/docs
for the Swagger UI) from your host machine.Using docker build
and docker run
forms the core workflow for transforming your application code and Dockerfile
into a running, isolated service. By building an image, you package the application and all its dependencies, including the specific Python interpreter and the ML model itself. Running this image as a container provides a consistent environment, ensuring your application behaves the same way regardless of where the container is deployed.
© 2025 ApX Machine Learning