Skip to main content

Custom Snapshot Setup

The SDK also allows us to set up a snapshot with specific instructions and configurations, which can be reused across different instances. Eacg setup step is also cached as a snapshot, meaning that redundant steps are skipped in subsequent runs. This is particularly useful for creating a consistent environment for running tasks or applications.

Example: Docker and Nginx Setup

The example below installs Docker, configures a Docker network, runs two containerized services (a headless Chrome and an NGINX proxy), then creates a final snapshot. An instance is then started using the snapshot, and a browser service is exposed for running a task.

#!/usr/bin/env python3
# Example: Custom Snapshot Setup with Morph Cloud

import os
import asyncio
from morphcloud.api import MorphCloudClient

client = MorphCloudClient()

# Create a snapshot with resource requirements and an identifying digest.
snapshot = client.snapshots.create(
vcpus=1,
memory=4096,
disk_size=8192,
digest="chromebox-1-1",
)
# Chain setup steps; each step is cached.
snapshot = (
snapshot.setup("apt update -y")
.setup("apt install -y docker.io")
.setup("systemctl enable docker")
.setup("systemctl start docker")
.setup("docker network create morph-net")
.setup(
"docker run -d --network morph-net --name headless-chrome "
"zenika/alpine-chrome "
"--headless --no-sandbox --disable-gpu --disable-dev-shm-usage "
"--remote-debugging-port=9222 --remote-debugging-address=0.0.0.0"
)
.setup(
"""\
cat <<'EOF' > /tmp/default.conf
server {
listen 80;
location / {
proxy_pass http://headless-chrome:9222;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host localhost;
}
location /json/ {
proxy_pass http://headless-chrome:9222;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host localhost;
proxy_set_header Accept-Encoding "";
sub_filter_types application/json;
sub_filter_once off;
sub_filter "ws://localhost" "wss://$http_host";
}
}
EOF
"""
)
.setup(
"docker run -d --network morph-net --name chrome-proxy "
"-p 9222:80 "
"-v /tmp/default.conf:/etc/nginx/conf.d/default.conf:ro "
"nginx:alpine"
)
)

# Start an instance using the snapshot.
with client.instances.start(snapshot.id, ttl_seconds=3600) as instance:
url = instance.expose_http_service("browser", 9222)
print(f"Instance ID: {instance.id}")
print(f"Browser service URL: {url}")
browser = Browser(config=BrowserConfig(cdp_url=url))
try:
yield browser
finally:
pass

Explanation

  • Snapshot Creation:
    A snapshot is created with defined resources (vCPUs, memory, disk) and a digest identifier (chromebox-1-1).

  • Chained Setup:
    The .setup() method is chained to perform commands such as updating packages, installing Docker, and configuring services. Each step is cached so that subsequent runs skip steps that haven’t changed.

  • Instance Startup:
    An instance is started with the snapshot, and a browser service is exposed for use. The instance is automatically managed by the context manager.