# ==================================================
# This is the full Dockerfile for the environment building.
# ==================================================

# ==================================================
# *Based on cuda11.1-cudnn8-devel-ubuntu20.04
#
# Other base images are listed in:
# https://hub.docker.com/r/nvidia/cuda/tags
#
# The version of some basic packages:
#   - Python: 3.8
#   - Pytorch: 1.8.2
#
# Change these versions by yourself if needed.
# ==================================================

FROM nvidia/cuda:11.1.1-cudnn8-devel-ubuntu20.04


# ==================================================
# *Basic Setups
# ==================================================

# Set default RUN shell to /bin/bash
SHELL ["/bin/bash", "-cu"]


# Set environment variables
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8


# TUNA Mirror (optional)
COPY misc/sources.list.ubuntu20.04 /etc/apt/sources.list


# Install basic packages for compiling and building
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --allow-downgrades --allow-change-held-packages --no-install-recommends \
    build-essential \
    cmake \
    g++-7 \
    git \
    curl \
    wget \
    ca-certificates \
    libjpeg-dev \
    libpng-dev \
    librdmacm1 \
    libibverbs1 \
    ibverbs-providers \
    tzdata \
    libgl1-mesa-glx \
    libglib2.0-0 \
    && rm -rf /var/lib/apt/lists/*


# Install Miniconda & use Python 3.8
ARG python=3.8
ENV PYTHON_VERSION=${python}
RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /tmp/install-conda.sh \
    && chmod +x /tmp/install-conda.sh \
    && /tmp/install-conda.sh -b -f -p /usr/local \
    && rm -f /tmp/install-conda.sh \
    && conda install -y python=${PYTHON_VERSION} \
    && conda clean -y --all


# Install Pytorch LTS (1.8.2)
# you can find other versions and installation commands from:
# https://pytorch.org/get-started/previous-versions/
RUN pip install --no-cache-dir \
    torch==1.8.2 \
    torchvision==0.9.2 \
    torchaudio==0.8.2 \
    --extra-index-url https://download.pytorch.org/whl/lts/1.8/cu111

# Below is the example installation command for stable versions:
# ENV PYTORCH_VERSION=1.8.2
# ENV TORCHVISION_VERSION=0.9.2
# RUN pip install --no-cache-dir \
#     torch==${PYTORCH_VERSION} \
#     torchvision==${TORCHVISION_VERSION} \
#     -f https://download.pytorch.org/whl/torch_stable.html


# ==================================================
# *Tools installation (optional)
# ==================================================


# Install basic packages
RUN apt-get update && apt-get install -y --allow-downgrades --allow-change-held-packages --no-install-recommends \
    zsh \
    vim \
    zip \
    unzip \
    rsync \
    htop \
    language-pack-en \
    nethogs \
    sysstat \
    gnupg \
    lsb-release \
    sudo \
    && rm -rf /var/lib/apt/lists/*


# Set ZSH as default shell & Install Oh My Zsh and zsh plugin: zsh-autosuggestions
RUN chsh -s `which zsh` \
    && curl https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh | bash -s -- --unattended \
    && wget https://raw.githubusercontent.com/oskarkrawczyk/honukai-iterm/master/honukai.zsh-theme -O ${ZSH:-~/.oh-my-zsh}/themes/honukai.zsh-theme --no-check-certificate \
    && sed -i.bak '/ZSH_THEME/s/\".*\"/\"honukai\"/' ~/.zshrc \
    && git clone https://github.com/zsh-users/zsh-autosuggestions ${ZSH:-~/.oh-my-zsh}/custom/plugins/zsh-autosuggestions\
    && sed -i.bak '/plugin/s/(.*)/(git zsh-autosuggestions)/' ~/.zshrc

# Make the color of zsh-autosuggestions right
ENV TERM=xterm-256color


# Install docker (to make docker in docker work)
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
    | gpg --dearmor -o /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/ubuntu \
    $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \
    && apt-get update \
    && apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin \
    && rm -rf /var/lib/apt/lists/*

# TUNA Mirror (optional)
COPY misc/sources.list.ubuntu20.04 /etc/apt/sources.list
RUN apt-get update && apt-get install -y --allow-downgrades --allow-change-held-packages --no-install-recommends \
    ffmpeg \
    openjdk-8-jdk \
    graphviz \
    uvicorn \
    && rm -rf /var/lib/apt/lists/*


# ==================================================
# Install python packages
# ==================================================

# Setup TUNA mirror (optional)
RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
COPY misc/.condarc /root/.condarc

# By default, install packages from `requirements.txt` with pip.
COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt \
    && rm -f /tmp/requirements.txt

# Install spacy models
# RUN python -m spacy download en_core_web_sm

# Another way is installing packages from a `env.yaml` with conda.
# COPY env.yaml /tmp/env.yaml
# RUN conda env create -f /tmp/env.yaml && rm -f /tmp/env.yaml


# ==================================================
# Post-installation steps
#
# Create a user that has the same UID and GID as the host user. This will
# prevent many privileges issues.
# ==================================================

# COPY .localrc
COPY misc/.localrc /root
RUN echo ". ~/.localrc" >> /root/.zshrc


# Add a user with the same UID and GID as the host user, to prevent privilege issues.
ARG USER_ID=1011
ARG GROUP_ID=1011
ARG USER_NAME=docker
RUN if [ $USER_NAME != "root" ] ; \
    then addgroup --gid ${GROUP_ID} ${USER_NAME} \
    && adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID ${USER_NAME} \
    && usermod -aG sudo ${USER_NAME} \
    && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers ; fi


# Copy installed configuration files from root to user
COPY misc/init_workspace /usr/local/bin
RUN /usr/local/bin/init_workspace --user ${USER_NAME} --home /home/${USER_NAME}


# Switch to the created user
USER ${USER_NAME}


# Set working directory to /workspace
WORKDIR "/workspace"