CreateProject
ChatGPTCreates a project from its files and deploys it. Waits for the deploy (wait_seconds) and answers with the operation and, once it ended, the project: its URL, its services' states, its problems.
violations instead = nothing was created: change what each says, call again. SUCCEEDED says the containers run and listen, not what a page answers: open the URL once (401 = its password page). Files, one of: the directory as it is on your disk, as an archive (CreateTransfer, then upload_id): nothing is retyped; files, text you send yourself, when there is no directory or no shell (never a file you have not read); source.github. /.env holds the secrets (env_file: .env). The compose file is the root's pethost.compose.yaml (so the repository's compose.yaml stays for development), else compose.yaml, compose.yml, docker-compose.yml or docker-compose.yaml; it becomes /compose.yaml, other compose and override files are dropped. Without one, a Dockerfile yields service app (reading /.env if any, its EXPOSE ports, a named volume per VOLUME of its last stage). compose.yaml rules. Data lives in named volumes; all else a container writes is lost when it is recreated. Project files are bind-mounted read-only. Public traffic comes only through the proxy, set in x-pethost, the one extension read, in the file or as x_pethost: x-pethost: metadata: {name: Recipe Box, emoji: "🥗", description: One line, notes: Free text} routes: - {host: recipes.sam.pethost.app, service: web, port: 3000} - {host: recipes.sam.pethost.app, path: /api, service: api, port: 8000, strip_path: true} A service without a route is private: the project's services reach it at <service>:<port>. A password for visitors goes only as x_pethost.password, never into the file: every route then answers 401 with a password page, over HTTPS only; nothing returns it (Project.password_protected says it is set); and files that write /compose.yaml keep the password_hash line the machine put in its x-pethost. All of compose.yaml is interpolated: $$ for $. The file runs as written, or is refused: the machine corrects nothing in it, in any version. Refused, each violation saying what to write instead: - container_name, profiles; name, driver, driver_opts, external or ipam of a volume or network: remove them. - ports: with a port a route sends to (remove the entry: the proxy serves it), or with a machine port the machine keeps, such as 22, 80, 443 (publish another, or use a route). - a writable bind mount (.:/app, ./data:/data): project files take :ro, data a named volume (data:/data, with data: under volumes:). - a volume with no name (- /data): name it. Below a bind mount it is allowed, as scratch space (/app/node_modules). - env_file naming a file the files lack: write it, empty if it sets nothing, or give the entry required: false. - privileged, cap_add, security_opt, devices, host namespaces, the Docker socket, a path outside the directory; more than one replica; include or extends from a URL; a git URL as a build context. An image's VOLUME that no mount covers fails the deploy (UNCOVERED_IMAGE_VOLUME): mount a named volume or a tmpfs there. ALREADY_EXISTS = the id is taken (a retry with its operation_id returns that operation). FAILED_PRECONDITION = the GitHub App cannot read the repository (see GetMachine.github), or no such branch or directory. A deleted project's id inherits its snapshots.





