How to run one off job in containerized service with arguments

When I send:

{
    "startCommand": "alembic -c /app/alembic.ini -h"
}

I see it rendered correctly in the logs but the command fails saying too few arguments. This is a valid command with enough arguments, though.

Screenshot of logs photos [dot] app [dot] goo [dot] gl/uydbK9mBaHsrJo8JA

According the usage information, it looks like you need to supply an actual sub-command to alembic, for example

{
    "startCommand": "alembic -c /app/alembic.ini -h upgrade"
}

alembic -c /app/alembic.ini -h is a valid command that will print the help output.

For example, directly in the container locally:

alembic -c /app/alembic.ini -h

or with docker docker run my-image alembic -c /app/alembic.ini -h

gives

usage: alembic [-h] [--version] [-c CONFIG] [-n NAME] [-x X] [--raiseerr] [-q]
               {branches,check,current,downgrade,edit,ensure_version,heads,history,init,list_templates,merge,revision,show,stamp,upgrade} ...

positional arguments:
  {branches,check,current,downgrade,edit,ensure_version,heads,history,init,list_templates,merge,revision,show,stamp,upgrade}
    branches            Show current branch points.
    check               Check if revision command with autogenerate has pending upgrade ops.
    current             Display the current revision for a database.
    downgrade           Revert to a previous version.
    edit                Edit revision script(s) using $EDITOR.
    ensure_version      Create the alembic version table if it doesn't exist already .
    heads               Show current available heads in the script directory.
    history             List changeset scripts in chronological order.
    init                Initialize a new scripts directory.
    list_templates      List available templates.
    merge               Merge two revisions together. Creates a new migration file.
    revision            Create a new revision file.
    show                Show the revision(s) denoted by the given symbol.
    stamp               'stamp' the revision table with the given revision; don't run any migrations.
    upgrade             Upgrade to a later version.

options:
  -h, --help            show this help message and exit
  --version             show program's version number and exit
  -c CONFIG, --config CONFIG
                        Alternate config file; defaults to value of ALEMBIC_CONFIG environment variable, or "alembic.ini"
  -n NAME, --name NAME  Name of section in .ini file to use for Alembic config
  -x X                  Additional arguments consumed by custom env.py scripts, e.g. -x setting1=somesetting -x setting2=somesetting
  --raiseerr            Raise a full stack trace on error
  -q, --quiet           Do not log to std output.

vs in render.

usage: alembic [-h] [--version] [-c CONFIG] [-n NAME] [-x X] [--raiseerr] [-q]
               {branches,check,current,downgrade,edit,ensure_version,heads,history,init,list_templates,merge,revision,show,stamp,upgrade} ...
alembic: error: too few arguments

additional examples:

Locally:

docker run my-image bash -c 'pwd && ls -la'
/
total 12
drwxr-xr-x   1 root root   6 Mar  8 12:19 .
drwxr-xr-x   1 root root   6 Mar  8 12:19 ..
-rwxr-xr-x   1 root root   0 Mar  8 12:19 .dockerenv
drwxr-xr-x   1 root root  32 Mar  6 16:44 app

On Render:

Start command: bash -c 'pwd && ls -la'

bash: line 1: pwd && ls -la: command not found

Something is up with how startCommand is being processed and it’s not obvious what the correct way to invoke something as simple as alembic with a config file path would be.

I arrived at the simple help flag test after using check failed.

With Render:

startCommand: "alembic -c /app/alembic.ini check"

gives the same error

alembic: error: too few arguments

I don’t know why it doesn’t work in your case - it’s working for me:
i dot imgur dot com slash FlE44vP.png

This is my POST body from Postman:

{
    "startCommand": "bash -c 'pwd && ls -la | head -1'",
    "planId": "plan-srv-006"
}

The log in Render:

==> Running 'bash -c 'pwd && ls -la | head -1''
/opt/render/project/src
total 2520

Can you confirm that is for a container based service? The /opt/render path makes me think you have a non-container service.

Ah, that may be. I’m just creating a job based on the web service I already had, which is not docker based. I thought the issue was more general, but obviously you mentioned that it was for containerized service. My bad, sorry :slight_smile:

No apology needed! Thanks for confirming.

Hopefully one of their engineers will chime in and confirm there is something with how this is passed to the container as the command or entrypoint and maybe they have a known issue around this…

1 Like

TLDR don’t use quotes with /bin/sh -c

OK, got on an email with support and here’s the important info:

The startCommand overrides ENTRYPOINT and CMD and the first part of the startCommand (string separated) becomes the entrypoint with the rest being args. passed through the command.

So this works:

curl --request POST 'https://api.render.com/v1/services/your-service/jobs' \
    --header "Authorization: Bearer ${RENDER_API_KEY}" \
    --header 'Content-Type: application/json' \
    --data @- <<DATA
{
    "startCommand": "/bin/sh -c alembic -c /app/alembic.ini check"
}
DATA

as does this

curl -v --request POST 'https://api.render.com/v1/services/your-service/jobs' \
    --header "Authorization: Bearer ${RENDER_API_KEY}" \
    --header 'Content-Type: application/json' \
    --data @- <<DATA
{
    "startCommand": "/bin/bash -c cd /app; ls"
}
DATA