What you’ll learn
In this guide you’ll learn how to:- Set up a project for a dual-mode Serverless worker.
- Create a handler that adapts based on an environment variable.
- Write a startup script to manage different operational modes.
- Build a Docker image that works in both Pod and Serverless environments.
- Deploy and test your worker in both environments.
Requirements
- You’ve created a Runpod account.
- You’ve installed Python 3.x and Docker and configured them for your command line.
- Basic understanding of Docker concepts and shell scripting.
Step 1: Set up your project structure
Create a directory for your project and the necessary files: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
This Python script will check for aMODE_TO_RUN environment variable to determine whether to run in Pod or Serverless mode.
Add the following code to handler.py:
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
The start.sh script serves as the entrypoint for your Docker container and manages different operational modes. 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
Create a Dockerfile that includes your handler and startup script:
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
Now you’re ready to build your Docker image and push it to Docker Hub: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:- Navigate to the Pods page in the Runpod console.
- Click Deploy.
- Select your preferred GPU.
- Under Container Image, enter
YOUR_USERNAME/dual-mode-worker:latest. - Under Public Environment Variables, select Add environment variable and add:
- Key:
MODE_TO_RUN - Value:
pod
- Key:
- Click Deploy.
- Connect via the web terminal, JupyterLab, or SSH to test your handler interactively.
- Debug and iterate on your code.
- Test GPU-specific operations.
- Edit
handler.pywithin 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.
- Navigate to the Serverless page in the Runpod console.
- Click New Endpoint.
- Click Import from Docker Registry.
- In the Container Image field, enter your Docker image URL:
docker.io/YOUR_USERNAME/dual-mode-worker:latest, then click Next***. - Under Environment Variables, add:
- Key:
MODE_TO_RUN - Value:
serverless
- Key:
- Configure your endpoint settings (GPU type, workers, etc.).
- Click Create Endpoint.
start.sh will now direct them to run in Serverless mode, using the runpod.serverless.start function to process requests.
Step 8: Test your endpoint
After deploying your endpoint in to Serverless mode, you can test it by sending API requests to your endpoint.- 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.