Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,27 @@ RUN ARCH=$(dpkg --print-architecture) && \
rm /tmp/glab.deb && \
glab --version

# Install Docker CLI from official repository (for Docker socket mounting)
RUN curl -fsSL https://download.docker.com/linux/debian/gpg | \
gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \
chmod 644 /usr/share/keyrings/docker-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list && \
apt-get update && \
apt-get install -y docker-ce-cli && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
docker --version

# Create non-root user
ARG USER_ID=1000
ARG GROUP_ID=1000
ARG USERNAME=agent

RUN groupadd -g ${GROUP_ID} ${USERNAME} || true && \
useradd -m -u ${USER_ID} -g ${GROUP_ID} -s /bin/zsh ${USERNAME} && \
(getent group docker || groupadd docker) && \
usermod -aG docker,0 ${USERNAME} && \
echo "${USERNAME} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USERNAME} && \
chmod 0440 /etc/sudoers.d/${USERNAME}

Expand Down Expand Up @@ -209,4 +223,4 @@ RUN bash -c "source $NVM_DIR/nvm.sh && \

# Entrypoint
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["/bin/zsh"]
CMD ["/bin/zsh"]
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,23 @@ Start your coding agent in the agentbox directory and issue this (example) promp

Then you can go to your project directory and run (e.g.) `agentbox --tool copilot`. Thanks to [Felix Medam](https://github.com/SputnikTea) for this very cool idea.

## Docker Access

AgentBox can optionally mount the host's Docker socket, allowing you to run Docker commands inside the container:

```bash
agentbox --docker
```

This mounts `/var/run/docker.sock` (or Docker Desktop's socket on macOS) and handles group permissions automatically. Useful for projects that need to build/run Docker images.

**How it works:**
- Your current directory is always mounted as `/workspace`
- Additional directories are mounted using their folder names (e.g., `/foo`, `/bar`)
- All directories are writable - changes sync back to the host
- The mounting order follows the order you specify in the flag


## Helpful Commands

```bash
Expand All @@ -60,6 +77,9 @@ agentbox -c
# Mount additional directories for multi-project access
agentbox --add-dir ~/proj1 --add-dir ~/proj2

# Enable Docker commands inside container
agentbox --docker

# Start shell with sudo privileges
agentbox shell --admin

Expand Down
40 changes: 36 additions & 4 deletions agentbox
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,8 @@ run_container() {
local container_name="$1"
local -n extra_dirs_to_mount=$2
local tool="$3"
shift 3
local mount_docker_socket="$4"
shift 4

# Check if first arg is "shell" mode
local shell_mode=false
Expand Down Expand Up @@ -285,6 +286,30 @@ run_container() {
log_warning "SSH not configured. Run 'agentbox ssh-init' to enable SSH operations."
fi

# Mount Docker socket if requested
if [[ "$mount_docker_socket" == "true" ]]; then
local docker_socket=""
# Check for Docker Desktop on macOS first, then Linux
if [[ -S "${HOME}/.docker/run/docker.sock" ]]; then
docker_socket="${HOME}/.docker/run/docker.sock"
elif [[ -S /var/run/docker.sock ]]; then
docker_socket="/var/run/docker.sock"
fi

if [[ -n "$docker_socket" ]]; then
mount_opts+=(-v "${docker_socket}:/var/run/docker.sock")
# Add container user to docker socket's group for permission access
local docker_gid
docker_gid=$(stat -c '%g' "$docker_socket" 2>/dev/null || stat -f '%g' "$docker_socket" 2>/dev/null)
if [[ -n "$docker_gid" ]]; then
mount_opts+=(--group-add "$docker_gid")
fi
log_info "Docker socket mounted (container has access to host Docker)"
else
log_warning "Docker socket not found"
fi
fi

# Mount cache directories for package managers
local cache_dir="${HOME}/.cache/agentbox/${container_name}"
mkdir -p "${cache_dir}/npm" "${cache_dir}/pip" "${cache_dir}/maven" "${cache_dir}/gradle"
Expand Down Expand Up @@ -422,6 +447,7 @@ Options:
-h, --help Show this help message
--tool TOOL Choose tool: claude (default) or opencode
-p PORT Forward a port from host to container (can be used multiple times)
--docker Mount Docker socket (enables docker commands inside container)
--rebuild Force rebuild of the image
--add-dir DIR Mount additional directory (can be used multiple times)

Expand All @@ -439,6 +465,7 @@ Examples:
agentbox --tool opencode # Start OpenCode instead of Claude
agentbox -p 3002 # Forward port 3002
agentbox -p 3002:8080 # Map host port 3002 to container port 8080
agentbox --docker # Enable docker commands inside container
agentbox shell # Start interactive shell instead of Claude
agentbox shell --admin # Start admin shell with sudo access
agentbox --add-dir ~/1 --add-dir ~/2 # Add dirs with Claude CLI
Expand Down Expand Up @@ -495,6 +522,7 @@ main() {
local force_rebuild=false
local shell_mode=false
local admin_mode=false
local docker_mount=false
local cmd_args=()
declare -a ports=()
local extra_dirs=()
Expand Down Expand Up @@ -537,6 +565,10 @@ main() {
tool="$1"
shift
;;
--docker)
docker_mount=true
shift
;;
shell)
shell_mode=true
shift
Expand Down Expand Up @@ -605,12 +637,12 @@ main() {
# Run or attach to container
if [[ "$shell_mode" == "true" ]]; then
if [[ "$admin_mode" == "true" ]]; then
run_container "$container_name" validated_dirs "$tool" "shell" "--admin" "${cmd_args[@]}"
run_container "$container_name" validated_dirs "$tool" "$docker_mount" "shell" "--admin" "${cmd_args[@]}"
else
run_container "$container_name" validated_dirs "$tool" "shell" "${cmd_args[@]}"
run_container "$container_name" validated_dirs "$tool" "$docker_mount" "shell" "${cmd_args[@]}"
fi
else
run_container "$container_name" validated_dirs "$tool" "${cmd_args[@]}"
run_container "$container_name" validated_dirs "$tool" "$docker_mount" "${cmd_args[@]}"
fi
}

Expand Down