google-cloud-platformgoogle-cloud-run

How do I run a single, one time run file in cloudrun, I do not care about web at all


Sorry for posting this. I'm trying to run a single file, as a one time executable job, I do not care about the web, I don't care about ports for users to hit, there are no user there is nothing to hit. I just want to run a single file, not a web server, a file.

Here is my index.js file

// Retrieve Job-defined env vars
const { CLOUD_RUN_TASK_INDEX = 0, CLOUD_RUN_TASK_ATTEMPT = 0 } = process.env;
// Retrieve User-defined env vars
const { SLEEP_MS, FAIL_RATE } = process.env;

// Define main script
const main = async () => {
    console.log(
        `Starting Task #${CLOUD_RUN_TASK_INDEX}, Attempt #${CLOUD_RUN_TASK_ATTEMPT}...`
    );
    // Simulate work
    if (SLEEP_MS) {
        await sleep(SLEEP_MS);
    }
    // Simulate errors
    if (FAIL_RATE) {
        try {
            randomFailure(FAIL_RATE);
        } catch (err) {
            err.message = `Task #${CLOUD_RUN_TASK_INDEX}, Attempt #${CLOUD_RUN_TASK_ATTEMPT} failed.\n\n${err.message}`;
            throw err;
        }
    }
    console.log(`Completed Task #${CLOUD_RUN_TASK_INDEX}.`);
};

// Wait for a specific amount of time
const sleep = ms => {
    return new Promise(resolve => setTimeout(resolve, ms));
};

// Throw an error based on fail rate
const randomFailure = rate => {
    rate = parseFloat(rate);
    if (!rate || rate < 0 || rate > 1) {
        console.warn(
            `Invalid FAIL_RATE env var value: ${rate}. Must be a float between 0 and 1 inclusive.`
        );
        return;
    }

    const randomFailure = Math.random();
    if (randomFailure < rate) {
        throw new Error('Task failed.');
    }
};

// Start script
main().catch(err => {
    console.error(err);
    process.exit(1); // Retry Job Task by exiting the process
});

Then I have my package.json like so

{
    "name": "jobs",
    "version": "1.0.0",
    "description": "Node.js sample for Cloud Run jobs",
    "main": "index.js",
    "scripts": {
        "start": "node index.js"
    },
    "engines": {
        "node": ">=16.0.0"
    },
    "author": "Google LLC",
    "license": "Apache-2.0"
}

These files are both right out of the docs, nothing altered at all.

And I'm getting this

Deployment failed                                                                                   
ERROR: (gcloud.run.deploy) Revision 'cloudruntest-00001-fdl' is not ready and cannot serve traffic. The user-provided container failed to start and listen on the port defined provided by the PORT=8080 environment variable within the allocated timeout. This can happen when the container port is misconfigured or if the timeout is too short. The health check timeout can be extended. Logs for this revision might contain more information.

Webservers are cool and all, but right now I just want to run a file, that's it, what do I need to do to run a file in cloudrun?


Solution

  • gcloud run deploy is used to deploy Cloud Run Services, which are expected to have a web server. gcloud run jobs deploy deploys a Cloud Run Job, which is expected to start up, run to completion, and then shut itself down.

    You'll also either need to pass --execute-now to the deploy command or call gcloud run jobs execute after deploy to get it to actually run. Cloud Run jobs are intended to be re-usable and not just one-offs so deploy normally just stages the job to be run and then you can invoke it whenever later.