Skip to content

Commit cf6c086

Browse files
committed
Make more layers of python image reusable
* by first installing system dependencies and then python Setting python version incl. patch Fix python version env var Improve readability of docker build output Use PR-base-image for datascience-image in a PR Enable buildKit layer caching Fix layer caching Remove breaking cache-parameter Next attempt to get buildcache to work Fix pip installation for datascience image Tweaked order of ARGs to invalidate less layers Use all caches in datascience builds Speed up builds by not loading images unnecessarily Ensure big apt-get layer is shared Don't build gpu images for now Fix main-builcache declaration Extracting apt-get into build-step to ensure reuse Share cache among all builds Build base image separately Strictly separate base from python image build Move build-arg so it's avaiable
1 parent dcd4861 commit cf6c086

File tree

5 files changed

+166
-65
lines changed

5 files changed

+166
-65
lines changed

.circleci/config.yml

Lines changed: 78 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,72 @@
11
version: 2.1
22

33
orbs:
4-
docker: circleci/docker@2.2.0
4+
docker: circleci/docker@2.8
55

6+
7+
commands:
8+
split_python_version:
9+
steps:
10+
- run:
11+
name: Split python version
12+
command: |
13+
echo "export PYTHON_VERSION=$(echo $PYTHON_VERSION_PATCH | cut -d'.' -f1,2)" >> $BASH_ENV
14+
source $BASH_ENV
15+
setup_buildkit_builder:
16+
steps:
17+
- run:
18+
name: Setup BuildKit builder
19+
command: |
20+
docker buildx create \
21+
--name custom-builder \
22+
--use \
23+
--driver docker-container \
624
jobs:
25+
build-and-push-base:
26+
executor: docker/docker
27+
steps:
28+
- checkout
29+
- setup_remote_docker
30+
- setup_buildkit_builder
31+
- docker/check:
32+
use-docker-credentials-store: true
33+
- docker/build:
34+
step-name: Base python image (debian + apt-get deps)
35+
path: ./python/base
36+
dockerfile: Dockerfile.base
37+
extra_build_args: |
38+
--progress plain
39+
--cache-from type=registry,ref=deepnote/python:base-buildcache,mode=max
40+
--cache-to type=registry,ref=deepnote/python:base-buildcache,mode=max
41+
--output type=registry,push=true
42+
image: deepnote/python
43+
tag: base${CIRCLE_PULL_REQUEST:+-ra-${CIRCLE_PULL_REQUEST##*/}}
744
build-and-push-python:
845
executor: docker/docker
946
parameters:
1047
python-version:
1148
type: string
1249
environment:
13-
PYTHON_VERSION: << parameters.python-version >>
50+
PYTHON_VERSION_PATCH: << parameters.python-version >>
1451
steps:
1552
- checkout
1653
- setup_remote_docker
1754
- docker/check:
1855
use-docker-credentials-store: true
56+
- split_python_version
57+
- setup_buildkit_builder
1958
- docker/build:
20-
step-name: Base Python image
59+
step-name: Python image
2160
path: ./python/base
22-
dockerfile: Dockerfile
23-
extra_build_args: "--build-arg FROM_PYTHON_VERSION=${PYTHON_VERSION}"
24-
image: deepnote/python
25-
tag: ${PYTHON_VERSION}${CIRCLE_PULL_REQUEST:+-ra-${CIRCLE_PULL_REQUEST##*/}}
26-
- docker/push:
61+
dockerfile: Dockerfile.python
62+
extra_build_args: |
63+
--build-arg CIRCLE_PULL_REQUEST=${CIRCLE_PULL_REQUEST}
64+
--build-arg PYTHON_VERSION=${PYTHON_VERSION}
65+
--build-arg PYTHON_VERSION_PATCH=${PYTHON_VERSION_PATCH}
66+
--progress plain
67+
--cache-from type=registry,ref=deepnote/python:${PYTHON_VERSION}-buildcache,mode=max
68+
--cache-to type=registry,ref=deepnote/python:${PYTHON_VERSION}-buildcache,mode=max
69+
--output type=registry,push=true
2770
image: deepnote/python
2871
tag: ${PYTHON_VERSION}${CIRCLE_PULL_REQUEST:+-ra-${CIRCLE_PULL_REQUEST##*/}}
2972
build-and-push-python-datascience:
@@ -32,24 +75,29 @@ jobs:
3275
python-version:
3376
type: string
3477
environment:
35-
PYTHON_VERSION: << parameters.python-version >>
78+
PYTHON_VERSION_PATCH: << parameters.python-version >>
3679
steps:
3780
- checkout
3881
- setup_remote_docker
3982
- docker/check:
4083
use-docker-credentials-store: true
84+
- split_python_version
85+
- setup_buildkit_builder
4186
- docker/build:
4287
step-name: Datascience Python image
4388
path: ./python/datascience
4489
docker-context: ./python/datascience
4590
dockerfile: Dockerfile.datascience
46-
extra_build_args: "--build-arg FROM_PYTHON_VERSION=${PYTHON_VERSION}"
91+
extra_build_args: |
92+
--build-arg PYTHON_VERSION=${PYTHON_VERSION}
93+
--build-arg CIRCLE_PULL_REQUEST=${CIRCLE_PULL_REQUEST}
94+
--progress plain
95+
--cache-from type=registry,ref=deepnote/python:${PYTHON_VERSION}-buildcache,mode=max
96+
--cache-from type=registry,ref=deepnote/python-datascience:${PYTHON_VERSION}-buildcache,mode=max
97+
--cache-to type=registry,ref=deepnote/python-datascience:${PYTHON_VERSION}-buildcache,mode=max
98+
--output type=registry,push=true
4799
image: deepnote/python-datascience
48100
tag: ${PYTHON_VERSION}${CIRCLE_PULL_REQUEST:+-ra-${CIRCLE_PULL_REQUEST##*/}}
49-
- docker/push:
50-
image: deepnote/python-datascience
51-
tag: ${PYTHON_VERSION}${CIRCLE_PULL_REQUEST:+-ra-${CIRCLE_PULL_REQUEST##*/}}
52-
53101
build-and-push-gpu:
54102
executor: docker/docker
55103
parameters:
@@ -68,10 +116,11 @@ jobs:
68116
- setup_remote_docker
69117
- docker/check:
70118
use-docker-credentials-store: true
119+
- split_python_version
71120
- docker/build:
72121
step-name: Tensorflow GPU image
73122
path: ./gpu
74-
extra_build_args: "--build-arg CUDA_IMAGE_TAG=${CUDA_TAG} --build-arg TF_VERSION=${TF_VERSION} --build-arg PYTHON_VER=${PY_VERSION}"
123+
extra_build_args: "--build-arg CUDA_IMAGE_TAG=${CUDA_TAG} --build-arg TF_VERSION=${TF_VERSION} --build-arg PYTHON_VER=${PY_VERSION} --progress plain"
75124
image: deepnote/tensorflow
76125
tag: ${TF_VERSION}${CIRCLE_PULL_REQUEST:+-ra-${CIRCLE_PULL_REQUEST##*/}}-gpu
77126
- docker/push:
@@ -81,25 +130,30 @@ jobs:
81130
workflows:
82131
build:
83132
jobs:
133+
- build-and-push-base:
134+
name: Building the base image
84135
- build-and-push-python:
85136
name: Python << matrix.python-version >>
86137
matrix:
87138
parameters:
88139
python-version:
89-
- "3.8"
90-
- "3.9"
91-
- "3.10"
92-
- "3.11"
93-
140+
- "3.8.19"
141+
- "3.9.19"
142+
- "3.10.15"
143+
- "3.11.10"
144+
requires:
145+
- Building the base image
94146
- build-and-push-python-datascience:
95147
name: Python Datascience << matrix.python-version >>
96148
matrix:
97149
parameters:
98150
python-version:
99-
- "3.8"
100-
- "3.9"
101-
- "3.10"
102-
- "3.11"
151+
- "3.8.19"
152+
- "3.9.19"
153+
- "3.10.15"
154+
- "3.11.10"
155+
requires:
156+
- Python << matrix.python-version >>
103157

104158
- build-and-push-gpu:
105159
name: Tensorflow 2.9

python/base/Dockerfile

Lines changed: 0 additions & 36 deletions
This file was deleted.

python/base/Dockerfile.base

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
FROM debian:bullseye-slim
2+
ENV DEBIAN_FRONTEND noninteractive
3+
4+
# Install OS dependencies
5+
RUN apt-get update && apt-get -yq dist-upgrade \
6+
&& apt-get install -yq --no-install-recommends \
7+
build-essential \
8+
bzip2 \
9+
cmake \
10+
curl \
11+
git \
12+
graphviz \
13+
libgtk2.0-dev \
14+
locales \
15+
sudo \
16+
unzip \
17+
vim \
18+
wget \
19+
ssh \
20+
gnupg2 \
21+
&& apt-get clean \
22+
&& rm -rf /var/lib/apt/lists/*
23+
24+
ENV SHELL=/bin/bash \
25+
LC_ALL=en_US.UTF-8 \
26+
LANG=en_US.UTF-8 \
27+
LANGUAGE=en_US.UTF-8 \
28+
DEEPNOTE_PYTHON_KERNEL_ONLY=true
29+
30+
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
31+
locale-gen

python/base/Dockerfile.python

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
ARG CIRCLE_PULL_REQUEST
2+
FROM debian:bullseye-slim AS builder
3+
4+
# Install dependencies for building Python
5+
RUN apt-get update && apt-get install -y --no-install-recommends \
6+
wget \
7+
cmake \
8+
build-essential \
9+
libssl-dev \
10+
zlib1g-dev \
11+
libncurses5-dev \
12+
libncursesw5-dev \
13+
libreadline-dev \
14+
libsqlite3-dev \
15+
libgdbm-dev \
16+
libdb5.3-dev \
17+
libbz2-dev \
18+
libexpat1-dev \
19+
liblzma-dev \
20+
tk-dev \
21+
libffi-dev \
22+
uuid-dev \
23+
ca-certificates \
24+
&& apt-get clean \
25+
&& rm -rf /var/lib/apt/lists/*
26+
27+
# Download and extract the Python source code
28+
WORKDIR /tmp
29+
ARG PYTHON_VERSION_PATCH
30+
RUN wget -qO- "https://www.python.org/ftp/python/${PYTHON_VERSION_PATCH}/Python-${PYTHON_VERSION_PATCH}.tgz" | tar xvz \
31+
&& cd "/tmp/Python-${PYTHON_VERSION_PATCH}" \
32+
&& ./configure --enable-optimizations --with-ensurepip=install \
33+
&& make -j "$(nproc)" \
34+
&& make altinstall
35+
36+
37+
FROM deepnote/python:base${CIRCLE_PULL_REQUEST:+-ra-${CIRCLE_PULL_REQUEST##*/}}
38+
# Copy Python from the builder stage
39+
ARG PYTHON_VERSION
40+
# Layers will be different between python versions from here onwards because of the build-arg
41+
42+
COPY --from=builder "/usr/local/bin/python${PYTHON_VERSION}" "/usr/local/bin/python${PYTHON_VERSION}"
43+
COPY --from=builder "/usr/local/bin/pip${PYTHON_VERSION}" "/usr/local/bin/pip${PYTHON_VERSION}"
44+
COPY --from=builder "/usr/local/lib/python${PYTHON_VERSION}" "/usr/local/lib/python${PYTHON_VERSION}"
45+
46+
RUN update-alternatives --install /usr/bin/python python "/usr/local/bin/python${PYTHON_VERSION}" 1
47+
RUN update-alternatives --install /usr/bin/pip pip "/usr/local/bin/pip${PYTHON_VERSION}" 1
48+
49+
# We create the virtual environment in the home directory in the Dockerfile
50+
# for performance improvement.
51+
RUN python -m venv --system-site-packages ~/venv

python/datascience/Dockerfile.datascience

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
ARG FROM_PYTHON_VERSION=3.8
2-
FROM deepnote/python:${FROM_PYTHON_VERSION}
1+
ARG PYTHON_VERSION=3.8
2+
ARG CIRCLE_PULL_REQUEST
3+
FROM deepnote/python:${PYTHON_VERSION}${CIRCLE_PULL_REQUEST:+-ra-${CIRCLE_PULL_REQUEST##*/}}
34

45
RUN pip install --upgrade pip
56

@@ -10,11 +11,11 @@ ADD requirements-below-3.11.txt /requirements-below-3.11.txt
1011
ADD constraints.txt /constraints.txt
1112

1213
#Determine the Python version and set the version-specifications file
13-
ARG FROM_PYTHON_VERSION
14+
ARG PYTHON_VERSION
1415

1516
RUN python -m pip install --upgrade setuptools pip
1617

17-
RUN if [ "$(printf '%s\n' "$FROM_PYTHON_VERSION" "3.11" | sort -V | head -n1)" = "3.11" ]; then \
18+
RUN if [ "$(printf '%s\n' "$PYTHON_VERSION" "3.11" | sort -V | head -n1)" = "3.11" ]; then \
1819
mv "requirements-3.11+.txt" "requirements.txt" \
1920
; else \
2021
mv "requirements-below-3.11.txt" "requirements.txt" \
@@ -28,4 +29,4 @@ RUN apt-get update \
2829
&& apt-get purge -y gcc \
2930
&& apt-get autoremove -y \
3031
&& apt-get clean \
31-
&& rm -rf /var/lib/apt/lists/* /root/.cache
32+
&& rm -rf /var/lib/apt/lists/* /root/.cache

0 commit comments

Comments
 (0)