One-Off Tasks #

You will use One-Off Tasks to run certain commands on a one-time basis. For example, you could use this to run database migrations or to debug your App.

A One-Off Task starts a new container for an App with a certain image. By default, this will be the current image tag configured in the stage definition for the App, but it can be overridden.

A One-Off Task can run up to 24h and will be terminated when it exceeds this limit.

Start a background task #

Start a One-Off Task with task:run -- COMMAND. SetOps will create the One-Off Task and start streaming its logs. The Task will continue running until the process exits, or until you run task:stop ID.

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:run -- echo "Hello World"
# 2020-11-11 14:22:13 Hello World

One-Off tasks can be configured with the following parameters.

  • --image-tag IMAGE_TAG run a one-off task with a specific image
  • --cpu CPUVALUE --memory MEMORYVALUE run a task with a specific resource configuration (see App Resources for valid values)
  • --entrypoint "list,of,commands" overwrite the container entrypoint for the task

The following snippet is an example for a command using all configuration options.

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:run --image-tag v1.0.0 --cpu 256 --memory 512 --entrypoint "/bin/bash,-c" -- echo "Hello World"
# 2020-11-11 14:22:13 Hello World

You can run detached background tasks with the --detached flag.

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:run --detached -- echo "rake db:migrate"

When running in a non-interactive environment e.g. a CI pipeline, you can use --detach-timeout to guarantee the CLI detaches from the output after the specified time. --detach-timeout can be specified in the format 10m where 10 is the value and m the unit. Valid units are h (hours), m (minutes), s (seconds), ms (milliseconds) and ns or us (nanoseconds). Please note, that you cannot use --detach-timeout in combination with --interactive.

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:run --detach-timeout 10m

Now you can see the list of all running tasks with the task command:

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task

You can stop running tasks with the task:stop command.

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:stop ID

Interactive one-off tasks with tmate #

Interactive One-Off Tasks allow you to debug your application on SetOps, for example with a REPL console. SetOps native support for this feature is currently experimental. We still recommend using tmate to connect to one-off tasks started with the SetOps CLI, which is outlined in this section. Refer to native interactive one-off-tasks for the experimental but native method.

Setup your app image #

Add the tmate CLI to your App image. For example, when building your image, you could add tmate to your bin/ directory.

Most easily, you can download the static-linux-amd64 version from the latest tmate release and extract it into the bin/ directory with this snippet:

# apt-get install -y --no-install-recommends curl ca-certificates xz-utils
curl -sSL -o- https://github.com/tmate-io/tmate/releases/download/2.4.0/tmate-2.4.0-static-linux-amd64.tar.xz | \
  tar -xJf - -C bin --strip-components=1 tmate-2.4.0-static-linux-amd64/tmate

Should you build the App image with a Dockerfile you can use one of the snippets below:

  • For Ubuntu / Debian-based images:

    RUN apt-get update \
     && apt-get install -y --no-install-recommends curl tar xz-utils ca-certificates \
     && curl -sSL -o- https://github.com/tmate-io/tmate/releases/download/2.4.0/tmate-2.4.0-static-linux-amd64.tar.xz | \
      tar -xJf- -C bin --strip-components=1 tmate-2.4.0-static-linux-amd64/tmate \
     && chmod +x /bin/tmate
    
  • For Alpine-based images:

    RUN apk add --update curl tar xz ca-certificates \
     && curl -sSL -o- https://github.com/tmate-io/tmate/releases/download/2.4.0/tmate-2.4.0-static-linux-amd64.tar.xz | \
      tar -xJf- -C bin --strip-components=1 tmate-2.4.0-static-linux-amd64/tmate \
     && chmod +x /bin/tmate
    

Ensure your App’s active image contains tmate.

Make sure that the user in the app image can use a shell. When an image is using a non-root user (via the USER command) or modifying the user’s shell, tmate might not be able to open a shell for you and end up in a continues restart loop:

...
Session shell restarted
Session shell restarted
Session shell restarted
...

Refer to your base image’s documentation on how to set a valid shell for a user.

Create a tmate session #

Launch a new one-off task with tmate using task:run:

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:run -- tmate -F
ID:   55a9b03b765446ecb954ccedfc9ea25b

Starting Task...

2021-03-17 09:58:34 [system] Task status is PROVISIONING, desired status is RUNNING
2021-03-17 09:58:43 [system] Task status is PENDING, desired status is RUNNING
2021-03-17 09:59:03 [system] Task status is RUNNING, desired status is RUNNING
2021-03-17 09:59:03 [app] To connect to the session locally, run: tmate -S /tmp/tmate-1000/mPMdig attach
2021-03-17 09:59:03 [app] Connecting to ssh.tmate.io...
2021-03-17 09:59:03 [app] <APPNAME> session read only: https://tmate.io/t/ro-AaNRnjaTqUMueFppUt2L2RRaK
2021-03-17 09:59:03 [app] ssh session read only: ssh ro-AaNRnjaTqUMueFppUt2L2RRaK@lon1.tmate.io
2021-03-17 09:59:03 [app] <APPNAME> session: https://tmate.io/t/pjE268N8gc85vWvsfccmLg6Lb
2021-03-17 09:59:03 [app] ssh session: ssh pjE268N8gc85vWvsfccmLg6Lb@lon1.tmate.io

You can use any link to connect to the task.

The tmate session will continue running until you stop it manually. When you’re finished, do not forget to stop the task with it’s task ID.

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:stop ID

Native interactive one-off tasks #

Please note: Native Interactive One-Off Tasks are an experimental feature with some shortcomings, explained below. Refer to one-off tasks with tmate for the stable method.

SetOps now supports native interactive one-off tasks. This allows you to use a shell, or a REPL (read-eval-print loop) console, for example.

There are some prerequisites for interactive one-off tasks:

  • You need to install the AWS session-manager-plugin binary. See their documentation for instructions on how to install the tool. Note that it is also available on Homebrew: brew install session-manager-plugin
  • Your App image needs to have a sleep executable. When using standard images, this is usually not an issue since they come with a base system. However, in minimalistic Docker base images, such as distroless, there is no sleep command present, and it can therefore not be used as an image for interactive one-off task.

You can start the interactive one-off task like this:

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:run --interactive -- bash
ID:   a89e769cf35f4e4f89c1d107dafaa94f

Starting Task...

2021-05-28 14:19:41 [system] Task status is PROVISIONING, desired status is RUNNING
2021-05-28 14:19:49 [system] Task status is PENDING, desired status is RUNNING
2021-05-28 14:19:54 [system] Task status is RUNNING, desired status is RUNNING
You can connect to the session with the following command:

  session-manager-plugin [...]

Run the session-manager-plugin command in a new terminal to access your interactive session. Note that the command can only be used once, and you must connect to the session before a timeout of one minute.

The task will continue running for 24 hours, or until you stop it manually. That is to ensure any work you started in your session is not interrupted. When you’re finished, do not forget to stop the task.

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:stop ID

Once you created an interactive session and stoped the shell so the task is still running, you can attach to the running task with the task:attach command.

setops -p <PROJECT> -s <STAGE> --app <APPNAME> task:attach ID -- bash

Interactive One-Off Tasks currently come with some limitations, which is why we consider them an experimental feature:

  • the command is run by the root user, regardless of which user your Docker image specifies
  • the entrypoint is not executed, which might prevent proper shell initialization (for example, it might not spawn the same programming language environment).

You’re happily invited to test the feature and use it if it suits your needs. Make sure to report issues to the SetOps team. Refer to one-off tasks with tmate for the stable method.