Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get RUN_AS_DEVIN working with app sandbox #1426

Merged
merged 19 commits into from Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
2f2e3d4
get RUN_AS_DEVIN and network=host working with app sandbox
xingyaoww Apr 28, 2024
ce6426d
attempt to fix the workspace base permission
xingyaoww Apr 28, 2024
ac341fe
sandbox might failed in chown due to mounting, but it won't be fatal
xingyaoww Apr 28, 2024
e3157ae
update sshbox instruction
xingyaoww Apr 28, 2024
a92b889
remove default user id since it will be passed in the instruction
xingyaoww Apr 28, 2024
b6e179e
revert permission fix since it should be resolved by correct SANDBOX_…
xingyaoww Apr 28, 2024
96996e5
the permission issue can be fixed by simply provide correct env var
xingyaoww Apr 28, 2024
a564e0f
remove log
xingyaoww Apr 28, 2024
199e9ca
set sandbox user id to getuid by default
xingyaoww Apr 28, 2024
ee36c82
move logging to initializer
xingyaoww Apr 28, 2024
7282e21
make the uid consistent across host, app container, and sandbox
xingyaoww Apr 28, 2024
680d2c0
remove hostname as it causes sudo issue
xingyaoww Apr 28, 2024
f3a252e
fix permission of entrypoint script
xingyaoww Apr 28, 2024
2e6d759
make the uvicron app run as host user uid for jupyter plugin
xingyaoww Apr 28, 2024
313c16f
Merge branch 'main' into run-as-devin-and-network-host
xingyaoww Apr 28, 2024
fcc5897
Merge commit '31c1a2d748f1b0f286f5fce678e7b9311a288fa9' into run-as-d…
xingyaoww Apr 30, 2024
1ce8d5d
revert use host network
xingyaoww Apr 30, 2024
cac18c7
get docker socket gid and usermod instead of chmod 777
xingyaoww Apr 30, 2024
ec8e5ca
try to fix app build disk space issue
xingyaoww Apr 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Expand Up @@ -134,6 +134,7 @@ docker run \
-e LLM_API_KEY \
-e WORKSPACE_MOUNT_PATH=$WORKSPACE_BASE \
-v $WORKSPACE_BASE:/opt/workspace_base \
-e SANDBOX_USER_ID=$(id -u) \
-v /var/run/docker.sock:/var/run/docker.sock \
-p 3000:3000 \
--add-host host.docker.internal=host-gateway \
Expand Down
32 changes: 28 additions & 4 deletions containers/app/Dockerfile
Expand Up @@ -32,21 +32,32 @@ FROM python:3.12-slim as runtime

WORKDIR /app

ENV RUN_AS_DEVIN=false
ENV USE_HOST_NETWORK=false
ENV RUN_AS_DEVIN=true
ENV SANDBOX_USER_ID=1000
ENV USE_HOST_NETWORK=true
xingyaoww marked this conversation as resolved.
Show resolved Hide resolved
ENV SSH_HOSTNAME=host.docker.internal
ENV WORKSPACE_BASE=/opt/workspace_base
ENV OPEN_DEVIN_BUILD_VERSION=$OPEN_DEVIN_BUILD_VERSION
RUN mkdir -p $WORKSPACE_BASE

RUN apt-get update -y \
&& apt-get install -y curl ssh
&& apt-get install -y curl ssh sudo

RUN useradd -m -u $SANDBOX_USER_ID -s /bin/bash opendevin && \
usermod -aG sudo opendevin && \
echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
RUN chown -R opendevin:opendevin /app
USER opendevin

ENV VIRTUAL_ENV=/app/.venv \
PATH="/app/.venv/bin:$PATH" \
PYTHONPATH='/app'

COPY --from=backend-builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
# change ownership of the virtual environment to the sandbox user
USER root
RUN chown -R opendevin:opendevin ${VIRTUAL_ENV}
USER opendevin

COPY ./opendevin ./opendevin
COPY ./agenthub ./agenthub
Expand All @@ -55,4 +66,17 @@ RUN playwright install --with-deps chromium

COPY --from=frontend-builder /app/dist ./frontend/dist

CMD ["uvicorn", "opendevin.server.listen:app", "--host", "0.0.0.0", "--port", "3000"]
USER root
RUN chown -R opendevin:opendevin /app
# make group permissions the same as user permissions
RUN chmod -R g=u /app
USER opendevin

# change ownership of the app directory to the sandbox user
COPY ./containers/app/entrypoint.sh /app/entrypoint.sh

# run the script as root
USER root
RUN chown opendevin:opendevin /app/entrypoint.sh
RUN chmod 777 /app/entrypoint.sh
CMD ["/app/entrypoint.sh"]
21 changes: 21 additions & 0 deletions containers/app/entrypoint.sh
@@ -0,0 +1,21 @@
#!/bin/bash
# check user is root
if [ "$(id -u)" -ne 0 ]; then
echo "Please run as root"
exit 1
fi

if [ -z "$SANDBOX_USER_ID" ]; then
echo "SANDBOX_USER_ID is not set"
exit 1
fi

# change uid of opendevin user to match the host user
# but the group id is not changed, so the user can still access everything under /app
usermod -u $SANDBOX_USER_ID opendevin

# make docker.sock accessible to the user
chmod 777 /var/run/docker.sock
xingyaoww marked this conversation as resolved.
Show resolved Hide resolved

# switch to the user and start the server
su opendevin -c "cd /app && uvicorn opendevin.server.listen:app --host 0.0.0.0 --port 3000"
1 change: 1 addition & 0 deletions opendevin/config.py
Expand Up @@ -48,6 +48,7 @@
ConfigType.USE_HOST_NETWORK: 'false',
ConfigType.SSH_HOSTNAME: 'localhost',
ConfigType.DISABLE_COLOR: 'false',
ConfigType.SANDBOX_USER_ID: os.getuid() if hasattr(os, 'getuid') else None,
}

config_str = ''
Expand Down
9 changes: 5 additions & 4 deletions opendevin/sandbox/docker/ssh_box.py
Expand Up @@ -41,7 +41,6 @@
elif hasattr(os, 'getuid'):
USER_ID = os.getuid()


class DockerSSHBox(Sandbox):
instance_id: str
container_image: str
Expand All @@ -62,6 +61,7 @@ def __init__(
timeout: int = 120,
sid: str | None = None,
):
logger.info(f'SSHBox is running as {"opendevin" if RUN_AS_DEVIN else "root"} user with USER_ID={USER_ID} in the sandbox')
# Initialize docker client. Throws an exception if Docker is not reachable.
try:
self.docker_client = docker.from_env()
Expand Down Expand Up @@ -150,8 +150,10 @@ def setup_user(self):
workdir=SANDBOX_WORKSPACE_DIR,
)
if exit_code != 0:
raise Exception(
f'Failed to chown workspace directory for opendevin in sandbox: {logs}')
# This is not a fatal error, just a warning
logger.warning(
f'Failed to chown workspace directory for opendevin in sandbox: {logs}. But this should be fine if the {SANDBOX_WORKSPACE_DIR=} is mounted by the app docker container.'
)
else:
exit_code, logs = self.container.exec_run(
# change password for root
Expand Down Expand Up @@ -379,7 +381,6 @@ def restart_docker_container(self):
**network_kwargs,
working_dir=SANDBOX_WORKSPACE_DIR,
name=self.container_name,
hostname='opendevin_sandbox',
detach=True,
volumes={
mount_dir: {
Expand Down