Skip to content
Draft
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
30 changes: 30 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.git
.github
.venv
__pycache__
*.pyc
*.pyo
*.pyd
*.swp
.DS_Store

# Build and distribution directories
dist
dist3
build/
**/build/
wheelhouse

# CMake artifacts (match at any depth)
**/CMakeCache.txt
**/CMakeFiles/
**/cmake_install.cmake
**/Makefile
*.cmake

# Common cache directories for Python tools
.pytest_cache
.mypy_cache
.ruff_cache

docs/build
136 changes: 136 additions & 0 deletions .github/workflows/publish-container.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
name: Publish Container

on:
push:
branches:
- develop
tags:
- "v*"
workflow_dispatch:

permissions:
contents: read
packages: write

env:
IMAGE_GHCR: ghcr.io/${{ github.repository }}
IMAGE_DOCKERHUB: docker.io/${{ vars.DOCKERHUB_IMAGE || 'avslab/basilisk' }}

concurrency:
group: publish-container-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build and Push (${{ matrix.arch }})
runs-on: ${{ matrix.runner }}
timeout-minutes: 180
strategy:
fail-fast: false
matrix:
include:
- arch: amd64
platform: linux/amd64
runner: ubuntu-24.04
- arch: arm64
platform: linux/arm64
runner: ubuntu-24.04-arm

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Compute image metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.IMAGE_GHCR }}
${{ env.IMAGE_DOCKERHUB }}
flavor: |
latest=false
suffix=-${{ matrix.arch }}
tags: |
type=raw,value=develop,enable=${{ github.ref == 'refs/heads/develop' }}
type=sha,prefix=develop-,format=short,enable=${{ github.ref == 'refs/heads/develop' }}
type=ref,event=tag
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}

- name: Build and push arch image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: true
platforms: ${{ matrix.platform }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=container-${{ matrix.arch }}
cache-to: type=gha,mode=max,scope=container-${{ matrix.arch }}

publish:
name: Publish Multi-Arch Manifests
runs-on: ubuntu-24.04
timeout-minutes: 30
needs: build

steps:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
registry: docker.io
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}

- name: Compute image metadata
id: meta
uses: docker/metadata-action@v5
with:
images: |
${{ env.IMAGE_GHCR }}
${{ env.IMAGE_DOCKERHUB }}
tags: |
type=raw,value=develop,enable=${{ github.ref == 'refs/heads/develop' }}
type=sha,prefix=develop-,format=short,enable=${{ github.ref == 'refs/heads/develop' }}
type=ref,event=tag
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') }}

- name: Create and push manifest lists
shell: bash
run: |
set -euo pipefail
while IFS= read -r tag; do
[[ -z "$tag" ]] && continue
docker buildx imagetools create \
-t "$tag" \
"$tag-amd64" \
"$tag-arm64"
docker buildx imagetools inspect "$tag"
done <<< "${{ steps.meta.outputs.tags }}"
114 changes: 114 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# syntax=docker/dockerfile:1.7
#
# Multi-stage Dockerfile for Basilisk:
# - "builder" stage: build deps + conan + swig + compilation
# - "runtime" stage: minimal runtime libs + the installed Basilisk wheel
#
# Build (runtime image):
# docker build -t bsk:py312 .
#
# Build (dev image with full toolchain):
# docker build --target builder -t bsk-dev:py312 .
#
# Run:
# docker run --rm bsk:py312
#
# Optional build args:
# --build-arg PYTHON_VERSION=3.12
# --build-arg CONAN_ARGS="--opNav True --mujoco True --mujocoReplay True"

ARG PYTHON_VERSION=3.12

# Builder
FROM python:${PYTHON_VERSION}-slim AS builder

ENV DEBIAN_FRONTEND=noninteractive \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

WORKDIR /opt/basilisk

# Build toolchain + headers needed to compile Basilisk.
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
git \
swig \
python3-setuptools \
python3-tk \
libgl1-mesa-dev \
libglfw3-dev \
libgtk2.0-dev \
libx11-dev \
libxcursor-dev \
libxi-dev \
libxinerama-dev \
libxrandr-dev \
&& rm -rf /var/lib/apt/lists/*

RUN python -m pip install --upgrade pip uv

# Configure Conan to allow system package manager usage.
RUN mkdir -p /root/.conan2 \
&& printf "tools.system.package_manager:mode=install\n" >> /root/.conan2/global.conf \
&& printf "tools.system.package_manager:sudo=False\n" >> /root/.conan2/global.conf

# Copy source
COPY . .

# Build Basilisk wheel.
ARG CONAN_ARGS="--opNav True --mujoco True --mujocoReplay True"

RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=cache,target=/root/.cache/uv \
CONAN_ARGS="${CONAN_ARGS}" \
uv pip install --system build && \
python -m build --wheel --outdir /opt/wheels .

# Runtime
FROM python:${PYTHON_VERSION}-slim AS runtime
ARG PYTHON_VERSION=3.12

ENV DEBIAN_FRONTEND=noninteractive \
PIP_DISABLE_PIP_VERSION_CHECK=1 \
PIP_NO_CACHE_DIR=1 \
PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1

WORKDIR /opt/app

# Runtime libraries only
RUN apt-get update && apt-get install -y --no-install-recommends \
python3-tk \
libgtk2.0-0 \
&& rm -rf /var/lib/apt/lists/*

# Install Basilisk wheel, strip binaries, and clean up.
COPY --from=builder /opt/wheels /opt/wheels
RUN apt-get update && apt-get install -y --no-install-recommends binutils \
&& python -m pip install --no-cache-dir /opt/wheels/*.whl \
&& rm -rf /opt/wheels \
# Remove unnecessary files to reduce image size
&& find /usr/local/lib/python* -type d -name 'tests' -exec rm -rf {} + 2>/dev/null || true \
&& find /usr/local/lib/python* -type d -name '__pycache__' -exec rm -rf {} + 2>/dev/null || true \
&& find /usr/local/lib/python* -name '*.pyc' -delete \
&& find /usr/local/lib/python* -name '*.pyo' -delete \
# Remove static libraries
&& find /usr/local/lib/python* -name '*.a' -delete \
# Strip debug symbols from shared objects
&& find /usr/local/lib/python* -name '*.so' -exec strip --strip-unneeded {} + \
# Remove pip
&& python -m pip uninstall -y pip \
&& apt-get purge -y binutils && apt-get autoremove -y \
&& rm -rf /var/lib/apt/lists/*

# Drop privileges
RUN useradd --create-home --shell /bin/bash basilisk
USER basilisk
WORKDIR /home/basilisk

# Expose Vizard communication ports and Bokeh server port
EXPOSE 5556 5570 5006

CMD ["python", "-c", "import Basilisk; print('Basilisk import OK')"]
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,29 @@ the platform-specific setup instructions:

See the [Build from Source docs](docs/source/Build.rst) for full details.

#### Containers

Basilisk container images are published to:

* [GHCR](https://ghcr.io/avslab/basilisk)
* [Docker Hub](https://hub.docker.com/r/avslab/basilisk)

Published tags follow this policy:

* `develop` and `develop-<short-sha>` for pushes to the `develop` branch
* `v*` (for example `v2.9.0`) and `latest` for release tags

Images are multi-architecture (`linux/amd64`, `linux/arm64`).

Quick start:

```bash
docker pull docker.io/avslab/basilisk:develop
docker run --rm docker.io/avslab/basilisk:develop
```

For more details, see [container docs](docs/source/Build/containers.rst).

### Basilisk Development guidelines

* [Contributing](CONTRIBUTING.md)
Expand Down
1 change: 1 addition & 0 deletions docs/source/Build.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ most users the precompiled version available on PyPI is sufficient. See the
Build/customPython
Build/installBuildConan
Build/pipInstall
Build/containers
Loading
Loading