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
112 changes: 44 additions & 68 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,83 +1,59 @@
# Use an x86_64 specific base image
FROM --platform=linux/amd64 ubuntu:20.04
# Use Python 3.11 slim image for reliable cross-platform builds
FROM --platform=linux/amd64 python:3.11-slim

# Set up environment
ENV DEBIAN_FRONTEND=noninteractive
ENV PYTHONUNBUFFERED=1
WORKDIR /workspace
ENV DEBIAN_FRONTEND=noninteractive \
PYTHONUNBUFFERED=1 \
POETRY_HOME="/opt/poetry" \
POETRY_VIRTUALENVS_IN_PROJECT=true \
POETRY_NO_INTERACTION=1
ENV PATH="$POETRY_HOME/bin:$PATH"

# Set shell to fail on errors in pipelines
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# Install system dependencies
RUN apt-get update && apt-get install -y \
software-properties-common && \
add-apt-repository ppa:deadsnakes/ppa && \
apt-get update && apt-get install -y \
python3.10 python3.10-venv python3.10-distutils \
protobuf-compiler ffmpeg git curl build-essential libffi-dev libssl-dev \
pkg-config libhdf5-dev openjdk-11-jdk wget gnupg unzip && \
# Combining into a single RUN layer and cleaning up reduces image size
RUN apt-get update && \
apt-get install -y --no-install-recommends \
protobuf-compiler \
ffmpeg \
git \
curl \
unzip \
build-essential \
libffi-dev \
libssl-dev \
pkg-config \
libhdf5-dev && \
rm -rf /var/lib/apt/lists/*

# Create virtual environment
RUN python3.10 -m venv /opt/venv

# Install pip properly
RUN curl -sS https://bootstrap.pypa.io/get-pip.py | /opt/venv/bin/python

# Upgrade pip and install essential packages
RUN /opt/venv/bin/pip install --upgrade pip setuptools wheel

# Install Poetry
RUN curl -sSL https://install.python-poetry.org | POETRY_HOME=/opt/poetry /opt/venv/bin/python - && \
cd /usr/local/bin && \
ln -s /opt/poetry/bin/poetry
RUN curl -sSL https://install.python-poetry.org | python3 -

# Add virtual environment and Poetry to PATH
ENV PATH="/opt/venv/bin:/opt/poetry/bin:$PATH"

# Install Bazel (required for some dependencies)
RUN wget https://github.com/bazelbuild/bazel/releases/download/5.1.1/bazel-5.1.1-installer-linux-x86_64.sh && \
chmod +x bazel-5.1.1-installer-linux-x86_64.sh && \
./bazel-5.1.1-installer-linux-x86_64.sh && \
rm bazel-5.1.1-installer-linux-x86_64.sh

# Clone the repository to a temporary location
RUN git clone https://github.com/google/sbsim.git /tmp/sbsim

# Configure poetry
RUN cd /tmp/sbsim && \
poetry config virtualenvs.create false && \
poetry config installer.max-workers 10
# Set main working directory
WORKDIR /workspace

# Install base dependencies first
RUN /opt/venv/bin/pip install \
jupyter \
notebook \
dm-reverb==0.14.0 \
urllib3 \
html5lib \
requests
# Copy only the necessary files for dependency installation first (layer caching)
COPY pyproject.toml poetry.lock ./

# Install dependencies from the temporary location
RUN cd /tmp/sbsim && \
poetry lock && \
poetry install --no-root
# Install Python dependencies using Poetry (without root package)
RUN poetry install --no-root --with dev,notebooks

# Build .proto files
RUN cd /tmp/sbsim/smart_control/proto && \
protoc --python_out=. smart_control_building.proto \
smart_control_normalization.proto \
smart_control_reward.proto
# Copy the rest of the application code
COPY . .

# Create a startup script that copies files on container start
RUN echo '#!/bin/bash\n\
source /opt/venv/bin/activate\n\
if [ ! -d "/workspace/sbsim/.git" ]; then\n\
cp -r /tmp/sbsim/. /workspace/sbsim/\n\
fi\n\
cd /workspace/sbsim\n\
jupyter notebook --ip=0.0.0.0 --port=8888 --allow-root --NotebookApp.token="" --no-browser --notebook-dir=/workspace/sbsim' > /start.sh && \
chmod +x /start.sh
# Install the project and regenerate protobuf files
RUN poetry install && \
poetry run python -m grpc_tools.protoc \
--proto_path=smart_control/proto \
--python_out=smart_control/proto \
smart_control/proto/smart_control_building.proto \
smart_control/proto/smart_control_normalization.proto \
smart_control/proto/smart_control_reward.proto

# Set up environment variables for Jupyter Notebook
# Expose port for Jupyter
EXPOSE 8888

CMD ["/start.sh"]
# Default command: launch Jupyter notebook
CMD ["poetry", "run", "jupyter", "notebook", "--ip=0.0.0.0", "--port=8888", "--allow-root", "--no-browser", "--ServerApp.token=''"]
173 changes: 96 additions & 77 deletions docs/setup/docker.md
Original file line number Diff line number Diff line change
@@ -1,127 +1,146 @@
# Docker Setup Guide

To get the repository set up on non-Linux environments, you can use the
pre-configured Docker environment ("Linux/amd64") specified by the "Dockerfile".
To get the repository set up on **non-Linux** environments (e.g. macOS on Apple Silicon), use the pre-configured Docker environment (`linux/amd64`) defined in the `Dockerfile`.

## Installing Docker
## 1. Prerequisites

First, install
[Docker Desktop](https://www.docker.com/products/docker-desktop/), and accept
the terms.
1. **Docker Desktop**: Download and install from [docker.com](https://www.docker.com/products/docker-desktop).
2. **Rosetta on Apple Silicon**: In Docker Desktop, enable **Use Rosetta for x86/amd64 images** under **Settings ▶ Experimental Features**.
3. **Verify** installation:

Open Docker Desktop, and wait until it is running before proceeding.
```bash
docker --version
docker run --platform linux/amd64 hello-world
```

Verify the installation:
If `hello-world` succeeds, you're ready to proceed.

```sh
docker --version
> **Apple Silicon Note:**
> Some TensorFlow-related dependencies may not work properly on `linux/arm64`.
> If Docker build fails, add `--platform=linux/amd64` to force x86_64 emulation.
> Note that emulation may be slow and TensorFlow workloads may crash or hang
> due to resource constraints. For heavy TF workloads, consider using a native
> Linux environment or cloud-based compute.

docker run hello-world
```
---

### Troubleshooting Installation Issues on Mac
## 2. Build the Docker Image

On Mac, if verification fails, try:
From the project root (where `Dockerfile` lives), run:

```sh
/Applications/Docker.app/Contents/Resources/bin/docker --version
```bash
# Build the image (uses python:3.11-slim as base)
docker build -t sbsim:latest .
```

If that works, as a one time setup step, update the ".zshrc" file to add the
installed location to the path:

```sh
# this is the "~/.zshrc" file...
export PATH="/Applications/Docker.app/Contents/Resources/bin:$PATH"
```
> On Apple Silicon, the Dockerfile already specifies `--platform=linux/amd64`.
> If you encounter issues, try explicitly passing the platform flag:
>
> ```bash
> docker build --platform linux/amd64 -t sbsim:latest .
> ```

Remember to restart your shell afterwards:
Confirm the image exists:

```sh
source ~/.zshrc
```bash
docker images sbsim:latest
```

Now you should be able to verify the installation:
---

## 3. Run the Container in Detached Mode

```sh
docker --version
We recommend running the container _detached_ so you can open shells, run tests, and launch Jupyter without tying up your terminal:

docker run hello-world
```bash
docker run -d \
--name sbsim-container \
-p 8888:8888 \
-v "$(pwd)":/workspace \
sbsim:latest
```

## Image Operations
> **Note:** This mounts your local code into `/workspace` in the container, enabling live edits.

Ensure you have navigated to the root directory of the repository, where the
"Dockerfile" is located, before proceeding.
### 3.1 Access Jupyter

Build the image:
Open your browser at:

```bash
docker build -t sbsim-docker-env .
```

Listing images:

```sh
docker images
http://localhost:8888
```

Removing the image, as necessary:
Because we disable the token in our `CMD`, no password is needed. If you see a deprecation warning for `NotebookApp.token`, you can instead use:

```sh
docker rmi sbsim-docker-env
```bash
jupyter notebook --no-browser --ServerApp.token=''
```

## Container Operations
---

## 4. Exec into the Running Container

After the image is built, run the container (in interactive mode, with open
ports):
To run commands inside the live container:

```bash
docker run -it -p 8888:8888 -v $(pwd):/workspace sbsim-docker-env
# Open a shell in the container
docker exec -it sbsim-container bash
```

> NOTE: the container will copy the repository into "/workspace/sbsim" on the
> first run. Use -v to persist changes.
Inside the container, you're already in `/workspace`. Use Poetry to run commands:

To access Jupyter notebooks, visit
[http://localhost:8888](http://localhost:8888) in the browser.
```bash
# Run tests
poetry run pytest -q

# Run a Python script
poetry run python path/to/script.py

To run scripts or tests inside the actively running docker container:
# Check Python version (should be 3.11.x)
poetry run python --version

```sh
# activate the virtual environment:
source /opt/venv/bin/activate
# Launch Jupyter (if not already running via CMD)
poetry run jupyter notebook --ip=0.0.0.0 --no-browser --ServerApp.token=''
```

# navigate to the repository:
cd /workspace/sbsim
Alternatively, run commands directly without exec:

# running scripts:
python path/to/script.py
```bash
# Run tests from outside the container
docker exec sbsim-container poetry run pytest -q

# running tests:
pytest
# Check Python version
docker exec sbsim-container python --version
```

To stop the container:
---

```sh
docker stop sbsim-docker-env
```
## 5. Stop & Clean Up

```bash
# Stop the container
docker stop sbsim-container

Listing containers (to get their identifiers):
# Remove the container
docker rm sbsim-container

```sh
docker ps -a
# Remove the image
docker rmi sbsim:latest
```

Removing a container:
---

```sh
docker rm <container-id>
```
## 6. Troubleshooting

- **Daemon not running**: If you see `Cannot connect to the Docker daemon`, open Docker Desktop or run:

```bash
/Applications/Docker.app/Contents/Resources/bin/docker --version
```

- **Platform mismatch**: If you still get a warning about `linux/amd64` vs `arm64`, ensure Rosetta support is enabled in Docker Desktop.
- **Permission errors**: By default, files created inside the container are owned by `root`. To write files to your host, either adjust volume permissions or run with `--user=$(id -u):$(id -g)`.

---

> NOTE: in the future we would like to further update these instructions and
> improve the Dockerfile. See
> [issue #80](https://github.com/google/sbsim/issues/80) (contributions
> welcome)!
_For ongoing improvements and discussion, see Issue [#80](https://github.com/google/sbsim/issues/80)._
Loading