What you’ll learn
In this guide, you will learn how to:- Verify your Docker installation.
- Run your first container from an existing image.
- Write a Dockerfile with common instructions.
- Create and configure an entrypoint script.
- Build a custom Docker image.
- Run containers from your custom image.
Requirements
Before starting, you need:- Docker Desktop installed and running (see the overview for installation instructions).
- Basic command-line familiarity.
- A text editor for creating files.
Step 1: Verify Docker installation
First, verify that Docker is installed correctly by checking the version:busybox image:
busybox image (if not already present), starts a container from it, runs the echo command inside the container, and then exits. You should see “Hello from Docker!” printed to your terminal.
Breaking down what happened:
docker run: Creates and starts a new container.busybox: The image to use (automatically pulled from Docker Hub if needed).echo "Hello from Docker!": The command to run inside the container.
Step 2: Create a project directory
Create a new directory for this tutorial and navigate into it:Step 3: Write a Dockerfile
Create a file namedDockerfile (no file extension) with the following content:
busybox is a minimal Linux image with basic utilities. Every Dockerfile must start with a FROM instruction. For real applications, you might use images like python:3.11, node:20, or nvidia/cuda:12.0.0-runtime-ubuntu22.04.
COPY entrypoint.sh /: This copies the entrypoint.sh file from your local directory into the root directory of the container’s filesystem. The COPY instruction is how you add your application code and files to the image.
RUN chmod +x /entrypoint.sh: This executes a command during the image build process to make the script executable. RUN instructions execute commands and save the results as a new layer in the image.
ENTRYPOINT [“/entrypoint.sh”]: This specifies the command that runs when a container starts from this image. Using the JSON array syntax (with brackets and quotes) is recommended as it prevents shell processing quirks.
Step 4: Create the entrypoint script
Create a file namedentrypoint.sh in the same directory:
Understanding entrypoint scripts
An entrypoint script is the command that runs when your container starts. Think of it as the “main” function of your container. Common uses include:- Starting applications: Launch a web server, API, or background process.
- Setup tasks: Initialize databases, check configurations, or set environment variables.
- Processing workflows: Run data processing pipelines or batch jobs.
runpod library and defines your handler function. For example, you might run python handler.py which calls runpod.serverless.start(). For Pods, the entrypoint might start JupyterLab, a training script, or a development environment like VS Code.
While we named this script
entrypoint.sh, you’ll see various naming conventions in Docker projects:start.shdocker-entrypoint.shrun.shcmd.sh
/scripts or /app directory, depending on the project structure.Step 5: Build the image
Now build a Docker image from your Dockerfile:docker build: Initiates the image build process.-t my-time-image: Tags the image with a name for easy reference. Without a tag, you’d have to use the image ID..: Specifies the build context (current directory). Docker looks for a Dockerfile here and can access files in this directory.
Why build custom images?
Custom images let you:- Package dependencies: Install specific libraries, frameworks, or tools your application needs.
- Configure environments: Set environment variables, create directories, or configure settings.
- Include application code: Bundle your code so it’s ready to run anywhere.
- Version applications: Tag images with version numbers to track changes over time.
- Ensure consistency: Eliminate “works on my machine” problems by standardizing the environment.
- Serverless workers need images with your handler code, inference libraries, and optionally cached models.
- Pods might need images with specific ML frameworks, CUDA versions, development tools, or custom configurations saved as templates.
Step 6: Run the container
Run a container from your newly built image:Step 7: Experiment with your container
Try a few variations to understand how containers work: Run the container multiple times to see different timestamps:Understanding Dockerfile best practices
As you create more complex Dockerfiles, keep these practices in mind: Use specific base image tags: Instead ofFROM python:3, use FROM python:3.11-slim to ensure consistent builds.
Minimize layers: Combine related RUN commands with && to reduce image size:
RUN command that creates them:
Building for Runpod
When building images for Runpod, keep these platform-specific considerations in mind: Use the correct architecture: Runpod’s infrastructure useslinux/amd64 architecture. If you’re building on an Apple Silicon Mac (ARM64), specify the platform:
-slim or -alpine variants when possible.
Include model caching: For ML models, consider using Runpod’s model caching feature instead of baking large models into your image. This dramatically reduces cold starts and deployment costs.
Configure GPU access: For GPU workloads, ensure your base image includes the correct CUDA version for your framework.
For detailed guidance on creating Dockerfiles for Serverless workers, see creating Dockerfiles for Serverless.
Next steps
Now that you can create Dockerfiles and build images, continue learning: Continue the tutorial series:- Master Docker commands for building, running, and managing containers.
- Learn about data persistence with Docker volumes.
- For Serverless: Deploy your first endpoint and learn about worker deployment.
- For Pods: Run your first Pod and explore connecting to Pods.
- Review creating Dockerfiles for Serverless with production best practices.