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

Private NAMD container workflow #26

Merged
merged 12 commits into from
Dec 18, 2024
Merged
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
26 changes: 23 additions & 3 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ on:
pull_request:
branches: ['main']

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
Expand All @@ -13,7 +16,7 @@ jobs:
strategy:
matrix:
arch: [amd64]
build: ["Common-CPU", "Common-GPU"]
build: ["common-cpu", "common-gpu"]

permissions:
contents: read
Expand All @@ -34,13 +37,15 @@ jobs:
- name: Option
id: option
run: |
if [ "${{ matrix.build }}" == "Common-CPU" ]; then
if [ "${{ matrix.build }}" == "common-cpu" ]; then
echo GMX_OPTS= >> $GITHUB_ENV
echo LMP_OPTS= >> $GITHUB_ENV
echo NAMD_OPTS= >> $GITHUB_ENV
echo DOCKERFILE="CPU.Dockerfile" >> $GITHUB_ENV
else
echo GMX_OPTS="-DGMX_GPU=CUDA" >> $GITHUB_ENV
echo LMP_OPTS="-DPKG_GPU=on -DGPU_API=cuda" >> $GITHUB_ENV
echo NAMD_OPTS="--with-cuda" >> $GITHUB_ENV
echo DOCKERFILE="GPU.Dockerfile" >> $GITHUB_ENV
fi

Expand All @@ -56,4 +61,19 @@ jobs:
CUDA_VER=12.4.1
DISTRO_ARCH=${{ matrix.arch }}
DISTRO_VER=22.04
DISTRO_NAME=ubuntu
DISTRO_NAME=ubuntu

- name: Build and push private NAMD Docker image
uses: docker/build-push-action@v5
with:
context: ./docker/namd
file: ./docker/namd/${{ env.DOCKERFILE }}
push: false
build-args: |
NAMD_OPTS="${{ env.NAMD_OPTS }}"
CUDA_VER=12.4.1
DISTRO_ARCH=${{ matrix.arch }}
DISTRO_VER=22.04
DISTRO_NAME=ubuntu
secrets: |
NAMD_ACCESS_TOKEN=${{ secrets.NAMD_ACCESS_TOKEN }}
25 changes: 22 additions & 3 deletions .github/workflows/deploy_docker.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
arch: [amd64]
build: ["Common-CPU", "Common-GPU"]
build: ["common-cpu", "common-gpu"]

permissions:
contents: read
Expand Down Expand Up @@ -47,13 +47,15 @@ jobs:
- name: Option
id: option
run: |
if [ "${{ matrix.build }}" == "Common-CPU" ]; then
if [ "${{ matrix.build }}" == "common-cpu" ]; then
echo GMX_OPTS= >> $GITHUB_ENV
echo LMP_OPTS= >> $GITHUB_ENV
echo NAMD_OPTS= >> $GITHUB_ENV
echo DOCKERFILE="CPU.Dockerfile" >> $GITHUB_ENV
else
echo GMX_OPTS="-DGMX_GPU=CUDA" >> $GITHUB_ENV
echo LMP_OPTS="-DPKG_GPU=on -DGPU_API=cuda" >> $GITHUB_ENV
echo NAMD_OPTS="--with-cuda" >> $GITHUB_ENV
echo DOCKERFILE="GPU.Dockerfile" >> $GITHUB_ENV
fi

Expand All @@ -77,4 +79,21 @@ jobs:
CUDA_VER=12.4.1
DISTRO_ARCH=${{ matrix.arch }}
DISTRO_VER=22.04
DISTRO_NAME=ubuntu
DISTRO_NAME=ubuntu

- name: Build and push private NAMD Docker image
uses: docker/build-push-action@v5
with:
context: ./docker/namd
file: ./docker/namd/${{ env.DOCKERFILE }}
push: true
tags: ghcr.io/becksteinlab/streaming-namd-docker:main-${{ matrix.build }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
NAMD_OPTS="${{ env.NAMD_OPTS }}"
CUDA_VER=12.4.1
DISTRO_ARCH=${{ matrix.arch }}
DISTRO_VER=22.04
DISTRO_NAME=ubuntu
secrets: |
NAMD_ACCESS_TOKEN=${{ secrets.NAMD_ACCESS_TOKEN }}
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ docker run -it --runtime=nvidia --gpus=all streaming_md_docker_local
We publish prebuilt images using CI at `ghcr.io`. Pull the latest image using:

```bash
docker pull ghcr.io/becksteinlab/streaming-md-docker:main-Common-GPU
docker pull ghcr.io/becksteinlab/streaming-md-docker:main-common-gpu
```

```bash
docker run -it --runtime=nvidia --gpus=all ghcr.io/becksteinlab/streaming-md-docker:main-Common-GPU
docker run -it --runtime=nvidia --gpus=all ghcr.io/becksteinlab/streaming-md-docker:main-common-gpu
```

131 changes: 131 additions & 0 deletions docker/namd/CPU.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
# Set environment variables during runtime.
ARG CUDA_VER
ARG DISTRO_ARCH
ARG DISTRO_VER
ARG DISTRO_NAME
FROM --platform=linux/${DISTRO_ARCH} nvidia/cuda:${CUDA_VER}-devel-${DISTRO_NAME}${DISTRO_VER} as conda

# Set `ARG`s during runtime.
ARG CUDA_VER
ARG DISTRO_ARCH
ARG DISTRO_VER
ARG DISTRO_NAME
ENV CUDA_VER=${CUDA_VER} \
DISTRO_ARCH=${DISTRO_ARCH} \
DISTRO_NAME=${DISTRO_NAME} \
DISTRO_VER=${DISTRO_VER}

# Set an encoding to make things work smoothly.
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8

# Set path to CUDA install (this is a symlink to /usr/local/cuda-${CUDA_VER})
ENV CUDA_HOME /usr/local/cuda

# bust the docker cache so that we always rerun the installs below
ADD https://loripsum.net/api /opt/docker/etc/gibberish

# Add qemu in here so that we can use this image on regular linux hosts with qemu user installed
# ADD qemu-aarch64-static /usr/bin/qemu-aarch64-static
# ADD qemu-ppc64le-static /usr/bin/qemu-ppc64le-static

# we want to persist a path in ldconfig (to avoid having to always set LD_LIBRARY_PATH), but *after* the existing entries;
# since entries in ld.so.conf.d have precedence before the preconfigured directories, we first add the latter to the former
# the upstream images all have libcuda.so under $CUDA_HOME/compat;
# add this to the ldconfig so it will be found correctly.
# don't forget to update settings by running ldconfig
RUN ldconfig -v 2>/dev/null | grep -v ^$'\t' | cut -f1 -d":" >> /etc/ld.so.conf.d/cuda-$CUDA_VER.conf && \
echo "$CUDA_HOME/compat" >> /etc/ld.so.conf.d/cuda-$CUDA_VER.conf && \
ldconfig

# Add the archived repo URL and fix RPM imports
# ADD rpm-repos /tmp/rpm-repos
# ADD fix_rpm /opt/docker/bin/fix_rpm
# RUN chmod +x /opt/docker/bin/fix_rpm
# RUN /opt/docker/bin/fix_rpm

# Remove preinclude system compilers
RUN apt-get remove -y --purge gcc g++

# Install basic requirements.
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
bzip2 \
sudo \
tar \
curl \
&& \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Run common commands
COPY run_commands /opt/docker/bin/run_commands
RUN chmod +x /opt/docker/bin/run_commands
RUN /opt/docker/bin/run_commands

# Download and cache CUDA related packages.
RUN . /opt/conda/etc/profile.d/conda.sh && \
conda activate && \
conda create -n test --yes --quiet --download-only && \
conda clean -tiy && \
chgrp -R lucky /opt/conda && \
chmod -R g=u /opt/conda

# Add a file for users to source to activate the `conda`
# environment `base`. Also add a file that wraps that for
# use with the `ENTRYPOINT`.
COPY entrypoint_source /opt/docker/bin/entrypoint_source
RUN chmod +x /opt/docker/bin/entrypoint_source
COPY entrypoint /opt/docker/bin/entrypoint
RUN chmod +x /opt/docker/bin/entrypoint

FROM conda AS build

ARG NAMD_OPTS=""

COPY . .
RUN . /opt/conda/etc/profile.d/conda.sh && conda env create --file env.yaml
RUN chmod +x install_namd.sh
RUN --mount=type=secret,id=NAMD_ACCESS_TOKEN \
. /opt/conda/etc/profile.d/conda.sh && conda activate env && ./install_namd.sh "$NAMD_OPTS"

# Delete the heavy environment but keep conda binaries
RUN . /opt/conda/etc/profile.d/conda.sh && conda remove -n env --all -y
RUN . /opt/conda/etc/profile.d/conda.sh && conda clean -a -y

ARG CUDA_VER
ARG DISTRO_ARCH
ARG DISTRO_VER
ARG DISTRO_NAME
# CUDA toolkit is massive, so use a smaller image for the runtime
FROM --platform=linux/${DISTRO_ARCH} ${DISTRO_NAME}:${DISTRO_VER}

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8

COPY . .

RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
ca-certificates

RUN update-ca-certificates

COPY --from=build /opt/docker/bin/run_commands /opt/docker/bin/run_commands
RUN /opt/docker/bin/run_commands

COPY --from=build /opt/docker/bin/entrypoint /opt/docker/bin/entrypoint
COPY --from=build /opt/docker/bin/entrypoint_source /opt/docker/bin/entrypoint_source

# Create the new lightweight env
RUN . /opt/conda/etc/profile.d/conda.sh && conda env create --file runtime_env.yaml

COPY --from=build /opt/namd-build /opt/namd-build
RUN ln -s /opt/namd-build/namd3 /bin/namd3

# Ensure that all containers start with tini and the user selected process.
# Activate the `conda` environment `base`.
# Provide a default command (`bash`), which will start if the user doesn't specify one.
ENTRYPOINT [ "/opt/conda/bin/tini", "--", "/opt/docker/bin/entrypoint" ]
CMD [ "/bin/bash" ]
134 changes: 134 additions & 0 deletions docker/namd/GPU.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Set environment variables during runtime.
ARG CUDA_VER
ARG DISTRO_ARCH
ARG DISTRO_VER
ARG DISTRO_NAME
FROM --platform=linux/${DISTRO_ARCH} nvidia/cuda:${CUDA_VER}-devel-${DISTRO_NAME}${DISTRO_VER} as conda

# Set `ARG`s during runtime.
ARG CUDA_VER
ARG DISTRO_ARCH
ARG DISTRO_VER
ARG DISTRO_NAME
ENV CUDA_VER=${CUDA_VER} \
DISTRO_ARCH=${DISTRO_ARCH} \
DISTRO_NAME=${DISTRO_NAME} \
DISTRO_VER=${DISTRO_VER}

# Set an encoding to make things work smoothly.
ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8

# Set path to CUDA install (this is a symlink to /usr/local/cuda-${CUDA_VER})
ENV CUDA_HOME /usr/local/cuda

# bust the docker cache so that we always rerun the installs below
ADD https://loripsum.net/api /opt/docker/etc/gibberish

# Add qemu in here so that we can use this image on regular linux hosts with qemu user installed
# ADD qemu-aarch64-static /usr/bin/qemu-aarch64-static
# ADD qemu-ppc64le-static /usr/bin/qemu-ppc64le-static

# we want to persist a path in ldconfig (to avoid having to always set LD_LIBRARY_PATH), but *after* the existing entries;
# since entries in ld.so.conf.d have precedence before the preconfigured directories, we first add the latter to the former
# the upstream images all have libcuda.so under $CUDA_HOME/compat;
# add this to the ldconfig so it will be found correctly.
# don't forget to update settings by running ldconfig
RUN ldconfig -v 2>/dev/null | grep -v ^$'\t' | cut -f1 -d":" >> /etc/ld.so.conf.d/cuda-$CUDA_VER.conf && \
echo "$CUDA_HOME/compat" >> /etc/ld.so.conf.d/cuda-$CUDA_VER.conf && \
ldconfig

# Add the archived repo URL and fix RPM imports
# ADD rpm-repos /tmp/rpm-repos
# ADD fix_rpm /opt/docker/bin/fix_rpm
# RUN chmod +x /opt/docker/bin/fix_rpm
# RUN /opt/docker/bin/fix_rpm

# Remove preinclude system compilers
RUN apt-get remove -y --purge gcc g++

# Install basic requirements.
# NOTE: this fixes the cuda version.
RUN apt-get update && \
converted=$(echo "$CUDA_VER" | awk -F. '{print $1 "-" $2}') && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
bzip2 \
sudo \
tar \
curl \
cuda-compiler-${converted} \
&& \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

# Run common commands
COPY run_commands /opt/docker/bin/run_commands
RUN chmod +x /opt/docker/bin/run_commands
RUN /opt/docker/bin/run_commands

# Download and cache CUDA related packages.
RUN . /opt/conda/etc/profile.d/conda.sh && \
conda activate && \
conda create -n test --yes --quiet --download-only && \
conda clean -tiy && \
chgrp -R lucky /opt/conda && \
chmod -R g=u /opt/conda

# Add a file for users to source to activate the `conda`
# environment `base`. Also add a file that wraps that for
# use with the `ENTRYPOINT`.
COPY entrypoint_source /opt/docker/bin/entrypoint_source
RUN chmod +x /opt/docker/bin/entrypoint_source
COPY entrypoint /opt/docker/bin/entrypoint
RUN chmod +x /opt/docker/bin/entrypoint

FROM conda AS build

ARG NAMD_OPTS=""

COPY . .
RUN . /opt/conda/etc/profile.d/conda.sh && conda env create --file env.yaml
RUN chmod +x install_namd.sh
RUN --mount=type=secret,id=NAMD_ACCESS_TOKEN \
. /opt/conda/etc/profile.d/conda.sh && conda activate env && ./install_namd.sh "$NAMD_OPTS"

# Delete the heavy environment but keep conda binaries
RUN . /opt/conda/etc/profile.d/conda.sh && conda remove -n env --all -y
RUN . /opt/conda/etc/profile.d/conda.sh && conda clean -a -y

ARG CUDA_VER
ARG DISTRO_ARCH
ARG DISTRO_VER
ARG DISTRO_NAME
# CUDA toolkit is massive, so use a smaller image for the runtime
FROM --platform=linux/${DISTRO_ARCH} nvidia/cuda:${CUDA_VER}-runtime-${DISTRO_NAME}${DISTRO_VER}

ENV LANG en_US.UTF-8
ENV LANGUAGE en_US.UTF-8

COPY . .

RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
ca-certificates

RUN update-ca-certificates

COPY --from=build /opt/docker/bin/run_commands /opt/docker/bin/run_commands
RUN /opt/docker/bin/run_commands

COPY --from=build /opt/docker/bin/entrypoint /opt/docker/bin/entrypoint
COPY --from=build /opt/docker/bin/entrypoint_source /opt/docker/bin/entrypoint_source

# Create the new lightweight env
RUN . /opt/conda/etc/profile.d/conda.sh && conda env create --file runtime_env.yaml

COPY --from=build /opt/namd-build /opt/namd-build
RUN ln -s /opt/namd-build/namd3 /bin/namd3

# Ensure that all containers start with tini and the user selected process.
# Activate the `conda` environment `base`.
# Provide a default command (`bash`), which will start if the user doesn't specify one.
ENTRYPOINT [ "/opt/conda/bin/tini", "--", "/opt/docker/bin/entrypoint" ]
CMD [ "/bin/bash" ]
3 changes: 3 additions & 0 deletions docker/namd/TMP.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
FROM alpine:latest
RUN apk add --no-cache bash
CMD ["bash"]
Loading
Loading