Deployment guide

OpenCue

Overview

OpenCue is the open-source render management system that turns a pile of machines into a render farm. Artists and pipeline tools submit a job made of layers and frames. OpenCue's scheduler, Cuebot, decides which render node runs which frame, when, with how many cores and how much memory. It tracks every frame through the queue, retries the ones that fail, keeps the logs and reports what the farm is doing in real time.

OpenCue was originally built and run in production at Sony Pictures Imageworks and is now an Academy Software Foundation project. It is designed around the way real productions work: shows, shots and departments, allocations and subscriptions that decide who gets the cores, per-service memory and core minimums, and job dependencies.

This SecureAnyCloud image ships a complete, working single-node farm on one VM. Cuebot, its PostgreSQL database, a render node daemon (RQD), the OpenCue REST gateway and the CueWeb browser interface are all installed, wired together and running when first boot finishes. You can sign in and submit a job straight away, then add your own render nodes as the farm grows. Everything is pinned to the OpenCue v1.19.1 release and verified by checksum at install time.

Upstream publishes six default secrets across its sample configuration, including a sample signing key. None of them exists on this image. Every one is regenerated uniquely on each VM at first boot, and no OpenCue service is allowed to start until that has happened. The CueWeb interface, which upstream ships with no login at all, is placed behind a per-VM credential.

OpenCue is a project of the Academy Software Foundation. This image is produced by SecureAnyCloud and is not affiliated with, endorsed by, or sponsored by the Academy Software Foundation, the OpenCue project or Sony Pictures Imageworks. It ships only the Apache-2.0 licensed open-source OpenCue release.

What you get:

  • OpenCue 1.19.1: Cuebot (the scheduler and dispatcher, gRPC on port 8443), pinned to the release jar and verified by SHA-256
  • PostgreSQL 16 as Cuebot's database, loaded with the OpenCue schema and seed data and bound to the loopback interface
  • RQD 1.19.1 (openrqd, the render node daemon) running on the same VM, so the farm can execute frames out of the box
  • The OpenCue REST gateway, built from the pinned v1.19.1 source and confined to loopback peers by a kernel-level systemd IP filter
  • CueWeb, the browser interface, built from the pinned v1.19.1 source and fronted by nginx on port 80 with HTTP Basic authentication
  • The OpenCue client tools cueadmin, cueman and pycuerun pinned to 1.19.1, plus opencue-submit-demo and opencue-job-status helpers
  • cuebot.service, openrqd.service, opencue-rest-gateway.service, cueweb.service, nginx.service and opencue-firstboot.service as systemd units, enabled and active on boot
  • A unique web interface password, database password, database superuser password, REST gateway signing key and CueWeb session secret, all generated per VM on first boot and never baked into the image
  • A clean, freshly seeded database on first boot, with no default login, no shipped secret, and no prior jobs or render hosts
  • 24/7 SecureAnyCloud support

Prerequisites

You need an active Azure subscription, an SSH key pair, and a VNet with a subnet in the target region.

Standard_B2ms (2 vCPU / 8 GiB RAM) is the recommended size and the smallest that works properly. OpenCue's own seeded service definitions reserve 3.2 GiB of memory per frame for the default and shell services, so a 4 GiB VM cannot book a default frame while also running the scheduler. Size up for more concurrent frames, or keep this VM as the scheduler and add dedicated render nodes.

Configure the network security group (NSG) to allow inbound 22/tcp from your management network and 80/tcp for the web interface, plus 443/tcp once you add TLS.

If you plan to add render nodes or connect the CueGUI desktop client, also allow 8443/tcp and 8444/tcp from your render network only. OpenCue's gRPC farm protocol is unauthenticated by design, so those two ports must never be open to the internet.

Step 1 - Deploy from the Azure Marketplace

Sign in to the Azure Portal, choose Create a resource, search the Marketplace for OpenCue by SecureAnyCloud, and select Create.

On the Basics tab, pick your subscription, resource group, region and size. Under Administrator account, choose SSH public key and paste your key. Under Inbound port rules, allow SSH (22) and HTTP (80).

Select Review + create, then Create.

Step 2 - Deploy from the Azure CLI

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:opencue:default:latest
az vm create \
  --resource-group <your-rg> \
  --name opencue \
  --image sac1647283583153:opencue:default:latest \
  --size Standard_B2ms \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_ed25519.pub \
  --vnet-name <your-vnet> --subnet <your-subnet> \
  --public-ip-sku Standard
az vm open-port --resource-group <your-rg> --name opencue --port 80 --priority 1010

Step 3 - Connect to your VM

Connect to the VM over SSH, using its public IP address:

ssh azureuser@<vm-public-ip>

Step 4 - Confirm the farm is running

On first boot, the image generates every per-VM secret, seeds a clean database and starts the whole stack. Confirm that the six services are active:

systemctl is-active postgresql cuebot openrqd opencue-rest-gateway cueweb nginx

Each one reports active. The public liveness endpoint answers with no credential:

curl -s -o /dev/null -w 'health: HTTP %{http_code}\n' http://127.0.0.1/healthz

That returns health: HTTP 200.

Only two groups of ports are meant to leave the VM: 80 (the authenticated web interface) and, if you add render nodes, the farm ports 8443 and 8444. The database, the CueWeb application server and Cuebot's metrics port stay on the loopback interface:

ss -ltn | grep -E ':(80|3000|5432|8080|8443|8444|8448)\b'

The REST gateway on 8448 binds all interfaces upstream and cannot be told otherwise. Its systemd unit therefore carries a kernel-level IP filter (IPAddressDeny=any with IPAddressAllow=localhost) that drops every non-loopback peer. A connection to it from any address other than 127.0.0.1 never completes.

Step 5 - Verify the password gate

CueWeb can pause, kill and retry any job on the farm, so it is never left open. The image fronts it with nginx HTTP Basic authentication. The password is generated uniquely for this VM on first boot, before the port is ever reachable. Any request without the exact credential is rejected.

Confirm it yourself. This request sends no credential:

curl -s -o /dev/null -w 'no credential: HTTP %{http_code}\n' http://127.0.0.1/

It returns no credential: HTTP 401. Guessable defaults are rejected too:

curl -s -o /dev/null -u admin:admin -w 'admin:admin: HTTP %{http_code}\n' http://127.0.0.1/

Your unique credential authenticates and returns 200. The commands below read the password from the credentials file, so it never appears on screen:

P=$(sudo grep '^OPENCUE_UI_PASSWORD=' /root/opencue-credentials.txt | cut -d= -f2-)
curl -s -o /dev/null -u "<OPENCUE_UI_USER>:$P" -w 'per-VM credential: HTTP %{http_code}\n' http://127.0.0.1/

The credentials file is readable only by root:

sudo stat -c '%a %U:%G' /root/opencue-credentials.txt

It reports 600 root:root. The file holds the web interface user and password, the database passwords, the REST gateway signing key and the CueWeb session secret, all unique to this VM. View it:

sudo cat /root/opencue-credentials.txt

Step 6 - Inspect the render farm

cueadmin is the OpenCue administration CLI. List the render hosts registered with Cuebot. The bundled node reports itself on first boot and should be UP:

cueadmin -lh

The host line shows its cores, memory, the allocation it landed in (local.general) and its state.

Next, list the allocations. Allocations are how you partition the farm between facilities and machine classes:

cueadmin -la

Finally, list the shows, which are the top-level unit of work in OpenCue. The image seeds one show, testing, so you have somewhere to submit to immediately:

cueadmin -ls

Step 7 - Submit a real job to the farm

The image ships a small demo outline that submits three frames of shell work. Run it:

opencue-submit-demo

It prints the job name it launched. Cuebot will not accept a second job with the same name while the first is still pending, so let a run finish before you submit the demo again.

Cuebot books the frames onto the render node within a few seconds. List them with cueman. Each frame shows the render host it was dispatched to and how long it has been running:

sleep 10 cueman -lf testing-demo-opencue_hello_farm

Once the farm has finished, the job leaves the live queue. Use the status helper, which includes finished jobs:

sleep 45 opencue-job-status testing-demo-opencue_hello_farm

It reports succeeded: 3 of 3 total. Every frame's output is captured to a render log on disk, exactly as it would be for a real render. Wait for the first frame's log to appear, then read it:

for i in $(seq 1 30); do
L=$(sudo ls -t /var/log/opencue/frames/testing/demo/logs/*/*.0001-render.rqlog 2>/dev/null | head -1) [ -n "$L" ] && break sleep 5 done
sudo grep -m1 -A2 'rendering frame' "$L"

Step 8 - Open the CueWeb interface

Browse to http://<vm-public-ip>/. Your browser prompts for the credential. Enter the user <OPENCUE_UI_USER> and the password from /root/opencue-credentials.txt.

CueWeb opens on the job monitor. It starts empty by design, because you choose which jobs to watch. Type a show-shot- prefix such as testing-demo- into the search box and pick the job from the list to add it to the monitor.

Each row shows the job state, frames done out of total, start and finish times, and a colour-coded progress bar: green for succeeded, yellow for running, blue for waiting.

Step 9 - Drill into layers and frames

Select the open-in-new icon at the end of a job row to open its breakdown.

The upper table lists the job's layers with the service each one uses, its frame range, and the cores, memory and GPU it reserves per frame. The lower table lists every frame with its status, the render host it was dispatched to, retry count and runtime. Use it to watch a render progress frame by frame.

Step 10 - Read a frame's render log

Select a frame's layer link to open the frame page. It shows the frame's full record (host, cores, runtime and memory high-water mark) above the render log, which is streamed straight from disk. A version selector appears when a frame has been retried.

Use this page to diagnose a failed render without logging in to the render node.

Step 11 - Control the queue

Select one or more jobs with the row checkboxes to enable the queue actions in the toolbar. You can pause and unpause a job, kill it, or eat and retry its dead frames.

These are the day-to-day controls a wrangler uses to keep a farm moving.

Step 12 - Submit your own outlines

Describe jobs in Python with pyoutline. A minimal outline creates an Outline for a show and shot, adds one or more Shell layers with a frame range, and launches it. The demo that ships with the image is at /opt/opencue/examples/hello_farm.py and is a good starting point:

cat /opt/opencue/examples/hello_farm.py

Two things decide whether a frame is ever dispatched. Check both before you write your first outline:

  • Service tags must match the host. Each layer names a service (shell, default, maya, nuke, arnold and so on) and each service carries tags. A frame is only booked on a host whose allocation tag matches. The bundled node is tagged general, so the shell and default services work out of the box. The preprocess and postprocess services are tagged util and wait forever until you tag a host for them.
  • Memory reservations are real. The seeded default, shell, arnold, houdini and prman services each reserve 3.2 GiB per frame. Set memory="256m" (or whatever your render actually needs) on the layer to override it. Otherwise the scheduler holds frames until a host has that much free.

Submit an outline you have written with pycuerun, or run it directly with the bundled Python. Cuebot refuses jobs submitted by root, so submit as your own user:

pycuerun /path/to/your_outline.py

Step 13 - Add render nodes

This VM is a complete farm on its own, but OpenCue is built to scale out. On each additional render machine, install RQD from the same OpenCue release. Point it at this VM's Cuebot with cuebot_endpoints: ["<this-vm-private-ip>:8443"] in its rqd.yaml, then start it.

The node registers itself and appears in cueadmin -lh within a few seconds. From then on, Cuebot dispatches frames to it automatically.

Keep 8443/tcp and 8444/tcp reachable only from your render subnet. OpenCue's farm protocol has no authentication of its own, so network scope is the control.

The CueGUI desktop client is not installed on this image, because a desktop application does not belong on a headless cloud VM. If you prefer it to CueWeb, install it on your own workstation from the same OpenCue release and point it at this VM's Cuebot endpoint.

Step 14 - Rotate the web interface password

The password is your access key to the farm. Set your own password, then reload nginx:

sudo htpasswd -B /etc/opencue/cueweb.htpasswd <OPENCUE_UI_USER>
sudo systemctl reload nginx

Step 15 - Production: your own domain with TLS

For production, front the web interface with your own domain and TLS. Point a DNS record at the VM public IP, install a certificate with your preferred tool (for example Certbot with the nginx plugin) and reload nginx.

Once TLS is in place, restrict inbound access in your NSG to 443/tcp, plus 22/tcp from your management network and 8443/tcp and 8444/tcp from your render subnet only.

Keep the credential confidential. It grants full control of the queue, including the ability to kill running renders.

Support

This image is supported 24/7 by SecureAnyCloud. For help with deployment or configuration, contact support through secureanycloud.com.

Deploy on Azure

Launch OpenCue on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure