Remote Docker Builds
When working with Docker, you may want to build images on a remote machine directly from local files. This can be useful when you the image is large and you don’t want to transfer it over the network.
To do this we can use ssh to tunnel the Docker socket from the remote machine to the local machine. This allows us to run docker commands locally that are executed remotely.
#!/bin/bash
# Enable strict mode
set -e
# Input Validation
if [ $# -lt 2 ]; then
echo "Usage: $0 [-d] <remote-host> <docker-command...>"
echo "Example: $0 myserver 'docker build -t myimage .'"
exit 1
fi
REMOTE_HOST=$1
shift
LOCAL_SOCKET="/tmp/docker.sock"
REMOTE_SOCKET="/var/run/docker.sock"
# Function to clean up background processes and local files
cleanup() {
echo "Cleaning up..."
if ps -p ${SSH_PID} > /dev/null 2>&1; then
kill ${SSH_PID}
wait ${SSH_PID} 2>/dev/null || true
fi
if [ -e "${LOCAL_SOCKET}" ]; then
rm -f "${LOCAL_SOCKET}"
echo "Removed local socket: ${LOCAL_SOCKET}"
fi
}
# Set trap to run cleanup on exit or interruption
trap cleanup EXIT INT TERM
# Ensure the local socket does not already exist
if [ -e "${LOCAL_SOCKET}" ]; then
echo "Error: Local socket ${LOCAL_SOCKET} already exists. Remove it before running this script."
exit 1
fi
# Start SSH tunnel
echo "Starting SSH tunnel to ${REMOTE_HOST}..."
ssh -N -L "${LOCAL_SOCKET}:${REMOTE_SOCKET}" "${REMOTE_HOST}" &
SSH_PID=$!
sleep 1 # Give SSH some time to start
# Check if the SSH tunnel started successfully
if ! ps -p ${SSH_PID} > /dev/null; then
echo "Error: Failed to establish SSH tunnel to ${REMOTE_HOST}."
exit 1
fi
echo "SSH tunnel established. PID: ${SSH_PID}"
# Run Docker command with remote socket
exec DOCKER_HOST="unix://${LOCAL_SOCKET}" "$@"
# Cleanup will happen automatically via trap
To build an image you can then just type:
./remote-docker.sh myserver 'docker build -t myimage .'
This runs the docker command on the remote machine and streams the output to the
local machine. The files that are transferred to the remote machine are only
files that are not ignored by the .dockerignore
file.
Last updated on