Troubleshooting
This guide contains some common commands and areas to check in order to troubleshoot any setup issues with your self-hosted run script deployment using tines-command-runner and tines-app.
docker-compose
exec into tines-command-runner container
docker ps (grab the <tcr_container_id>)
docker exec -it <tcr_container_id> /bin/bashReview docker logs for tines-command-runner
docker logs -f <tcr_container_id>Stop / Start all services
docker compose down && docker compose up -dStop only tines-command-runner service
docker stop <tcr_container_id>
docker start <tcr_container_id>Review docker env variables for tines-command-runner:
docker inspect <tcr_container_id> | jq '.[0].Config.Env'or if jq is not installed:
docker inspect <tcr_container_id> | grep -A 20 "Env"Environment Variables
tines-command-runner
PIP_INDEX_URL: Specifies the primary Python Package Index. Default ishttps://pypi.org/simple. This can be overridden to use a custom package index.PIP_EXTRA_INDEX_URL: Allows specifying a fallback package index. Default ishttp://pypi-server:8080/simple/, which is the default local PyPI server(pypi-server) running alongside the command runner.NO_PIP_INDEX: If set, disables all package indexes, includingPIP_INDEX_URLandPIP_EXTRA_INDEX_URL, relying only on packages included in the container.TRUSTED_HOST: Specifies a trusted package index host. Default ispypi-server, ensuring that the local PyPI server is trusted.
tines-app
TINES_COMMAND_RUNNER_PORT- defaults to4400TINES_COMMAND_RUNNER_HOST- defaults totines-command-runner
capacity configuration
tines-command-runner can be configured to handle different levels of concurrent requests through two key environment variables:
TINES_COMMAND_RUNNER_WORKERS- Controls the number of Puma worker processes. (Default is 2).TINES_COMMAND_RUNNER_THREADS- Controls the number of threads per worker. (Default is 5).
These values determine the total concurrent requests the command runner can handle (workers × threads). For example, with default values, the service can handle 10 concurrent requests (2 workers × 5 threads).
APP_USER
Ensuring APP_USER can sudo into Users
As part of the permissions structure for run script we generate users within in the container via the Dockerfile.
This has a number of variables which can be overridden if necessary:
APP_USER=${APP_USER:-2000}
NUM_USERS=${NUM_USERS:-1000}
GROUP_ID=${GROUP_ID:-1000}
GROUP_NAME=${GROUP_NAME:-tines-team-group}Check User Existence in /etc/passwd
getent passwd | grep tines-tcr-team-userCheck for Users Created with Specific UID Range:
awk -F: '$3 >= 2000 && $3 < 3000 {print $1, $3}' /etc/passwdVerify Home Directories Exist
ls -ld /home/tines-tcr-team-user-*Check Group Membership
getent group tines-team-groupCheck file write permissions for a user (in the case of permissions errors)
sudo -u tines-tcr-team-user-2000 touch /specify-the-dir-pathUID Mappings
Check permissions on team-uid-mappings
ls -ld /team-uid-mappings
cat /team-uid-mappingsView UID to Username Mapping (for All Users)
getent passwdCheck UID for a Specific User
id tines-tcr-team-user-2000Connectivity
This command should be run from within the tines-app container. It will attempt to connect to the tines-command-runner in a way that’s very similar to how the tines-app itself does it. It loads the host and port and then makes a POST request to the endpoint.
curl -vvv "http://${TINES_COMMAND_RUNNER_HOST:-tines-command-runner}:${TINES_COMMAND_RUNNER_PORT:-4400}/run_script" \
-H "Content-Type: application/json" \
-d '{
"action_id": 1,
"script_type": "python",
"script_content": "def main(input_data):\n print(f\"Received input_data: {input_data}\")\n result = \"2\" + str(2)\n return \"result is \" + str(result)\n",
"pre_run_command": "uv pip install $TINES_DEPENDENCIES_LIST",
"dependencies": [],
"environment_id": "1234",
"team_id": 100,
"timeout": 60
}'