Part 3: Dockerizing the Blender Server and Orchestrator
In this section, we’ll containerize both the Blender server and orchestrator using Docker. This ensures consistent, portable, and isolated deployments across different environments.
- Understand the benefits of containerization
- Create Dockerfiles for Node.js applications
- Use Docker networks for inter-container communication
- Mount volumes for persistent data
- Build and run Docker containers
- Understand container resource limitations
Why Docker?
Docker provides a way to package and run applications in isolated environments called containers. This approach offers several benefits:
- Consistency: Applications run the same way in any environment (dev, staging, production)
- Portability: Containers can be easily shared and deployed across different systems
- Isolation: Applications and dependencies are separated from the host system
- Scalability: Simplifies scaling by running multiple container instances
- Reproducibility: Dockerfile serves as documentation for the exact environment
Limitations and Considerations
Image Size
Blender is a large application (~500MB+), so the Docker image will be substantial in size. Consider:
- Using
.dockerignoreto exclude unnecessary files - Multi-stage builds for production deployments
- Image layer optimization
Resource Management
Running Blender inside a container requires careful tuning:
- CPU: Docker has configurable CPU limits (Docker CPU Constraints)
- GPU: GPU access requires NVIDIA Container Toolkit (NVIDIA Docker)
- Memory: Set appropriate memory limits to prevent OOM errors
Storage
Ensure Blender files and output directories are properly mounted to access them outside the container.
Note: For this tutorial, Docker is used to demonstrate containerization basics. Production deployments would require additional optimization for Blender’s resource-intensive workloads.
Step 1: Installing Docker
Install Docker for your operating system:
Verify installation:
docker --version
docker run hello-world
Step 2: Update server.js for Docker
Update server.js to use paths that work inside a container:
const port = 3000; // Port to match Dockerfile
// Paths inside the container
const blenderPath = '/usr/bin/blender';
const blendFilePath = '/app/blend/files/splash-pokedstudio.blend';
const outputDir = '/app/output';
Key changes:
blenderPath: Blender location in the containerblendFilePath: Mounted volume path for.blendfilesoutputDir: Mounted volume path for rendered frames
Step 3: Create Docker Network
Create a custom Docker network to enable communication between containers:
docker network create blender-network
This allows containers to communicate using container names as hostnames (e.g., http://blender-server:3000).
Step 4: Dockerfile for the Blender Server
Create a Dockerfile in the server/ directory:
# Use the linuxserver/blender Docker image as the base
FROM linuxserver/blender:latest
# Install Node.js and npm
RUN apt-get update && apt-get install -y \
nodejs \
npm \
&& rm -rf /var/lib/apt/lists/*
# Set the working directory inside the container
WORKDIR /app
# Copy application files into the container
COPY . .
# Install Node.js dependencies
RUN npm install
# Expose the port that your API will run on
EXPOSE 3000
# Override the entrypoint to bypass starting Xvnc and Openbox
ENTRYPOINT []
# Start the Node.js application
CMD ["node", "server.js"]
Dockerfile breakdown:
FROM linuxserver/blender:latest: Base image with Blender pre-installedRUN apt-get install: Install Node.js runtimeWORKDIR /app: Set working directoryCOPY . .: Copy application codeRUN npm install: Install dependenciesEXPOSE 3000: Document the port (doesn’t actually publish it)ENTRYPOINT []: Override base image entrypointCMD ["node", "server.js"]: Start the application
Building the Docker Image
cd server
docker build -t blender-server .
What happens:
- Docker downloads the base image
- Installs Node.js
- Copies your code
- Installs npm dependencies
- Creates a runnable image tagged
blender-server
Running the Container
docker run -p 3000:3000 \
--network blender-network \
--name blender-server \
-v /path/to/blend/files:/app/blend/files \
-v /path/to/output:/app/output \
blender-server
Command breakdown:
-p 3000:3000: Map host port 3000 to container port 3000--network blender-network: Connect to custom network--name blender-server: Name the container-v /path/to/blend/files:/app/blend/files: Mount blend files directory-v /path/to/output:/app/output: Mount output directory
Note: Replace
/path/to/blend/filesand/path/to/outputwith actual paths on your host system. Paths should end with/for directories.
Step 5: Update orchestrator.js for Docker
Update orchestrator.js to use container names instead of localhost:
const NODES = [
'http://blender-server:3000', // Use container name as hostname
];
When containers are on the same Docker network, they can communicate using container names thanks to Docker’s built-in DNS.
Step 6: Dockerfile for the Orchestrator
Create a Dockerfile in the orchestrator/ directory:
# Use the official Node.js image as the base
FROM node:16
# Set the working directory inside the container
WORKDIR /app
# Copy application files into the container
COPY . .
# Install Node.js dependencies
RUN npm install
# Expose the port that your API will run on
EXPOSE 4000
# Start the Node.js application
CMD ["node", "orchestrator.js"]
Why node:16? Unlike the server, the orchestrator doesn’t need Blender, so we use a lightweight Node.js base image.
Building the Docker Image
cd orchestrator
docker build -t orchestrator .
Running the Container
docker run -p 4000:4000 \
--network blender-network \
--name orchestrator \
orchestrator
Testing the Dockerized System
1. Start the Blender Server
docker run -d -p 3000:3000 \
--network blender-network \
--name blender-server \
-v /path/to/blend/files:/app/blend/files \
-v /path/to/output:/app/output \
blender-server
The -d flag runs the container in detached mode (background).
2. Start the Orchestrator
docker run -d -p 4000:4000 \
--network blender-network \
--name orchestrator \
orchestrator
3. Submit a Render Job
curl -X POST http://localhost:4000/render \
-H "Content-Type: application/json" \
-d '{"from": 1, "to": 20}' \
-i
Same curl command as before - but now it’s running in containers!
4. View Container Logs
# Orchestrator logs
docker logs orchestrator
# Blender server logs
docker logs blender-server
5. Stop and Remove Containers
docker stop orchestrator blender-server
docker rm orchestrator blender-server
Docker Networking Diagram
graph TB
Host[Host Machine<br/>localhost:4000]
subgraph "Docker Network: blender-network"
Orch[orchestrator container<br/>Port 4000]
Server[blender-server container<br/>Port 3000]
end
Blend[Mounted Volume<br/>/blend/files]
Output[Mounted Volume<br/>/app/output]
Host -->|Port Mapping<br/>4000:4000| Orch
Orch -->|http://blender-server:3000| Server
Blend -.->|Read| Server
Server -.->|Write| Output
style Host fill:#e1f5ff
style Orch fill:#fff4e1
style Server fill:#e8f5e9
style Blend fill:#f3e5f5
style Output fill:#f3e5f5
Troubleshooting
Container won’t start
docker logs <container-name>
Can’t connect between containers
# Verify both containers are on the same network
docker network inspect blender-network
Volume mount issues
Ensure:
- Paths are absolute (not relative)
- Directories exist on the host
- You have proper permissions
Port already in use
# Find what's using the port
lsof -i :3000
# Or use different ports
docker run -p 3001:3000 ...
Conclusion
You’ve successfully containerized your distributed rendering system! Your setup now has:
- ✅ Dockerized Blender server
- ✅ Dockerized orchestrator
- ✅ Docker network for inter-container communication
- ✅ Volume mounts for persistent data
- ✅ Consistent deployment across environments
Next Steps
In the next section, we’ll use Docker Compose to manage multiple containers with a single configuration file, making deployment even simpler.
💡 See the complete code: examples/part3-docker
Having issues? Open an issue on GitHub