Run Script Setup

We support running Run Script actions on your infrastructure for self-hosted customers and for cloud customers using tunnels. For general details on the Run Script action, refer to the documentation here.

Overview

Run Script actions are executed locally using tines-command-runner.

Our deployment of tines-command-runner includes two containers:

  1. tines-command-runner

  2. pypi-server(https://github.com/pypiserver/pypiserver)

The tines-command-runner container handles executing scripts.

Usage of pypi-server is optional. The pypi-server acts as a local python package index, making the installation of packages efficient and easily configurable. For details on configuring tines-command-runner, including available environment variables and options for configuring your own custom package index, see our tines-command-runner configuration reference.

Privilege Escalation

The tines-command-runner image generates a unique Linux user for each Tines Stories team using Run Script actions. To ensure each team's scripts are isolated from one another, tines-command-runner uses sudo to switch between these users when running scripts for a particular team.

If your environment restricts privilege escalation by default, avoid restricting the following capabilities on the tines-command-runner container.

Required capabilities

  • SETUID

    • Allows the container to change the effective user ID (required for `sudo` to switch users)

  • SETGID

    • Allows the container to change the effective group ID (required for `sudo` to switch groups)

  • AUDIT_WRITE

    • Allows writing to the kernel audit log (required by PAM/sudo for security logging)

Deployment

Step 1. Prepare the tines-command-runner Docker image 

To simplify deployment, we mirror the image from Docker Hub into an ECR repository:

aws --profile test ecr create-repository --repository-name tines-command-runner

# Replace this with the address of the registry output in the previous command:
REGISTRY=306378194054.dkr.ecr.eu-west-1.amazonaws.com

aws ecr get-login-password --region eu-west-1 | \
  docker login --username AWS --password-stdin $REGISTRY

TCR_IMAGE=tines-command-runner:latest

docker pull tines/$TCR_IMAGE
docker tag tines/$TCR_IMAGE $REGISTRY/$TCR_IMAGE
docker push $REGISTRY/$TCR_IMAGE

Run tines-command-runner as its own ECS service. Both tines-app (web) and tines-sidekiq (workers) connect to this service:

  • Run Script actions connect from Sidekiq.

  • Apps builds connect from the web container. Warm-up and cleanup jobs also connect from Sidekiq.

Follow the Fargate deployment guide to create the task definition, security group, and ECS service. Then complete these steps:

Step 2. Establish tines-command-runner visibility

Register the TCR service in AWS Cloud Map, or an equivalent private DNS service, so it resolves from app and worker tasks.

Step 3. Update environment variables

Set these variables on both tines-app and tines-sidekiq, typically in the shared .env file in S3:

TINES_COMMAND_RUNNER_HOST=tines-command-runner.tines.internal
TINES_COMMAND_RUNNER_PORT=4400

Set TINES_COMMAND_RUNNER_HOST to the DNS name of your standalone service. The example uses the fully qualified Cloud Map service name.

Step 4. Prepare the tines-command-runner Docker image 

  1. Security group. Allow TCP port 4400 to the TCR service from both the tines-app and tines-sidekiq security groups. tines-command-runner has no built-in authentication, so restrict access to the Tines services that need it.

Start with one TCR task. If you scale to multiple tasks, configure an internal application load balancer with cookie stickiness. See Run script (tines-command-runner) for the sticky-session requirement.

Migrate an existing Sidekiq sidecar deployment

Earlier versions of this page had tines-command-runner deployed as a sidecar in the tines-sidekiq task and used TINES_COMMAND_RUNNER_HOST=localhost. Migrate from this setup to the standalone service architecture:

  1. Create a standalone tines-command-runner ECS service with private DNS (e.g. AWS Cloud Map) and the security group rules as described in the Fargate deployment guide.

  2. Set TINES_COMMAND_RUNNER_HOST on both tines-app and tines-sidekiq to the service DNS name.

  3. Confirm that both task types can connect to the service on port 4400.

  4. Confirm that Run Script actions work, then publish an app.

  5. Remove the tines-command-runner container from the tines-sidekiq task definition and redeploy.

Run Script Timeout Configuration

The default maximum Run Script timeout is 60 seconds. To increase it, set RUN_SCRIPT_MAX_TIMEOUT environment variable on your .env file or on a tines-sidekiq and tines-app task definition revision.

# Other Tines application environment variables
RUN_SCRIPT_MAX_TIMEOUT=90

tines-app uses this value to set the allowed timeout in the action run configuration, and tines-sidekiq uses it when it invokes tines-command-runner. Keep the value consistent across both services.

Allocate enough CPU and memory to tines-command-runner for longer-running scripts and their expected concurrency. See Run script (tines-command-runner) for capacity and concurrency guidance.

Was this helpful?