GCP

    Deploy Operate on Google Cloud

    Operate's Google Cloud image runs as one self-contained VM in your Google Cloud project: the Operate web app and worker stack, with MongoDB and Redis on the same VM. The image holds no App ID or integration credentials. After launch, open the HTTPS address, create the first admin account, then enter your App ID and integrations in Operate.

    The Google Cloud Marketplace listing is not live yet. Contact the Operate team to ask about access.

    Separately, Operate sends a usage record to operatex.dev for billing: your App ID, token counts, timings, and model name. It does not send your logs, records, or code.

    •

    How it works

    The image is Ubuntu 24.04 with Docker Engine and the Compose plugin and a pinned Operate release. A systemd service starts the stack at boot. First boot creates this VM's own database credentials, then starts Operate, then sets up HTTPS. First boot only reports that Operate is ready after an HTTPS check against the VM's external IPv4 passes with a trusted certificate.

    The boot disk must be at least 40 GB, the image's default. Use the machine type and disk sizes the Marketplace listing publishes once it is live.

    Allow web traffic in the VPC

    Give the VM an external IPv4 address. The image reads it from Google Cloud metadata at first boot to get its certificate. Create VPC ingress firewall rules allowing TCP 80 and 443 from the client ranges that need Operate. These VPC rules are separate from the firewall inside the VM. Port 80 is used for certificate setup and the redirect, users open Operate on 443, and port 8080 stays closed to the internet. See Google's firewall guide.

    Limit SSH access

    SSH is TCP 22. Allow it only from the administrator's range, for example 203.0.113.10/32, never from everywhere.

    Recover HTTPS if setup fails

    If the VM had no external IPv4 at first boot, assign one. Confirm the VPC allows 80 and 443, then run:

    bash
    sudo operate tls

    It reads the current address from metadata, updates Caddy's address settings, restarts Caddy, and checks that https://<external-ip>/api/healthcheck returns 200 with a valid certificate. If it fails, check sudo journalctl -u caddy and /var/log/operate-setup.log, fix the cause and run it again. It does not change the database credentials. Do not rerun the first-boot script to recover HTTPS.

    Reserve a static external IPv4 if the address must survive a stop or replacement, and run sudo operate tls again whenever the address changes.

    •

    Data Volume

    Without a separate disk, MongoDB, Redis, cloned repositories and Operate's internal secrets live in Docker volumes on the boot disk. They survive restarts and reboots, but Compute Engine deletes the boot disk with the VM by default, and the data with it.

    A separate Persistent Disk keeps the data outside the boot disk. At first boot, or when you run sudo operate storage, the image formats the disk if it has no file system, mounts it at /mnt/operate-data, moves existing data onto it, and sets OPERATE_DATA_ROOT. Use Persistent Disk, never Local SSD, for this data. The image only uses a disk that the VM reports as a persistent disk, so Local SSD and any disk it cannot identify are left unused.

    Recommended size

    20 GB is the practical minimum and 50 GB is a good starting point for production. Leave room for database growth.

    Attach a disk at launch

    bash
    gcloud compute instances create operate-1 \
      --image-family=operate-marketplace \
      --image-project=PROJECT_ID \
      --boot-disk-size=40GB \
      --create-disk=name=operate-data,size=50GB,type=pd-balanced,device-name=operate-data,auto-delete=no

    Replace PROJECT_ID with the project that publishes the image; auto-delete=no keeps the disk when the VM is deleted.

    Attach a disk after launch

    1. Create a Persistent Disk in the VM's zone.
    2. In the console open Compute Engine > VM instances, select the VM and click Edit.
    3. Under Storage > Additional disks choose + Attach existing disk and pick it.
    4. Set mode Read/write and deletion rule Keep disk.
    5. Set its custom device name to operate-data, then save.

    Google exposes it as /dev/disk/by-id/google-operate-data, a stable name the image uses instead of /dev/sd* or /dev/nvme*. To list device names on the VM, run:

    bash
    ls -1 /dev/disk/by-id/google-* | sed 's|.*/google-||'

    Then run sudo operate storage, which stops Operate, formats the disk only if it has no file system, mounts it, copies existing data, sets OPERATE_DATA_ROOT and restarts, without changing the database credentials. With more than one eligible disk, pass the device name:

    bash
    sudo operate storage operate-data

    Verify the disk is in use

    bash
    # Is the disk mounted?
    mountpoint /mnt/operate-data && df -h /mnt/operate-data
    
    # Is Operate pointed at it?
    grep OPERATE_DATA_ROOT /opt/operate/operate.env
    
    # Is Docker using paths on the disk?
    docker compose --env-file /opt/operate/operate.env -f /opt/operate/app/docker-compose.yml \
      config | grep /mnt/operate-data
    
    # What did the setup script decide?
    cat /var/log/operate-setup.log

    Back up or move the disk

    Keep the disk's deletion rule at Keep disk. Before replacing a VM, stop Operate with sudo systemctl stop operate.service, snapshot the data disk, then start Operate again. See Google's snapshot best practices. The database credentials live in /opt/operate/operate.env on the boot disk, not on the data disk, so save OPERATE_MONGODB_USERNAME, OPERATE_MONGODB_PASSWORD and OPERATE_MONGODB_URI before deleting the old VM.

    Each VM creates fresh MongoDB credentials at first boot, so a moved disk will not connect until the saved values are restored. Boot the replacement without the disk, put the saved values into /opt/operate/operate.env, then attach the disk and run sudo operate storage operate-data. Keep a separate backup until the replacement works.
    •

    Staying current

    bash
    sudo operate update

    The command checks for and installs a newer Operate release. It does not update the VM image or the guest OS.

    •

    Verify

    After first boot reports Operate is ready, open https://<external-ip>/. The getting-started page loads with a trusted certificate and no browser warning. Create the first admin account, enter the App ID and integrations, then follow step 6 of the self-hosted guide to verify an integration. To check the data disk, run the commands in Data Volume; the resolved paths should be under /mnt/operate-data.

    Still stuck? We can handle the full setup for you.

    Talk to us