Skip to content

Commit

Permalink
Merge pull request #198 from cs50/r
Browse files Browse the repository at this point in the history
Adds support for R, tidied Dockerfile
  • Loading branch information
dmalan authored Jan 27, 2024
2 parents 4da9f31 + d7e621d commit 7d990b6
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 65 deletions.
153 changes: 95 additions & 58 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,54 @@
# Build statge
# Build stage
FROM ubuntu:22.04 as builder
ARG DEBIAN_FRONTEND=noninteractive


# Stage-wide dependencies
RUN apt update && \
apt install --no-install-recommends --no-install-suggests --yes \
build-essential \
ca-certificates \
curl


# Install Java 21.x
# http://jdk.java.net/21/
RUN cd /tmp && \
if [ $(uname -m) = "x86_64" ]; then ARCH="x64"; else ARCH="aarch64"; fi && \
curl --remote-name https://download.java.net/java/GA/jdk21.0.2/f2283984656d49d69e91c558476027ac/13/GPL/openjdk-21.0.2_linux-${ARCH}_bin.tar.gz && \
tar xzf openjdk-21.0.2_linux-${ARCH}_bin.tar.gz && \
rm --force openjdk-21.0.2_linux-${ARCH}_bin.tar.gz && \
mv jdk-21.0.2 /opt/jdk && \
mkdir --parent /opt/bin && \
ln --symbolic /opt/jdk/bin/* /opt/bin/ && \
chmod a+rx /opt/bin/*


# Install Node.js 21.x
# https://nodejs.dev/en/download/
# https://github.com/tj/n#installation
RUN curl --location https://raw.githubusercontent.com/tj/n/master/bin/n --output /usr/local/bin/n && \
chmod a+x /usr/local/bin/n && \
n 21.6.1


# Install Node.js packages
RUN npm install --global \
http-server


# Patch index.js in http-server
COPY index.js.patch /tmp
RUN cd /usr/local/lib/node_modules/http-server/lib/core/show-dir && \
patch index.js < /tmp/index.js.patch && \
rm --force /tmp/index.js.patch


# Suggested build environment for Python, per pyenv, even though we're building ourselves
# https://github.com/pyenv/pyenv/wiki#suggested-build-environment
RUN apt update && \
apt install --no-install-recommends --no-install-suggests --yes \
curl ca-certificates build-essential git \
build-essential ca-certificates curl git \
libssl-dev libbz2-dev libreadline-dev libsqlite3-dev \
llvm libncursesw5-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev \
make tk-dev unzip wget xz-utils zlib1g-dev
Expand All @@ -16,7 +57,7 @@ RUN apt update && \
# Install Python 3.11.x
# https://www.python.org/downloads/
RUN cd /tmp && \
curl https://www.python.org/ftp/python/3.11.7/Python-3.11.7.tgz --output Python-3.11.7.tgz && \
curl --remote-name https://www.python.org/ftp/python/3.11.7/Python-3.11.7.tgz && \
tar xzf Python-3.11.7.tgz && \
rm --force Python-3.11.7.tgz && \
cd Python-3.11.7 && \
Expand All @@ -31,14 +72,32 @@ RUN cd /tmp && \
pip3 install --no-cache-dir --upgrade pip


# Install R
# https://docs.posit.co/resources/install-r-source/#build-and-install-r
# https://cran.rstudio.com/src/base/R-4/
RUN sed --in-place "/^#.*deb-src.*universe$/s/^# //g" /etc/apt/sources.list && \
apt update && \
apt build-dep --yes r-base && \
cd /tmp && \
curl --remote-name https://cran.rstudio.com/src/base/R-4/R-4.3.2.tar.gz && \
tar xzf R-4.3.2.tar.gz && \
rm --force R-4.3.2.tar.gz && \
cd R-4.3.2 && \
./configure --enable-memory-profiling --enable-R-shlib && \
make && \
make install && \
cd .. && \
rm --force --recursive R-4.3.2


# Install Ruby 3.2.x
# https://www.ruby-lang.org/en/downloads/
RUN apt update && \
apt install --no-install-recommends --no-install-suggests --yes \
autoconf \
libyaml-dev && \
apt clean && \
rm -rf /var/lib/apt/lists/* && \
rm --force --recursive /var/lib/apt/lists/* && \
cd /tmp && \
curl https://cache.ruby-lang.org/pub/ruby/3.2/ruby-3.2.2.tar.gz --output ruby-3.2.2.tar.gz && \
tar xzf ruby-3.2.2.tar.gz && \
Expand Down Expand Up @@ -66,64 +125,33 @@ RUN gem install --no-document \
# https://www.sqlite.org/howtocompile.html#compiling_the_command_line_interface
COPY shell.c.patch /tmp
RUN cd /tmp && \
curl --remote-name https://www.sqlite.org/2023/sqlite-amalgamation-3440200.zip && \
unzip sqlite-amalgamation-3440200.zip && \
rm --force sqlite-amalgamation-3440200.zip && \
cd sqlite-amalgamation-3440200 && \
curl --remote-name https://www.sqlite.org/2024/sqlite-amalgamation-3450000.zip && \
unzip sqlite-amalgamation-3450000.zip && \
rm --force sqlite-amalgamation-3450000.zip && \
cd sqlite-amalgamation-3450000 && \
patch shell.c < /tmp/shell.c.patch && \
gcc -D HAVE_READLINE -D SQLITE_DEFAULT_FOREIGN_KEYS=1 -D SQLITE_OMIT_DYNAPROMPT=1 shell.c sqlite3.c -lpthread -ldl -lm -lreadline -lncurses -o /usr/local/bin/sqlite3 && \
cd .. && \
rm --force --recursive sqlite-amalgamation-3440200 && \
rm --force --recursive sqlite-amalgamation-3450000 && \
rm --force /tmp/shell.c.patch
# Install Java 21.x
# http://jdk.java.net/21/
RUN cd /tmp && \
curl --remote-name https://download.java.net/java/GA/jdk21.0.1/415e3f918a1f4062a0074a2794853d0d/12/GPL/openjdk-21.0.1_linux-x64_bin.tar.gz && \
tar xzf openjdk-21.0.1_linux-x64_bin.tar.gz && \
rm --force openjdk-21.0.1_linux-x64_bin.tar.gz && \
mv jdk-21.0.1 /opt/ && \
mkdir --parent /opt/bin && \
ln --symbolic /opt/jdk-21.0.1/bin/* /opt/bin/ && \
chmod a+rx /opt/bin/*
# Install Node.js 21.x
# https://nodejs.dev/en/download/
# https://github.com/tj/n#installation
RUN curl --location https://raw.githubusercontent.com/tj/n/master/bin/n --output /usr/local/bin/n && \
chmod a+x /usr/local/bin/n && \
n 21.5.0
# Install GitHub CLI
# https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-raspberry-pi-os-apt
RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \
apt update && \
apt install gh --no-install-recommends --no-install-suggests --yes
# Final stage
FROM ubuntu:22.04
LABEL maintainer="[email protected]"
ARG DEBIAN_FRONTEND=noninteractive
# Copy files from builder
COPY --from=builder /usr /usr
COPY --from=builder /opt /opt
COPY --from=builder /usr/local /usr/local
# Avoid "delaying package configuration, since apt-utils is not installed"
# Install locales
RUN apt update && \
apt install --no-install-recommends --no-install-suggests --yes \
apt-utils \
curl \
ca-certificates \
locales && \
locale-gen \
en_US.utf8 \
Expand All @@ -145,16 +173,18 @@ RUN apt update && \
ENV LANG=C.UTF-8
# Install CS50, Ubuntu, and Python packages
RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh | bash && \
apt update && \
# Install Ubuntu packages
RUN apt update && \
apt upgrade --yes && \
apt install --no-install-recommends --no-install-suggests --yes \
astyle \
bash-completion \
build-essential `# dpkg-dev, libc, gcc, g++, make, etc.`\
ca-certificates \
clang \
coreutils `# For fold` \
cowsay \
curl \
dos2unix \
dnsutils `# For nslookup` \
fonts-noto-color-emoji `# For render50` \
Expand All @@ -163,7 +193,7 @@ RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh |
git-lfs \
jq \
less \
libcs50 \
liblapack3 `# For R` \
libmagic-dev `# For style50` \
libpango-1.0-0 libharfbuzz0b libpangoft2-1.0-0 `# For render50` \
libyaml-0-2 `# Runtime package for gem` \
Expand All @@ -178,9 +208,19 @@ RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh |
unzip \
valgrind \
vim \
wget \
zip && \
apt clean && \
pip3 install --no-cache-dir \
apt clean
# Install CS50 library
RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh | bash && \
apt update && \
apt install --yes libcs50
# Install Python packages
RUN pip3 install --no-cache-dir \
autopep8 \
black \
"check50<4" \
Expand All @@ -196,16 +236,13 @@ RUN curl https://packagecloud.io/install/repositories/cs50/repo/script.deb.sh |
"submit50<4"
# Install Node.js packages
RUN npm install --global \
[email protected] `# Fixate for patch`
# Patch index.js in http-server
COPY index.js.patch /tmp
RUN cd /usr/local/lib/node_modules/http-server/lib/core/show-dir && \
patch index.js < /tmp/index.js.patch && \
rm --force /tmp/index.js.patch
# Install GitHub CLI (after builder stage, because writes to /usr/share)
# https://github.com/cli/cli/blob/trunk/docs/install_linux.md#debian-ubuntu-linux-raspberry-pi-os-apt
RUN curl --fail --location --show-error --silent https://cli.github.com/packages/githubcli-archive-keyring.gpg | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
chmod go+r /usr/share/keyrings/githubcli-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | tee /etc/apt/sources.list.d/github-cli.list > /dev/null && \
apt update && \
apt install --no-install-recommends --no-install-suggests --yes gh
# Copy files to image
Expand Down Expand Up @@ -245,4 +282,4 @@ ONBUILD USER ubuntu
# Set user
USER ubuntu
WORKDIR /home/ubuntu
ENV WORKDIR=/home/ubuntu
ENV WORKDIR=/home/ubuntu
1 change: 1 addition & 0 deletions etc/profile.d/cli.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ if [ "$(whoami)" != "root" ]; then
alias mv="mv -i"
alias pip="pip --no-cache-dir"
alias python="python -q"
alias R="R --vanilla"
alias rm="rm -i"
alias sudo="sudo " # Trailing space enables elevated command to be an alias

Expand Down
9 changes: 2 additions & 7 deletions shell.c.patch
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
# diff shell.c shell_modified.c > shell.c.patch
29321,29323c29321,29323
< oputf("SQLite version %s %.19s%s\n" /*extra-version-info*/
29438,29440d29437
< sputf(stdout, "SQLite version %s %.19s%s\n" /*extra-version-info*/
< "Enter \".help\" for usage hints.\n",
< sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);
---
> //oputf("SQLite version %s %.19s%s\n" /*extra-version-info*/
> // "Enter \".help\" for usage hints.\n",
> // sqlite3_libversion(), sqlite3_sourceid(), SHELL_CIO_CHAR_SET);

0 comments on commit 7d990b6

Please sign in to comment.