Skip to content

Instantly share code, notes, and snippets.

@olivertappin
Created June 9, 2020 09:40
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olivertappin/80cf11e72b5d3410725105efc58e9572 to your computer and use it in GitHub Desktop.
Save olivertappin/80cf11e72b5d3410725105efc58e9572 to your computer and use it in GitHub Desktop.
docker exec using the Docker Engine API with /var/run/docker.sock and curl
#!/bin/sh
# Why? In a containerised environment, you may need to run commands on other Docker containers
# within the Docker bridge network. For slim images such as Alpine-based distributions, you do
# not want the docker executable installed. Instead, you can simply pass the docker socket during
# runtime, and interact with it using cURL. The following functions allow you to easily interact
# with other containers, as you would using the native docker exec command.
# Example of mounting the docker socket:
#
# sudo chmod o+w /var/run/docker.sock
# docker run --name my-container -v /var/run/docker.sock:/var/run/docker.sock my-container
#
# Requirements:
#
# python
# sed
# curl
#
# This will be used over your existing docker executable
docker() {
# See https://docs.docker.com/engine/api/#api-version-matrix to use the correct version
curl -fs --unix-socket /var/run/docker.sock "http:/v1.40$2" -X$1 \
-H "Content-Type: application/json" \
-d "$3"
}
# The exec function is already taken by the global namespace
execute() {
CONTAINER=$1
shift
ARGS=$@
COMMAND=$(echo $ARGS | sed 's/\ /", "/g')
EXEC_RESPONSE=$(docker POST "/containers/$CONTAINER/exec" "{\"AttachStdout\": true, \"Tty\": true, \"Cmd\": [\"$COMMAND\"]}")
if [[ $? -ne 0 ]]; then
echo "Unable to complete docker exec with command: $ARGS"
return 1
fi
EXEC_ID=$(echo $EXEC_RESPONSE | python -c 'import json, sys; print(json.loads(sys.stdin.read())["Id"]);')
docker POST "/exec/$EXEC_ID/start" '{"Detach": false, "Tty": true}'
EXEC_JSON_RESPONSE=$(docker GET "/exec/$EXEC_ID/json")
if [[ $? -ne 0 ]]; then
echo "Unable to read response from docker exec with command: $ARGS"
return 1
fi
EXIT_CODE=$(echo $EXEC_JSON_RESPONSE | python -c 'import json, sys; print(json.loads(sys.stdin.read())["ExitCode"]);')
return $EXIT_CODE
}
# Working example using the methods above:
#
# execute my-container ls -lah
#
# Equivalent docker exec command:
#
# docker exec my-container ls -lah
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment