├── Dockerfile ├── README.md ├── build.sh ├── data ├── package.accept_keywords │ └── blender ├── package.use │ └── blender └── profile │ └── use.stable.mask ├── readme └── images │ ├── blenderDocker.png │ ├── connectedSlave.jpg │ ├── enableBlenderAddon.jpg │ ├── masterInterface.jpg │ └── switchToNetworkRenderer.jpg ├── scripts └── renderServerStartup.py └── systemd ├── blender-master.service └── blender-slave.service /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM gentoo/stage3-amd64 2 | MAINTAINER d3v0x 3 | 4 | RUN emerge-webrsync -v 5 | RUN emerge -DN @world 6 | 7 | RUN rm -f /etc/portage/package.accept_keywords; \ 8 | mkdir /etc/portage/package.accept_keywords 9 | 10 | ADD ./data/package.use/blender /etc/portage/package.use/blender 11 | ADD ./data/package.accept_keywords/blender /etc/portage/package.accept_keywords/blender 12 | ADD ./data/profile/use.stable.mask /etc/portage/profile/use.stable.mask 13 | 14 | RUN emerge media-gfx/blender 15 | RUN rm -rf /usr/portage 16 | 17 | ADD scripts /root/ 18 | CMD blender -b -P /root/renderServerStartup.py 19 | EXPOSE 8000 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blender-render-cluster 2 | A docker based multi machine render setup 3 | 4 | ![Build](https://jenkins.nespithal.com/buildStatus/icon?job=docker-blender-render-cluster) 5 | 6 | ## Warning: This is only possible in Blender < 2.80. For newer Blender releases this plugin is no longer available so this project is deprecated as well. 7 | 8 | ## Quick Start 9 | 10 | ![Alt text](readme/images/blenderDocker.png?raw=true "Blender Docker Logo") 11 | 12 | ### Option 1 - The easy way: Download basic blender image 13 | 14 | $ docker pull d3v0x/blender-render-cluster 15 | 16 | All Blender docker images are tagged since version 2.77a. To get a list of available versions, simply run 17 | 18 | curl https://index.docker.io/v1/repositories/d3v0x/blender-render-cluster/tags 19 | 20 | If you want to download a specific version, type 21 | 22 | docker pull d3v0x/blender-render-cluster:2.77a 23 | 24 | This will download a 2.77a Blender image. 25 | 26 | ### Option 2 - The "hard" way: Build basic blender image 27 | 28 | $ docker build -t blender-render-cluster . 29 | 30 | This will build the latest Blender version from my [Gentoo d3v0x-overlay](https://github.com/d3v0x/d3v0x-overlay) 31 | 32 | ### How to start as master 33 | 34 | $ docker run --name blender_master -e "RENDER_MODE=MASTER" -p 8000:8000 -d d3v0x/blender-render-cluster 35 | 36 | ### How to start and run as slave 37 | 38 | RENDER_MODE will be set to SLAVE by default. You only have to connect/link to the master container. 39 | 40 | $ docker run --name blender_slave --link blender_master:master -e "MASTER_PORT_8000_TCP_ADDR=master" -d d3v0x/blender-render-cluster 41 | 42 | ### Connect new slave to master on other host 43 | 44 | To connect to a master on another server/host you only have to override the environment variable MASTER_PORT_8000_TCP_ADDR and enter the master IP address 45 | 46 | $ docker run -d -e "MASTER_PORT_8000_TCP_ADDR=192.168.178.21" blender_master 47 | 48 | ## Tl;Dr Edition 49 | 50 | Sometimes it takes hours or maybe days to render a final image or an animation. I've got several virtual machines, some idle servers and much unused CPU/GPU. This time I want to show how to set up your own render farm with Blenders Network Renderer and my new Blender Cluster Docker image. 51 | 52 | Requirements: 53 | 54 | * Some servers or virtual machines 55 | * A running docker daemon on each machine 56 | 57 | Before we start we have to set up our master. This machine will maintain all the jobs and is the first contact for the client - your local workstation. 58 | 59 | So lets log in to your server and download my Gentoo based Blender-Render-Cluster image. Of couse you can build the image by yourself if you want. All the sources can be found here at this repo. In this example I want to show how to set up your master and client machines with the prebuild Blender-Render-Cluster image from Docker Hub. You can get some details [here](https://hub.docker.com/r/d3v0x/blender-render-cluster/). 60 | 61 | ### Set up your master 62 | 63 | First of all write down the IP of your master. This is important when we create the slaves on the other machines. Get the IP with 64 | 65 | rin@rusty ~ $ ip addr 66 | [...] 67 | 2: enp2s0: mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 68 | inet 10.0.109.55/24 scope global enp2s0 69 | valid_lft forever preferred_lft forever 70 | [...] 71 | 72 | In this example my IP is 10.0.109.55. 73 | 74 | Now we want to download the image and start up the master. 75 | 76 | rin@rusty ~ $ docker pull d3v0x/blender-render-cluster 77 | 78 | This will take some time and downloads the base image: 79 | 80 | [...] 81 | latest: Pulling from d3v0x/blender-render-cluster 82 | 137d1c317b8c: Downloading [==> ] 10.25 MB/255.7 MB 83 | c2418f02a306: Download complete 84 | 67174dd10795: Download complete 85 | 1c7a34115767: Downloading [========> ] 17.28 MB/98.57 MB 86 | 7ddca3076d93: Download complete 87 | 3ca40110a232: Downloading [===========================> ] 16.85 MB/30.91 MB 88 | f95d0e53882a: Download complete 89 | [...] 90 | 91 | After the download is completed you can see the new blender image in the list 92 | 93 | rin@rusty ~ $ docker images 94 | REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 95 | d3v0x/blender-render-cluster latest 1bbb3cc7d57c 3 hours ago 1.95 GB 96 | 97 | And that's it. Now we can start our master image with 98 | 99 | $ docker run -e "RENDER_MODE=MASTER" -p 8000:8000 -d --name blender_master d3v0x/blender-render-cluster 100 | 101 | The RENDER_MODE environment variable is required because the python script for Blender within the container will set all the configuration of the network render add-on for you. And with this single image you can create master or slave containers based on this environment variable. The default / fallback will set the render mode to __slave__. 102 | 103 | Now you can switch to your webbrowser and go to http://master-ip:8000 and get the web interface of your master render server. Now your master is online. 104 | 105 | ![Alt text](readme/images/masterInterface.jpg?raw=true "Master Web Interface") 106 | 107 | 108 | ### Connect slaves to your master 109 | 110 | After the master is up and running we can start to connect some slaves. Log in to your next virtual machine and download the Docker image again. 111 | 112 | rin@gentoo-vm ~ $ docker pull d3v0x/blender-render-cluster 113 | 114 | But this time we want a slave which connects to the master. So we have to start the container with masters IP address: 115 | 116 | rin@gentoo-vm ~ $ docker run --name blender_slave -d -e "MASTER_PORT_8000_TCP_ADDR=10.0.109.55" d3v0x/blender-render-cluster 117 | 118 | Replace the IP 10.0.109.55 with your masters IP of course. And now you've got your first slave in your list. Check the web interface to get some details. 119 | If your master and the slave is on the same machine you can link both docker containers together instead of overwriting the IP. 120 | 121 | rin@gentoo-vm ~ $ docker run --name blender_slave -d --link blender_master:master -e "MASTER_PORT_8000_TCP_ADDR=master" d3v0x/blender-render-cluster 122 | 123 | Repeat this for all your other machines. 124 | 125 | ![Alt text](readme/images/connectedSlave.jpg?raw=true "Connected Slave") 126 | 127 | ### Set up Blender to render within your new cluster 128 | 129 | And now we want to render our animation within our new rendering network. Before we can send our jobs we have to enable the Blender Add-on "Render: Network Render" within the Blender User Preferences. 130 | 131 | ![Alt text](readme/images/enableBlenderAddon.jpg?raw=true "Enable Blender Addon") 132 | 133 | Next, switch to the Network Render Engine. Be sure you saved you're scene before because the file will be sent to the master. 134 | 135 | ![Alt text](readme/images/switchToNetworkRenderer.jpg?raw=true "Switch to Network Renderer") 136 | 137 | Now you've got many new settings within your Render Section within the Properties Panel. Add your masters IP address and click on refresh at "Slaves Status". You should see all your slaves. 138 | 139 | And that's it. Happy rendering! 140 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | PACKAGE="blender-render-cluster" 6 | 7 | docker build --no-cache -t d3v0x/${PACKAGE} . 8 | 9 | TAG=$(docker run --rm d3v0x/${PACKAGE} ls /var/db/pkg/media-gfx/ | grep blender | sed -e 's/[a-z]*-//') 10 | 11 | docker tag d3v0x/${PACKAGE} d3v0x/${PACKAGE}:${TAG} 12 | 13 | echo "Pushing ${PACKAGE}:${TAG}" 14 | 15 | docker push d3v0x/${PACKAGE} 16 | -------------------------------------------------------------------------------- /data/package.accept_keywords/blender: -------------------------------------------------------------------------------- 1 | media-gfx/blender 2 | 3 | # required by media-gfx/blender-2.79-r1::gentoo[openimageio] 4 | # required by media-gfx/blender (argument) 5 | =media-libs/openimageio-1.8.7 ~amd64 6 | -------------------------------------------------------------------------------- /data/package.use/blender: -------------------------------------------------------------------------------- 1 | media-gfx/blender python_targets_python3_5 headless cycles openimageio tiff 2 | 3 | # required by dev-python/urllib3-1.22::gentoo 4 | # required by dev-python/requests-2.18.4::gentoo 5 | # required by media-gfx/blender-2.78a-r1::gentoo 6 | # required by blender (argument) 7 | >=virtual/python-ipaddress-1.0-r1 python_targets_python3_5 8 | # required by dev-python/cffi-1.9.1::gentoo 9 | # required by dev-python/cryptography-2.0.2::gentoo[python_targets_python3_5,python_targets_python2_7,python_targets_python3_4] 10 | # required by dev-python/pyopenssl-17.2.0::gentoo 11 | # required by dev-python/urllib3-1.22::gentoo 12 | # required by dev-python/requests-2.18.4::gentoo 13 | # required by media-gfx/blender-2.78a-r1::gentoo 14 | # required by blender (argument) 15 | >=dev-python/pycparser-2.14 python_targets_python3_5 16 | # required by media-gfx/blender-2.78a-r1::gentoo 17 | # required by blender (argument) 18 | >=dev-python/requests-2.18.4 python_targets_python3_5 19 | # required by dev-python/cryptography-2.0.2::gentoo 20 | # required by dev-python/pyopenssl-17.2.0::gentoo 21 | # required by dev-python/urllib3-1.22::gentoo 22 | # required by dev-python/requests-2.18.4::gentoo 23 | # required by media-gfx/blender-2.78a-r1::gentoo 24 | # required by blender (argument) 25 | >=dev-python/asn1crypto-0.22.0 python_targets_python3_5 26 | # required by dev-python/requests-2.18.4::gentoo 27 | # required by media-gfx/blender-2.78a-r1::gentoo 28 | # required by blender (argument) 29 | >=dev-python/idna-2.5 python_targets_python3_5 30 | # required by dev-python/pycparser-2.14::gentoo 31 | # required by dev-python/cffi-1.9.1::gentoo 32 | # required by dev-python/cryptography-2.0.2::gentoo[python_targets_python3_5,python_targets_python2_7,python_targets_python3_4] 33 | # required by dev-python/pyopenssl-17.2.0::gentoo 34 | # required by dev-python/urllib3-1.22::gentoo 35 | # required by dev-python/requests-2.18.4::gentoo 36 | # required by media-gfx/blender-2.78a-r1::gentoo 37 | # required by blender (argument) 38 | >=dev-python/ply-3.9 python_targets_python3_5 39 | # required by dev-python/requests-2.18.4::gentoo 40 | # required by media-gfx/blender-2.78a-r1::gentoo 41 | # required by blender (argument) 42 | >=dev-python/chardet-3.0.4 python_targets_python3_5 43 | # required by dev-python/requests-2.18.4::gentoo 44 | # required by media-gfx/blender-2.78a-r1::gentoo 45 | # required by blender (argument) 46 | >=dev-python/urllib3-1.22 python_targets_python3_5 47 | # required by dev-python/requests-2.18.4::gentoo 48 | # required by media-gfx/blender-2.78a-r1::gentoo 49 | # required by blender (argument) 50 | >=dev-python/certifi-2017.7.27.1 python_targets_python3_5 51 | # required by media-gfx/blender-2.78a-r1::gentoo 52 | # required by blender (argument) 53 | >=dev-python/numpy-1.13.3 python_targets_python3_5 54 | # required by dev-python/urllib3-1.22::gentoo 55 | # required by dev-python/requests-2.18.4::gentoo 56 | # required by media-gfx/blender-2.78a-r1::gentoo 57 | # required by blender (argument) 58 | >=dev-python/PySocks-1.6.7 python_targets_python3_5 59 | # required by dev-python/cryptography-2.0.2::gentoo[python_targets_python3_5,python_targets_python2_7,python_targets_python3_4] 60 | # required by dev-python/pyopenssl-17.2.0::gentoo 61 | # required by dev-python/urllib3-1.22::gentoo 62 | # required by dev-python/requests-2.18.4::gentoo 63 | # required by media-gfx/blender-2.78a-r1::gentoo 64 | # required by blender (argument) 65 | >=dev-python/cffi-1.9.1 python_targets_python3_5 66 | # required by dev-python/pyopenssl-17.2.0::gentoo 67 | # required by dev-python/urllib3-1.22::gentoo 68 | # required by dev-python/requests-2.18.4::gentoo 69 | # required by media-gfx/blender-2.78a-r1::gentoo 70 | # required by blender (argument) 71 | >=dev-python/cryptography-2.0.2 python_targets_python3_5 72 | # required by dev-python/pyopenssl-17.2.0::gentoo 73 | # required by dev-python/urllib3-1.22::gentoo 74 | # required by dev-python/requests-2.18.4::gentoo 75 | # required by media-gfx/blender-2.78a-r1::gentoo 76 | # required by blender (argument) 77 | >=dev-python/six-1.10.0 python_targets_python3_5 78 | # required by dev-python/urllib3-1.22::gentoo 79 | # required by dev-python/requests-2.18.4::gentoo 80 | # required by media-gfx/blender-2.78a-r1::gentoo 81 | # required by blender (argument) 82 | >=dev-python/pyopenssl-17.2.0 python_targets_python3_5 83 | # required by dev-python/cryptography-2.0.2::gentoo 84 | # required by dev-python/pyopenssl-17.2.0::gentoo 85 | # required by dev-python/urllib3-1.22::gentoo 86 | # required by dev-python/requests-2.18.4::gentoo 87 | # required by media-gfx/blender-2.78a-r1::gentoo 88 | # required by blender (argument) 89 | >=dev-python/setuptools-36.5.0 python_targets_python3_5 90 | # required by dev-python/cryptography-2.6.1::gentoo 91 | # required by dev-python/urllib3-1.24.2::gentoo 92 | # required by dev-python/requests-2.21.0-r1::gentoo 93 | # required by media-gfx/blender-2.79b-r1::gentoo 94 | # required by media-gfx/blender (argument) 95 | >=virtual/python-enum34-2 python_targets_python3_5 96 | -------------------------------------------------------------------------------- /data/profile/use.stable.mask: -------------------------------------------------------------------------------- 1 | -python_targets_python3_5 2 | -python_single_target_python3_5 3 | -------------------------------------------------------------------------------- /readme/images/blenderDocker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozybuild/docker-blender-render-cluster/4eb68bb28659212f6c431ec84727d5f1d177b139/readme/images/blenderDocker.png -------------------------------------------------------------------------------- /readme/images/connectedSlave.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozybuild/docker-blender-render-cluster/4eb68bb28659212f6c431ec84727d5f1d177b139/readme/images/connectedSlave.jpg -------------------------------------------------------------------------------- /readme/images/enableBlenderAddon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozybuild/docker-blender-render-cluster/4eb68bb28659212f6c431ec84727d5f1d177b139/readme/images/enableBlenderAddon.jpg -------------------------------------------------------------------------------- /readme/images/masterInterface.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozybuild/docker-blender-render-cluster/4eb68bb28659212f6c431ec84727d5f1d177b139/readme/images/masterInterface.jpg -------------------------------------------------------------------------------- /readme/images/switchToNetworkRenderer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cozybuild/docker-blender-render-cluster/4eb68bb28659212f6c431ec84727d5f1d177b139/readme/images/switchToNetworkRenderer.jpg -------------------------------------------------------------------------------- /scripts/renderServerStartup.py: -------------------------------------------------------------------------------- 1 | import os 2 | import bpy.ops 3 | import logging 4 | 5 | logger = logging.getLogger() 6 | logger.setLevel(20) 7 | 8 | renderMode = os.getenv('RENDER_MODE', False) 9 | 10 | masterIp = os.getenv('MASTER_PORT_8000_TCP_ADDR', False) 11 | 12 | if masterIp == False: 13 | masterIp = os.getenv('MASTER_IP', '127.0.0.1') 14 | 15 | if renderMode == False: 16 | logger.warning('No RENDER_MODE environment variable detected. Set default to SLAVE') 17 | renderMode = 'SLAVE' 18 | 19 | logger.info("Set render mode to: " + renderMode) 20 | 21 | bpy.ops.wm.addon_enable(module="netrender") 22 | bpy.context.scene.render.engine = 'NET_RENDER' 23 | 24 | if renderMode == 'MASTER': 25 | bpy.context.scene.network_render.mode = 'RENDER_MASTER' 26 | 27 | if renderMode == 'SLAVE': 28 | bpy.context.scene.network_render.mode = 'RENDER_SLAVE' 29 | bpy.context.scene.network_render.server_address = masterIp 30 | 31 | bpy.ops.render.netclientstart() 32 | -------------------------------------------------------------------------------- /systemd/blender-master.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Blender Master Container 3 | Requires=docker.service 4 | After=docker.service 5 | 6 | [Service] 7 | Restart=always 8 | ExecStart=/usr/bin/docker start -a blender_master 9 | ExecStop=/usr/bin/docker stop -t 2 blender_master 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /systemd/blender-slave.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Blender Slave Container 3 | Requires=docker.service 4 | After=docker.service 5 | 6 | [Service] 7 | Restart=always 8 | ExecStart=/usr/bin/docker start -a blender_slave 9 | ExecStop=/usr/bin/docker stop -t 2 blender_slave 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | --------------------------------------------------------------------------------