Skip to content

Commit e73df36

Browse files
sagerbdotNomad
andauthored
Add multiple Quarto, R and Python versions into e2e docker images (#2606)
Co-authored-by: Jordan Jensen <jordan.jensen@posit.co>
1 parent 8d2d665 commit e73df36

File tree

18 files changed

+423
-1121
lines changed

18 files changed

+423
-1121
lines changed

test/e2e/Dockerfile.base

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Defines an image that has the basis for Connect or a User
2+
# Multiple versions of R, Python and Quarto are installed.
3+
4+
FROM ubuntu:22.04 AS base
5+
6+
# Configure apt-get to use the mirror in us-east-1 instead of the Docker default of archive.ubuntu.com
7+
RUN sed -i "s/archive.ubuntu.com/us-east-1.ec2.archive.ubuntu.com/g" /etc/apt/sources.list
8+
9+
ARG DEBIAN_FRONTEND=noninteractive
10+
ARG CONNECT_MANAGER_VERSION=0.5.1
11+
ARG CONNECT_OS=ubuntu22
12+
ARG OS_IDENTIFIER=ubuntu-2204
13+
RUN export TZ=America/New_York
14+
15+
# Install prerequisites
16+
RUN export DEBIAN_FRONTEND=noninteractive && \
17+
apt-get update && \
18+
apt-get install -y \
19+
build-essential \
20+
curl \
21+
dnsutils \
22+
dpkg-sig \
23+
gawk \
24+
gfortran \
25+
git \
26+
ldap-utils \
27+
libbz2-dev \
28+
libcurl4-openssl-dev \
29+
libdeflate-dev \
30+
libev-dev \
31+
libffi-dev \
32+
liblzma-dev \
33+
libncurses5-dev \
34+
libncursesw5-dev \
35+
libopenblas-dev \
36+
libpaper-utils \
37+
libpcre2-dev \
38+
libreadline-dev \
39+
libsodium-dev \
40+
libsqlite3-dev \
41+
libssl-dev \
42+
libtinfo5 \
43+
libxml2-dev \
44+
libzmq3-dev \
45+
llvm \
46+
mailcap \
47+
make \
48+
media-types \
49+
python3-openssl \
50+
rrdtool \
51+
software-properties-common \
52+
sssd-ldap \
53+
sudo \
54+
tk-dev \
55+
unzip \
56+
vim \
57+
wget \
58+
xz-utils \
59+
zip \
60+
zlib1g-dev
61+
62+
#
63+
# Install Multiple Versions of Python in parallel
64+
#
65+
66+
FROM base AS python-3.10.16
67+
# Install Python and make it default (used by build scripts)
68+
ARG PYTHON_VERSION=3.10.16
69+
RUN curl -fsSL -O https://cdn.rstudio.com/python/${OS_IDENTIFIER}/pkgs/python-${PYTHON_VERSION}_1_amd64.deb \
70+
&& export DEBIAN_FRONTEND=noninteractive \
71+
&& apt-get install -f -y ./python-${PYTHON_VERSION}_1_amd64.deb \
72+
&& rm python-${PYTHON_VERSION}_1_amd64.deb \
73+
&& /opt/python/${PYTHON_VERSION}/bin/pip install --upgrade pip setuptools wheel
74+
75+
FROM base AS python-3.11.11
76+
ARG PYTHON_VERSION=3.11.11
77+
RUN curl -fsSL -O https://cdn.rstudio.com/python/${OS_IDENTIFIER}/pkgs/python-${PYTHON_VERSION}_1_amd64.deb \
78+
&& export DEBIAN_FRONTEND=noninteractive \
79+
&& apt-get install -f -y ./python-${PYTHON_VERSION}_1_amd64.deb \
80+
&& rm python-${PYTHON_VERSION}_1_amd64.deb \
81+
&& /opt/python/${PYTHON_VERSION}/bin/pip install --upgrade pip setuptools wheel
82+
83+
FROM base AS python-3.12.9
84+
ARG PYTHON_VERSION=3.12.9
85+
RUN curl -fsSL -O https://cdn.rstudio.com/python/${OS_IDENTIFIER}/pkgs/python-${PYTHON_VERSION}_1_amd64.deb \
86+
&& export DEBIAN_FRONTEND=noninteractive \
87+
&& apt-get install -f -y ./python-${PYTHON_VERSION}_1_amd64.deb \
88+
&& rm python-${PYTHON_VERSION}_1_amd64.deb \
89+
&& /opt/python/${PYTHON_VERSION}/bin/pip install --upgrade pip setuptools wheel
90+
91+
#
92+
# Install Multiple Versions of R in parallel
93+
#
94+
95+
# Install R versions
96+
FROM base AS r-4.1.3
97+
ARG R_VERSION=4.1.3
98+
RUN curl -O https://cdn.rstudio.com/r/${OS_IDENTIFIER}/pkgs/r-${R_VERSION}_1_amd64.deb \
99+
&& apt-get install -y ./r-${R_VERSION}_1_amd64.deb \
100+
&& rm ./r-${R_VERSION}_1_amd64.deb
101+
102+
FROM base AS r-4.2.3
103+
ARG R_VERSION=4.2.3
104+
RUN curl -O https://cdn.rstudio.com/r/${OS_IDENTIFIER}/pkgs/r-${R_VERSION}_1_amd64.deb \
105+
&& apt-get install -y ./r-${R_VERSION}_1_amd64.deb \
106+
&& rm ./r-${R_VERSION}_1_amd64.deb
107+
108+
FROM base AS r-4.3.3
109+
ARG R_VERSION=4.3.3
110+
RUN curl -O https://cdn.rstudio.com/r/${OS_IDENTIFIER}/pkgs/r-${R_VERSION}_1_amd64.deb \
111+
&& apt-get install -y ./r-${R_VERSION}_1_amd64.deb \
112+
&& rm ./r-${R_VERSION}_1_amd64.deb
113+
114+
FROM base AS r-4.4.2
115+
ARG R_VERSION=4.4.2
116+
RUN curl -O https://cdn.rstudio.com/r/${OS_IDENTIFIER}/pkgs/r-${R_VERSION}_1_amd64.deb \
117+
&& apt-get install -y ./r-${R_VERSION}_1_amd64.deb \
118+
&& rm ./r-${R_VERSION}_1_amd64.deb
119+
120+
#
121+
# Install Multiple Versions of Quarto in parallel
122+
#
123+
124+
FROM base AS quarto-1.4.556
125+
ENV QUARTO_VERSION=1.4.556
126+
# from https://docs.posit.co/resources/install-quarto.html#download-install-quarto-tar
127+
RUN mkdir -p /opt/quarto/${QUARTO_VERSION} \
128+
&& curl -o quarto.tar.gz -L \
129+
"https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz" \
130+
&& tar -zxvf quarto.tar.gz -C "/opt/quarto/${QUARTO_VERSION}" --strip-components=1 \
131+
&& rm quarto.tar.gz
132+
133+
FROM base AS quarto-1.5.52
134+
ENV QUARTO_VERSION=1.5.52
135+
RUN mkdir -p /opt/quarto/${QUARTO_VERSION} \
136+
&& curl -o quarto.tar.gz -L \
137+
"https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz" \
138+
&& tar -zxvf quarto.tar.gz -C "/opt/quarto/${QUARTO_VERSION}" --strip-components=1 \
139+
&& rm quarto.tar.gz
140+
141+
FROM base AS quarto-1.6.42
142+
ENV QUARTO_VERSION=1.6.42
143+
RUN mkdir -p /opt/quarto/${QUARTO_VERSION} \
144+
&& curl -o quarto.tar.gz -L \
145+
"https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz" \
146+
&& tar -zxvf quarto.tar.gz -C "/opt/quarto/${QUARTO_VERSION}" --strip-components=1 \
147+
&& rm quarto.tar.gz
148+
149+
FROM base AS quarto-1.7.6
150+
ENV QUARTO_VERSION=1.7.6
151+
RUN mkdir -p /opt/quarto/${QUARTO_VERSION} \
152+
&& curl -o quarto.tar.gz -L \
153+
"https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-amd64.tar.gz" \
154+
&& tar -zxvf quarto.tar.gz -C "/opt/quarto/${QUARTO_VERSION}" --strip-components=1 \
155+
&& rm quarto.tar.gz
156+
157+
FROM base AS final-stage
158+
# Copy in our installed Python versions
159+
ARG PYTHON_VERSION=3.10.16
160+
COPY --from=python-3.10.16 /opt/python/3.10.16 /opt/python/3.10.16
161+
ARG PYTHON_VERSION=3.11.11
162+
COPY --from=python-3.11.11 /opt/python/3.11.11 /opt/python/3.11.11
163+
ARG PYTHON_VERSION=3.12.9
164+
COPY --from=python-3.12.9 /opt/python/3.12.9 /opt/python/3.12.9
165+
# Use the last version installed AS our default
166+
RUN ln -s /opt/python/3.10.16/bin/python /usr/local/bin/python3
167+
168+
# Copy in our installed R versions
169+
ARG R_VERSION=4.1.3
170+
COPY --from=r-4.1.3 /opt/R/4.1.3 /opt/R/4.1.3
171+
ARG R_VERSION=4.2.3
172+
COPY --from=r-4.2.3 /opt/R/4.2.3 /opt/R/4.2.3
173+
ARG R_VERSION=4.3.3
174+
COPY --from=r-4.3.3 /opt/R/4.3.3 /opt/R/4.3.3
175+
ARG R_VERSION=4.4.2
176+
COPY --from=r-4.4.2 /opt/R/4.4.2 /opt/R/4.4.2
177+
178+
# Symlink default (4.1.3) into path location
179+
ARG R_VERSION=4.1.3
180+
RUN ln -s /opt/R/4.1.3/bin/R /usr/local/bin/R \
181+
&& ln -s /opt/R/4.1.3/bin/Rscript /usr/local/bin/Rscript
182+
183+
# Copy in our installed Quarto versions
184+
ARG QUARTO_VERSION=1.4.556
185+
COPY --from=quarto-1.4.556 /opt/quarto/1.4.556 /opt/quarto/1.4.556
186+
ARG QUARTO_VERSION=1.5.52
187+
COPY --from=quarto-1.5.52 /opt/quarto/1.5.52 /opt/quarto/1.5.52
188+
ARG QUARTO_VERSION=1.6.42
189+
COPY --from=quarto-1.6.42 /opt/quarto/1.6.42 /opt/quarto/1.6.42
190+
ARG QUARTO_VERSION=1.7.6
191+
COPY --from=quarto-1.7.6 /opt/quarto/1.7.6 /opt/quarto/1.7.6
192+
193+
# symlink the earliest into the path location
194+
ARG QUARTO_VERSION=1.4.556
195+
RUN ln -s /opt/quarto/${QUARTO_VERSION}/bin/quarto /usr/bin/quarto
196+
197+
# clean up from our apt-update
198+
RUN rm -rf /var/lib/apt/lists/*

test/e2e/Dockerfile.connect

Lines changed: 75 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,81 @@
11
# Defines an image that installs connect-manager and a Connect DEB
22
# The Connect host to be used as the publishing target.
3+
# Multiple versions of R, Python and Quarto are installed and configured.
34

4-
FROM ubuntu:22.04 AS e2e-publisher-connect
5+
FROM e2ebase AS connect-publisher-e2e
56

6-
ARG DEBIAN_FRONTEND=noninteractive
7-
ARG R_VERSION=4.3.0
8-
ARG R_REPOSITORY=https://packagemanager.posit.co/cran/__linux__/jammy/latest
9-
ARG PYTHON_VERSION=3.11.3
10-
ARG CONNECT_MANAGER_VERSION=0.5.1
117
RUN export TZ=America/New_York
128

13-
# Install prerequisites
14-
RUN apt-get update && apt-get install -y \
15-
curl \
16-
xz-utils
9+
# Setup users and groups using cloned script from Connect's docker image:
10+
# docker/ubuntu24/Dockerfile
11+
12+
# An incoming Jenkins uid/gid alters how the account is created. Allows
13+
# matching uid/gid on the launching Jenkins agent. Configured late to keep
14+
# more layers reusable.
15+
ARG JENKINS_GID=999
16+
ARG JENKINS_UID=999
17+
18+
# Create the jenkins user with the same id:gid as the jenkins-node
19+
RUN groupadd -g $JENKINS_GID jenkins && \
20+
useradd -m -d /var/lib/jenkins -u $JENKINS_UID -g jenkins jenkins
21+
22+
# give jenkins root(sudo) access
23+
RUN echo "%jenkins ALL=(root) NOPASSWD:ALL" > /etc/sudoers.d/jenkins
24+
RUN chmod 440 /etc/sudoers.d/jenkins
25+
26+
# Create a cache dir owned by jenkins to prevent rosetta race condition on Apple
27+
# Silicon and allow Quarto content to run. Without this, the dir may be owned by
28+
# root.
29+
RUN mkdir -p /var/lib/jenkins/.cache && chown jenkins:jenkins /var/lib/jenkins/.cache
30+
31+
# The data-scientists group is use for testing permissions for shared group resources.
32+
# This group can be used when testing multi-user/alternate-user execution with a non-primary, shared group
33+
RUN groupadd data-scientists
1734

18-
# Install Python
19-
ADD https://astral.sh/uv/0.5.29/install.sh /uv-installer.sh
20-
RUN sh /uv-installer.sh && rm /uv-installer.sh
21-
ENV PATH="/root/.local/bin/:$PATH"
22-
RUN UV_PYTHON_INSTALL_DIR=/opt/python uv python install ${PYTHON_VERSION}
35+
# The rstudio-connect user mirrors the user we create during installation.
36+
# This user is often used as the default RunAs user by tests and when testing
37+
# primary-user execution.
38+
#
39+
# The rstudio-connect user DOES NOT have a home directory. Its primary group
40+
# is rstudio-connect. It is also a member of the shared data-scientists group
41+
RUN useradd -r -M -s /usr/sbin/nologin -G data-scientists \
42+
-c "System user for rstudio-connect daemon" rstudio-connect
2343

24-
# Install R
25-
RUN curl -O https://cdn.rstudio.com/r/ubuntu-2204/pkgs/r-${R_VERSION}_1_amd64.deb
26-
RUN apt-get install -y ./r-${R_VERSION}_1_amd64.deb
44+
# The shiny-runner user is an alternate RunAs user. This user can be used when
45+
# testing multi-user/alternate-user execution.
46+
#
47+
# The shiny-runner user DOES have a home directory. Its primary group is
48+
# shiny-runner. It is a member of the data-scientists, jenkins, and rstudio-connect groups.
49+
RUN useradd -r -m -s /usr/sbin/nologin -G data-scientists,jenkins,rstudio-connect \
50+
-c "Alternate RunAs user with home directory" shiny-runner
51+
52+
# The nohome-runner user is an alternate RunAs user. This user can be used
53+
# when testing multi-user/alternate user execution.
54+
#
55+
# The nohome-runner DOES NOT have a home directory. Its primary group is
56+
# nohome-runner. It is a member of the data-scientists, jenkins, and rstudio-connect groups.
57+
RUN useradd -r -M -s /usr/sbin/nologin -G data-scientists,jenkins,rstudio-connect \
58+
-c "Alternate RunAs user without a home directory" nohome-runner
59+
60+
# Ths nonmember-runner user is an invalid RunAs user. This user can be used
61+
# when testing group validation.
62+
#
63+
# The nonmember-runner user is NOT a member of the jenkins or rstudio-connect
64+
# groups.
65+
RUN useradd -r -m -s /usr/sbin/nologin \
66+
-c "Alternate RunAs user with home directory" nonmember-runner
67+
68+
# because licensing
69+
RUN mkdir /var/lib/rstudio-connect
70+
71+
# Enable git when running as users other than the GH actions runner
72+
# https://github.com/actions/checkout/issues/766
73+
RUN git config --global --add safe.directory /connect
74+
RUN su - jenkins -c 'git config --global --add safe.directory /connect'
2775

2876
WORKDIR /opt/connect-manager
2977

78+
ARG CONNECT_MANAGER_VERSION=0.5.1
3079
RUN curl -fsSL "https://cdn.rstudio.com/connect/connect-manager/${CONNECT_MANAGER_VERSION}/connect-manager-${CONNECT_MANAGER_VERSION}.tar.xz" | tar --strip-components=1 -xvJf -
3180

3281
RUN tar \
@@ -42,21 +91,21 @@ RUN rm -f \
4291
connect_manager_client-*.whl
4392

4493
# Pull and Install Connect .deb
45-
RUN curl -O https://cdn.posit.co/connect/2024.12/rstudio-connect_2024.12.0~ubuntu22_amd64.deb
46-
47-
RUN apt-get update \
48-
&& apt-get install -y ./rstudio-connect_2024.12.0~ubuntu22_amd64.deb \
49-
&& rm -rf rstudio-connect_2024.12.0~ubuntu22_amd64.deb \
50-
&& apt-get clean \
51-
&& rm -rf /var/lib/apt/lists/*
94+
ARG CONNECT_OS=ubuntu22
95+
RUN curl -O https://cdn.posit.co/connect/2025.02/rstudio-connect_2025.02.0~${CONNECT_OS}_amd64.deb \
96+
&& apt-get update \
97+
&& apt-get install -y ./rstudio-connect_2025.02.0~${CONNECT_OS}_amd64.deb \
98+
&& rm -rf rstudio-connect_2025.02.0~${CONNECT_OS}_amd64.deb \
99+
&& apt-get clean \
100+
&& rm -rf /var/lib/apt/lists/*
52101

53102
# Copy Connect config
54103
COPY test/e2e/config/connect.gcfg /etc/rstudio-connect/rstudio-connect.gcfg
55104

56105
# Copy Bootstrap Key
57106
COPY test/e2e/bootstrap-secret.key /etc/rstudio-connect/bootstrap-secret.key
58107

59-
ENV CONNECT_LICENSE ${CONNECT_LICENSE}
108+
ENV CONNECT_LICENSE=$(CONNECT_LICENSE)
60109

61110
CMD [ "/opt/connect-manager/connect-manager", \
62111
"--start-connect", \

test/e2e/Dockerfile.vscode

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,38 @@
1-
# Defines an image that installs code-server and the Publisher extension to it
1+
# Image which contains:
2+
# Multiple Versions of R, Python and Quarto
3+
# VS Code server with extensions for python, r and quarto
24

3-
FROM codercom/code-server:39 AS code-server
5+
FROM e2ebase AS code-server
6+
7+
RUN export TZ=America/New_York
8+
9+
#
10+
# Install code-server
11+
#
12+
13+
RUN curl -fsSL https://code-server.dev/install.sh | sh
14+
15+
# extensions to code-server
16+
RUN code-server --install-extension ms-python.python \
17+
&& code-server --install-extension quarto.quarto
18+
19+
# create a code-server config file and set password to none
20+
RUN mkdir -p ~/.config/code-server \
21+
&& printf "bind-addr: 127.0.0.1:8080\nauth: none\ncert: false" > ~/.config/code-server/config.yaml
22+
23+
# turn off workspace trusting
24+
RUN mkdir -p /root/.local/share/code-server/User \
25+
&& printf '{\n\t"security.workspace.trust.enabled": false,\n\t"security.workspace.trust.banner": "never",\n\t"security.workspace.trust.startupPrompt": "never"\n}' \
26+
> /root/.local/share/code-server/User/settings.json
27+
28+
# Expose port
29+
EXPOSE 8080
430

531
WORKDIR /home/coder/workspace
32+
ENV DEFAULT_WORKSPACE=/home/coder/workspace
633

7-
ENTRYPOINT ["/home/coder/entrypoint.sh"]
34+
# Start code-server
35+
#
36+
# use http://localhost:8080?folder=/home/coder/workspace to connect to code server and open our test dir
37+
#
38+
ENTRYPOINT ["/home/coder/entrypoint.sh"]

0 commit comments

Comments
 (0)