- Slow iteration: Each deployment requires a new build and test cycle, which can be time-consuming.
- Limited visibility: Logs and errors are not always easy to debug, especially when running in a remote environment.
- Resource constraints: Your local machine may not have the necessary resources to test your application.
To get a basic dual-mode worker up and running immediately, you can clone this repository and use it as a base.
What you’ll learn
In this tutorial you’ll learn how to:- Set up a project for a dual-mode Serverless worker.
- Create a handler file (
handler.py) that adapts its behavior based on a user-specified environment variable. - Write a startup script (
start.sh) to manage different operational modes. - Build a Docker image designed for flexibility.
- Understand and utilize the “Pod-first” development workflow.
- Deploy and test your worker in both Pod and Serverless environments.
Requirements
- You’ve created a Runpod account.
- You’ve installed Python 3.x and Docker on your local machine and configured them for your command line.
- Basic understanding of Docker concepts and shell scripting.
Step 1: Set up your project structure
First, create a directory for your project and the necessary files. Open your terminal and run the following commands:handler.py: Your Python script with the Runpod handler logic.start.sh: A shell script that will be the entrypoint for your Docker container.Dockerfile: Instructions to build your Docker image.requirements.txt: A file to list Python dependencies.
Step 2: Create the handler.py file
This Python script will contain your core logic. It will check for a user-specified environment variable MODE_TO_RUN to determine whether to run in Pod or Serverless mode.
Add the following code to handler.py:
MODE_TO_RUN = os.getenv("MODE_TO_RUN", "pod"): Reads the mode from an environment variable, defaulting topod.async def handler(event): Your core logic.if mode_to_run == "pod" ... else: This conditional controls what happens when the script is executed directly.- In
podmode, it runs a sample test call to yourhandlerfunction, allowing for quick iteration. - In
serverless” mode, it starts the Runpod Serverless worker.
- In
Step 3: Create the start.sh script
This script will be the entrypoint for your Docker container. It reads the MODE_TO_RUN environment variable and configures the container accordingly.
Add the following code to start.sh:
case $MODE_TO_RUN in ... esac: This structure directs the startup based on the mode.serverlessmode: Executeshandler.py, which then starts the Runpod Serverless worker.execreplaces the shell process with the Python process.podmode: Starts up the JupyterLab server for Pod development, then runssleep infinityto keep the container alive so you can connect to it (e.g., via SSH ordocker exec). You would then manually runpython /app/handler.pyinside the Pod to test your handler logic.
Step 4: Create the Dockerfile
This file defines how to build your Docker image.
Add the following content to Dockerfile:
FROM runpod/pytorch:2.0.1-py3.10-cuda11.8.0-devel-ubuntu22.04: Starts with a Runpod base image that comes with nginx, runpodctl, and other helpful base packages.ARG WORKSPACE_DIR=/workspaceandENV WORKSPACE_DIR=${WORKSPACE_DIR}: Allows the workspace directory to be set at build time.WORKDIR $WORKSPACE_DIR: Sets the working directory to the value ofWORKSPACE_DIR.COPY requirements.txt ./requirements.txtandRUN pip install ...: Installs Python dependencies.COPY . .: Copies all application files into the workspace directory.ENV MODE_TO_RUN="pod": Sets the default operational mode to “pod”. This can be overridden at runtime.CMD ["$WORKSPACE_DIR/start.sh"]: Specifiesstart.shas the command to run when the container starts.
Step 5: Build and push your Docker image
Instead of building and pushing your image via Docker Hub, you can also deploy your worker from a GitHub repository.
1
Build your Docker image
Build your Docker image, replacing The
[YOUR_USERNAME] with your Docker Hub username and choosing a suitable image name:--platform linux/amd64 flag is important for compatibility with Runpod’s infrastructure.2
Push the image to your container registry
You might need to run
docker login first.Step 6: Testing in Pod mode
Now that you’ve finished building our Docker image, let’s explore how you would use the Pod-first development workflow in practice. Deploy the image to a Pod by following these steps:- Go to the Pods page in the Runpod console and click Create Pod.
- Select an appropriate GPU for your workload (see Choose a Pod for guidance).
- Under Pod Template, select Edit Template.
- Under Container Image, enter
[YOUR_USERNAME]/dual-mode-worker:latest. - Under Public Environment Variables, select Add environment variable. Set variable key to
MODE_TO_RUNand the value topod. - Click Set Overrides, then deploy your Pod.
/app and run your handler directly:
handler.py, giving you immediate feedback. You can edit handler.py within the Pod and re-run it for rapid iteration.
Step 7: Deploy to a Serverless endpoint
Once you’re confident with yourhandler.py logic tested in Pod mode, you’re ready to deploy your dual-mode worker to a Serverless endpoint.
- Go to the Serverless section of the Runpod console.
- Click New Endpoint.
- Under Custom Source, select Docker Image, then select Next.
- In the Container Image field, enter your Docker image URL:
docker.io/[YOUR_USERNAME]/dual-mode-worker:latest. - Under Public Environment Variables, set
MODE_TO_RUNtoserverless. - Configure GPU, workers, and other settings as needed.
- Select Create Endpoint.
start.sh will now direct it to run in Serverless mode, starting the runpod.serverless.start worker.
Step 8: Test your endpoint
After deploying your endpoint in to Serverless mode, you can test it with the following steps:- Navigate to your endpoint’s detail page in the Runpod console.
- Click the Requests tab.
- Use the following JSON as test input:
- Click Run.
Explore the Pod-first development workflow
Congratulations! You’ve successfully built, deployed, and tested a dual-mode Serverless worker. Now, let’s explore the recommended iteration process for a Pod-first development workflow:1
Develop using Pod mode
- Deploy your initial Docker image to a Runpod Pod, ensuring
MODE_TO_RUNis set topod(or rely on the Dockerfile default). - Connect to your Pod (via SSH or web terminal).
- Navigate to the
/appdirectory. - As you develop, install any necessary Python packages (
pip install [PACKAGE_NAME]) or system dependencies (apt-get install [PACKAGE_NAME]). - Iterate on your
handler.pyscript. Test your changes frequently by runningpython handler.pydirectly in the Pod’s terminal. This will execute the test harness you defined in theelif MODE_TO_RUN == "pod":block, giving you immediate feedback.
2
Update your Docker image
Once you’re satisfied with a set of changes and have new dependencies:
- Add new Python packages to your
requirements.txtfile. - Add system installation commands (e.g.,
RUN apt-get update && apt-get install -y [PACKAGE_NAME]) to yourDockerfile. - Ensure your updated
handler.pyis saved.
3
Re-deploy and test in Serverless mode
- Re-deploy your worker image to a Serverless endpoint using Docker Hub or GitHub.
- During deployment, ensure that the
MODE_TO_RUNenvironment variable for the endpoint is set toserverless.
For instructions on how to set environment variables during deployment, see Manage endpoints.
- After your endpoint is deployed, you can test it by sending API requests.