You're viewing a demo portfolio

Join the waitlist
PRSM

deploy_compose

Active

Tool of cloud.redu/mcp

declared in 2.0.0

Deploys a MULTI-CONTAINER app — a repo that ships docker-compose.yml / compose.yaml — onto ONE VM via podman-compose, and exposes one or more services at redu.cloud URLs. Use this instead of deploy_app when the repo is a compose stack. Same prereqs + source modes as deploy_app; always run plan_deploy first. PORT is the HOST port for the exposed service. DB: 'compose' uses the stack's own db container; 'managed' provisions a separate managed Postgres/MySQL/MariaDB VM and appends connection env. For WordPress/WooCommerce cluster intent, do not leave the compose db service/local uploads as state: pass app_profile, cluster_target:true, database:'managed', db_engine:'mariadb' or 'mysql', cluster_media_mode:'media_space', and either media_space_id or create_media_space:true. Redu writes an override file that points the WordPress service at managed DB env and mounts the media space into /var/www/html/wp-content/uploads. Poll get_deployment until ready.

Parameters schema

{
  "type": "object",
  "$schema": "http://json-schema.org/draft-07/schema#",
  "required": [
    "name",
    "keypair_name"
  ],
  "properties": {
    "env": {
      "type": "object",
      "description": "Env vars APPENDED to the compose project's .env (for ${VAR} interpolation). We never rewrite your compose file.",
      "additionalProperties": {
        "type": "string"
      }
    },
    "name": {
      "type": "string",
      "maxLength": 63,
      "minLength": 1,
      "description": "Name for the deployment / VM (lowercase letters, numbers, hyphens)."
    },
    "port": {
      "type": "integer",
      "default": 8080,
      "maximum": 65535,
      "minimum": 1,
      "description": "REQUIRED in practice: the HOST port the exposed service publishes (the LEFT side of its compose `ports:` mapping) — redu health-probes + proxies THIS port, so a wrong value fails the deploy. plan_deploy detects it."
    },
    "repo": {
      "type": "string",
      "format": "uri",
      "description": "GIT MODE: public git repo URL that ships a docker-compose file. Private repo also needs git_token. Omit when using source_token."
    },
    "dname": {
      "type": "string",
      "description": "Custom *.redu.cloud subdomain. For a STABLE, KNOWN-AHEAD URL (needed when the app must be told its OWN url — OAuth callbacks, cookie domain, a frontend that calls its API), generate the FULL auto-gen form yourself: `<label>-<8 lowercase letters/digits>.redu.cloud` (e.g. `myapp-7k2m9x4p.redu.cloud`) — that exact form is used VERBATIM — and wire the app's own URL env to that SAME value. A BARE `<label>.redu.cloud` is NOT used as-is: redu appends a random 8-char suffix for uniqueness, so anything wired to the bare name will NOT match the real URL. Omit to auto-generate (then read the real URL from get_deployment)."
    },
    "redis": {
      "enum": [
        "none",
        "managed"
      ],
      "type": "string",
      "description": "'managed' = a SEPARATE managed Redis VM, auto-provisioned + wired; its REDIS_URL/REDIS_* is APPENDED to the project .env — your compose service must REFERENCE it to use it (we never rewrite your compose file). Omit/'none' to use the stack's own redis container. With 'managed' you do NOT call create_redis."
    },
    "expose": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "port"
        ],
        "properties": {
          "port": {
            "type": "integer",
            "maximum": 65535,
            "minimum": 1
          },
          "dname": {
            "type": "string"
          },
          "service": {
            "type": "string"
          }
        },
        "additionalProperties": false
      },
      "description": "MULTI-SURFACE apps: expose several services, each gets its OWN *.redu.cloud URL. The FIRST entry is the primary one redu health-gates (its port overrides `port`). CRITICAL when one surface must KNOW another's URL (a frontend that calls its API — e.g. Lago's front -> API): GENERATE each surface's dname up front as `<label>-<8 lowercase letters/digits>.redu.cloud` (used VERBATIM) and wire the app's cross-surface URL env (LAGO_API_URL, LAGO_FRONT_URL, FRONTEND_URL, NEXT_PUBLIC_API_URL, …) to those EXACT values. Do NOT use a bare `<label>.redu.cloud` — redu appends a random suffix, so config wired to the bare name breaks."
    },
    "subdir": {
      "type": "string",
      "description": "Directory within the source that contains the compose file (if not at the root)."
    },
    "db_name": {
      "type": "string",
      "description": "DB name for single_vm/managed (default 'app')."
    },
    "db_user": {
      "type": "string",
      "description": "DB user for single_vm/managed (default 'appuser')."
    },
    "git_ref": {
      "type": "string",
      "description": "git mode only: branch/tag/commit (default: the repo's default branch)."
    },
    "service": {
      "type": "string",
      "description": "The compose SERVICE to expose at the public URL (informational; the exposed port is `port`)."
    },
    "database": {
      "enum": [
        "compose",
        "single_vm",
        "managed"
      ],
      "type": "string",
      "description": "DB mode: 'compose' (default) = use the compose file's OWN db service (self-contained, nothing extra provisioned); 'single_vm' = Postgres ON the app VM; 'managed' = a SEPARATE managed-PG/MySQL VM. For single_vm/managed the conn env (DATABASE_URL/PG*/MYSQL_*) is APPENDED to the project .env — your compose service must REFERENCE it (e.g. environment: - DATABASE_URL=${DATABASE_URL}) to actually use it; we never modify your compose file. Choose engine with db_engine."
    },
    "db_engine": {
      "enum": [
        "postgres",
        "mysql",
        "mariadb"
      ],
      "type": "string",
      "description": "managed only: 'postgres' (default) → PG* env; 'mysql'/'mariadb' → MYSQL_* env. mysql/mariadb require database:'managed'."
    },
    "flavor_id": {
      "type": "string",
      "default": "3",
      "minLength": 1,
      "description": "App VM size — from list_flavors. A multi-container stack often wants m1.large+; plan_deploy sizes it."
    },
    "git_token": {
      "type": "string",
      "description": "git mode only: token to clone a PRIVATE repo."
    },
    "db_version": {
      "type": "string",
      "description": "DB version for single_vm/managed (Postgres '16'|'15'|'14'; MySQL '8.0'; MariaDB '11.4')."
    },
    "network_id": {
      "type": "string",
      "minLength": 1,
      "description": "Private network id — auto-selected from check_deploy_prerequisites if omitted."
    },
    "app_profile": {
      "enum": [
        "generic",
        "wordpress",
        "woocommerce"
      ],
      "type": "string",
      "description": "Detected app profile from source inspection. For WordPress/WooCommerce pass wordpress/woocommerce so cluster deploys enforce managed DB + shared media instead of treating local uploads as stateless."
    },
    "compose_file": {
      "type": "string",
      "description": "Path within the source to the compose file (e.g. 'deploy/docker-compose.yml'). Auto-detected (docker-compose.yml / compose.yaml / …) if omitted."
    },
    "db_flavor_id": {
      "type": "string",
      "description": "managed only: the dedicated DB VM size (from list_flavors). Defaults to the app flavor."
    },
    "db_superuser": {
      "type": "boolean",
      "description": "single_vm/managed Postgres: grant the DB user SUPERUSER (dedicated DB VM, so safe)."
    },
    "keypair_name": {
      "type": "string",
      "minLength": 1,
      "description": "REQUIRED. An EXISTING SSH keypair name — from list_keypairs / import_keypair."
    },
    "source_token": {
      "type": "string",
      "minLength": 16,
      "description": "UPLOAD MODE: token from prepare_upload — deploys an uploaded tarball of your LOCAL dir (no git). Omit `repo` when set."
    },
    "db_extensions": {
      "type": "array",
      "items": {
        "enum": [
          "vector",
          "pgvector",
          "postgis",
          "pgaudit",
          "pg_stat_statements",
          "hstore",
          "pg_trgm",
          "uuid-ossp",
          "citext",
          "pgcrypto",
          "ltree",
          "btree_gin",
          "btree_gist"
        ],
        "type": "string"
      },
      "description": "single_vm/managed Postgres: extensions to pre-install (pgvector, postgis, pgaudit, …)."
    },
    "redis_version": {
      "enum": [
        "7",
        "6"
      ],
      "type": "string",
      "description": "managed Redis only: version (default '7')."
    },
    "cluster_target": {
      "type": "boolean",
      "description": "Set TRUE when the user asked to deploy this compose app as an autoscaling cluster. For WordPress/WooCommerce this requires managed MySQL/MariaDB plus media_space/central_media_origin."
    },
    "compose_engine": {
      "enum": [
        "auto",
        "docker",
        "podman"
      ],
      "type": "string",
      "description": "Container engine for the compose build (default: the server's choice, usually podman). Set 'docker' to force the docker engine."
    },
    "media_space_id": {
      "type": "integer",
      "description": "Existing Redu media space id to mount at WordPress wp-content/uploads. Get it from list_media_spaces.",
      "exclusiveMinimum": 0
    },
    "redis_password": {
      "type": "string",
      "description": "managed Redis only: a specific password to set (otherwise auto-generated)."
    },
    "idempotency_key": {
      "type": "string",
      "minLength": 8
    },
    "migrate_command": {
      "type": "string",
      "description": "One-time DB prepare/migrate/seed, run AFTER `up -d` and BEFORE the app is marked ready — redu runs `podman-compose run --rm <migrate_service|service> <cmd>` (Rails `bundle exec rails db:prepare`, Django `python manage.py migrate`, Prisma `prisma migrate deploy`). REQUIRED for any stack whose schema is NOT auto-created on boot (e.g. Lago): WITHOUT it the stack deploys and flips to 'ready' but 502s on real use because the DB schema is missing."
    },
    "migrate_service": {
      "type": "string",
      "description": "Compose service to run migrate_command in (defaults to `service`)."
    },
    "redis_flavor_id": {
      "type": "string",
      "description": "managed Redis only: the dedicated Redis VM size (from list_flavors). Defaults to the app flavor."
    },
    "media_mount_path": {
      "type": "string",
      "description": "Host mount path on the app VM/member. Redu mounts this into /var/www/html/wp-content/uploads."
    },
    "media_origin_url": {
      "type": "string",
      "format": "uri",
      "description": "Public base URL where WordPress wp-content/uploads is served when using central_media_origin. Do not put this on the DB VM."
    },
    "media_space_name": {
      "type": "string",
      "maxLength": 63,
      "minLength": 1,
      "description": "Optional media space name when create_media_space:true. Defaults to <deployment-name>-media."
    },
    "cluster_media_mode": {
      "enum": [
        "local_uploads",
        "central_media_origin",
        "media_space"
      ],
      "type": "string",
      "description": "Record the WordPress media strategy for future clustering. For real WordPress clusters use media_space by default: Redu mounts a shared uploads filesystem into every member. local_uploads is single-VM only and upgrade_to_cluster will refuse it for WordPress."
    },
    "create_media_space": {
      "type": "boolean",
      "description": "For WordPress/WooCommerce cluster_target:true: set TRUE when no suitable media space exists. Redu creates an NFS media VM + persistent volume and mounts it into /var/www/html/wp-content/uploads."
    },
    "media_space_size_gb": {
      "type": "integer",
      "maximum": 2048,
      "minimum": 1,
      "description": "Media space data volume size in GB when create_media_space:true (default 20)."
    },
    "security_group_names": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "default": [
        "default"
      ]
    },
    "media_space_flavor_id": {
      "type": "string",
      "minLength": 1,
      "description": "Flavor id for the media VM when create_media_space:true. Defaults to m1.small/backend default."
    }
  },
  "additionalProperties": false
}

What this tool wraps· 3 endpoints

min confidence0.700.50

Parent server

cloud.redu/mcp

1/7 registries
View full server →