Skip to content

Commit d2738e7

Browse files
bpkrothmotus
andauthored
Simplify devcontainer (#864)
# Pull Request ## Title Combines container build steps to reduce devcontainer size substantially. --- ## Description Reduces container size from ~5.7GB to ~2.7GB by combining the following steps: - install conda (previously in a base image layer) - create the base mlos environment This reduces the space substantially because conda's usual attempt to do hardlinks across environments is actually able to work. The downside is that changes to base package level requirements require reinstalling all of conda again (i.e., the single large combined container layer is less cacheable). Should help with issues like: Microsoft-CISL/sqlite-autotuning#7 --- ## Type of Change - 🔄 Refactor - Dev environment --- ## Testing - `time make devcontainer` - "Rebuild devcontainer" inside VSCode - `docker image ls` to check the sizes --- --------- Co-authored-by: Sergiy Matusevych <[email protected]>
1 parent 50a0e0f commit d2738e7

File tree

1 file changed

+61
-54
lines changed

1 file changed

+61
-54
lines changed

.devcontainer/Dockerfile

Lines changed: 61 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,43 @@
11
# Copyright (c) Microsoft Corporation.
22
# Licensed under the MIT License.
33

4-
FROM mcr.microsoft.com/devcontainers/miniconda:3 AS base
4+
FROM mcr.microsoft.com/vscode/devcontainers/base AS base
55

66
# Add some additional packages for the devcontainer terminal environment.
77
USER root
88
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
99
&& apt-get -y install --no-install-recommends \
1010
bash bash-completion \
1111
less colordiff \
12-
curl jq \
12+
curl gpg ca-certificates \
13+
jq \
1314
ripgrep \
1415
vim-nox neovim python3-pynvim \
1516
make \
1617
rename \
18+
sudo \
1719
&& apt-get clean && rm -rf /var/lib/apt/lists/* \
1820
&& echo "C-w: unix-filename-rubout" >> /etc/inputrc
1921
# Also tweak C-w to stop at slashes as well instead of just spaces
2022

23+
# Prepare the mlos_deps.yml file in a cross platform way.
24+
FROM mcr.microsoft.com/vscode/devcontainers/base AS deps-prep
25+
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
26+
&& apt-get -y install --no-install-recommends \
27+
python3-minimal python3-setuptools
28+
COPY --chown=vscode . /tmp/conda-tmp/
29+
RUN /tmp/conda-tmp/prep-deps-files.sh \
30+
&& ls -l /tmp/conda-tmp/ # && cat /tmp/conda-tmp/combined.requirements.txt /tmp/conda-tmp/mlos_deps.yml
31+
32+
FROM base AS conda
33+
2134
# Set some cache dirs to be owned by the vscode user even as we're currently
2235
# executing as root to build the container image.
2336
# NOTE: We do *not* mark these as volumes - it doesn't help rebuilding at all.
2437

38+
RUN addgroup conda \
39+
&& adduser vscode conda
40+
2541
ARG PIP_CACHE_DIR=/var/cache/pip
2642
ENV PIP_CACHE_DIR=/var/cache/pip
2743
RUN mkdir -p ${PIP_CACHE_DIR} \
@@ -36,66 +52,57 @@ RUN mkdir -p ${CONDA_PKGS_DIRS} \
3652

3753
USER vscode:conda
3854

39-
# Upgrade conda and use strict priorities
40-
# Use the mamba solver (necessary for some quality of life speedups due to
41-
# required packages to support Windows)
42-
RUN umask 0002 \
55+
# Try and prime the devcontainer's ssh known_hosts keys with the github one for scripted calls.
56+
RUN mkdir -p /home/vscode/.ssh \
57+
&& ( \
58+
grep -q ^github.com /home/vscode/.ssh/known_hosts \
59+
|| ssh-keyscan github.com | tee -a /home/vscode/.ssh/known_hosts \
60+
)
61+
62+
COPY --from=deps-prep --chown=vscode:conda /tmp/conda-tmp/mlos_deps.yml /tmp/conda-tmp/combined.requirements.txt /tmp/conda-tmp/
63+
64+
# Combine the installation of miniconda and the mlos dependencies into a single step in order to save space.
65+
# This allows the mlos env to reference the base env's packages without duplication across layers.
66+
RUN echo "Setup miniconda" \
67+
&& curl -Ss https://repo.anaconda.com/pkgs/misc/gpgkeys/anaconda.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/conda.gpg > /dev/null \
68+
&& gpg --keyring /etc/apt/trusted.gpg.d/conda.gpg --no-default-keyring --fingerprint 34161F5BF5EB1D4BFBBB8F0A8AEB4F8B29D82806 \
69+
&& echo "deb [arch=amd64 signed-by=/etc/apt/trusted.gpg.d/conda.gpg] https://repo.anaconda.com/pkgs/misc/debrepo/conda stable main" | sudo tee /etc/apt/sources.list.d/conda.list \
70+
&& sudo apt-get update \
71+
&& sudo DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends conda \
72+
&& sudo apt-get clean && sudo rm -rf /var/lib/apt/lists/* \
73+
&& echo "# Adjust the conda installation to be user/group writable." \
74+
&& sudo /opt/conda/bin/conda init --system \
75+
&& sudo chgrp -R conda /opt/conda \
76+
&& sudo chmod -R g+wX /opt/conda \
77+
&& find /opt/conda -type d -print0 | xargs -0 sudo chmod -c g+s \
78+
&& umask 0002 \
79+
&& echo "# Use conda-forge first to get the latest versions of packages " \
80+
&& echo "# and reduce duplication with mlos env (which also uses conda-forge first)." \
81+
&& echo "# Upgrade conda and use strict priorities" \
82+
&& echo "# Use the mamba solver (necessary for some quality of life speedups due to required packages to support Windows)" \
83+
&& /opt/conda/bin/conda init \
4384
&& /opt/conda/bin/conda config --set channel_priority strict \
4485
&& /opt/conda/bin/conda info \
45-
&& /opt/conda/bin/conda update -v -y -n base -c defaults --all \
86+
&& /opt/conda/bin/conda update -v -y -n base -c conda-forge -c defaults --all \
4687
&& /opt/conda/bin/conda list -n base \
47-
&& /opt/conda/bin/conda install -v -y -n base conda-libmamba-solver \
48-
&& /opt/conda/bin/conda config --set solver libmamba \
88+
&& /opt/conda/bin/conda install -v -y -n base -c conda-forge -c defaults conda-libmamba-solver \
89+
&& /opt/conda/bin/conda config --system --set solver libmamba \
90+
&& echo "# Install some additional editor packages for the base environment." \
91+
&& /opt/conda/bin/conda run -n base pip install --no-cache-dir -U pynvim \
92+
&& echo "# Clean up conda cache to save some space." \
4993
&& /opt/conda/bin/conda list -n base \
5094
&& /opt/conda/bin/conda clean -v -y -a \
51-
&& /opt/conda/bin/conda run -n base pip cache purge
52-
53-
# No longer relevant since we're using conda-forge in the environment files by default now.
54-
## Update the base. This helps save space by making sure the same version
55-
## python is used for both the base env and mlos env.
56-
#RUN umask 0002 \
57-
# && /opt/conda/bin/conda update -v -y -n base -c defaults --all \
58-
# && /opt/conda/bin/conda update -v -y -n base -c defaults conda python \
59-
# && /opt/conda/bin/conda clean -v -y -a \
60-
# && /opt/conda/bin/conda run -n base pip cache purge
61-
62-
# Install some additional editor packages for the base environment.
63-
RUN umask 0002 \
64-
&& /opt/conda/bin/conda run -n base pip install --no-cache-dir -U pynvim
65-
66-
# Setup (part of) the mlos environment in the devcontainer.
67-
# NOTEs:
68-
# - The mlos_deps.yml file is prepared by the prep-container-build script(s).
69-
# - The rest happens during first container start once the source is available.
70-
# See Also: updateContentCommand in .devcontainer/devcontainer.json
71-
RUN mkdir -p /opt/conda/pkgs/cache/ && chown -R vscode:conda /opt/conda/pkgs/cache/
72-
RUN /opt/conda/bin/conda init bash \
73-
&& /opt/conda/bin/conda config --set solver libmamba
74-
75-
# Prepare the mlos_deps.yml file in a cross platform way.
76-
FROM mcr.microsoft.com/devcontainers/miniconda:3 AS deps-prep
77-
COPY --chown=vscode:conda . /tmp/conda-tmp/
78-
RUN /tmp/conda-tmp/prep-deps-files.sh \
79-
&& ls -l /tmp/conda-tmp/ # && cat /tmp/conda-tmp/combined.requirements.txt /tmp/conda-tmp/mlos_deps.yml
80-
81-
# Install some additional dependencies for the mlos environment.
82-
# Make sure they have conda group ownership to make the devcontainer more
83-
# reliable useable across vscode uid changes.
84-
FROM base AS devcontainer
85-
USER vscode
86-
COPY --from=deps-prep --chown=vscode:conda /tmp/conda-tmp/mlos_deps.yml /tmp/conda-tmp/combined.requirements.txt /tmp/conda-tmp/
87-
RUN umask 0002 \
95+
&& /opt/conda/bin/conda run -n base pip cache purge \
96+
&& echo "# Install some additional dependencies for the mlos environment." \
97+
&& echo "# Make sure they have conda group ownership to make the devcontainer more" \
98+
&& echo "# reliable useable across vscode uid changes." \
8899
&& sg conda -c "/opt/conda/bin/conda env create -n mlos -v -f /tmp/conda-tmp/mlos_deps.yml" \
89100
&& sg conda -c "/opt/conda/bin/conda run -n mlos pip install --no-cache-dir -U -r /tmp/conda-tmp/combined.requirements.txt" \
90101
&& sg conda -c "/opt/conda/bin/conda run -n mlos pip cache purge" \
91102
&& sg conda -c "/opt/conda/bin/conda clean -v -y -a" \
92-
&& mkdir -p /opt/conda/pkgs/cache/ && chown -R vscode:conda /opt/conda/pkgs/cache/
93-
RUN mkdir -p /home/vscode/.conda/envs \
103+
&& mkdir -p /opt/conda/pkgs/cache/ && chown -R vscode:conda /opt/conda/pkgs/cache/ \
104+
&& mkdir -p /home/vscode/.conda/envs \
94105
&& ln -s /opt/conda/envs/mlos /home/vscode/.conda/envs/mlos
95106

96-
# Try and prime the devcontainer's ssh known_hosts keys with the github one for scripted calls.
97-
RUN mkdir -p /home/vscode/.ssh \
98-
&& ( \
99-
grep -q ^github.com /home/vscode/.ssh/known_hosts \
100-
|| ssh-keyscan github.com | tee -a /home/vscode/.ssh/known_hosts \
101-
)
107+
#ENV PATH=/opt/conda/bin:$PATH
108+
ENV PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

0 commit comments

Comments
 (0)