Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] Make the Dockerfile be able to support itself + fix various issues #4

Draft
wants to merge 24 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
4902a14
fix: Fix "dubious ownership" issues with git by creating a user
itislu Feb 5, 2025
acd22ad
docs: Add note that first time building can take some time
itislu Feb 5, 2025
281c799
improve: Make .ssh directory read-only
itislu Feb 5, 2025
ca5f8fd
improve: Use multistage build
itislu Feb 6, 2025
b37c321
feat: Install `scan-build`
itislu Feb 6, 2025
ad8b90e
refactor: Remove reliance on devcontainer feature and set up everythi…
itislu Feb 6, 2025
0cad60c
fix: Ensure francinette alias exists in zsh
itislu Feb 6, 2025
f422c65
feat: Share zsh history with host
itislu Feb 6, 2025
410fa03
refactor: Remove duplicate Dockerfile and always install .devcontainer
itislu Feb 6, 2025
b2592ad
fix: Fix zsh history saving issue
itislu Feb 6, 2025
0f12334
docs: Add command to attach to container in the shell
itislu Feb 6, 2025
53a40eb
chore: Install packages in one layer to reduce image size + sort by c…
itislu Feb 7, 2025
052af6c
chore: Move MLX and norminette installation further up
itislu Feb 7, 2025
8c01744
feat: Add support for `.env` file
itislu Feb 7, 2025
00a45a8
perf: Improve build speed by compiling with all CPU cores
itislu Feb 7, 2025
3126527
style: Rename compose service + name all docker stages
itislu Feb 7, 2025
f75632a
feat: Install `ncdu`
itislu Feb 8, 2025
b2a8b4f
feat: Install `man`
itislu Feb 8, 2025
16b7739
improve: Set the `SHELL` variable
itislu Feb 8, 2025
5ff5c43
fix: Fix .gitconfig "resource busy" issue
itislu Feb 8, 2025
62747c5
feat: Install `fish` and provide comments how to import own shell con…
itislu Feb 8, 2025
0715700
fix: Ensure francinette aliases exist if user uses their own rc files
itislu Feb 8, 2025
a51fd19
fix: Fix support for special characters
itislu Feb 9, 2025
fe6540f
chore: Try more libraries to make MLX work
itislu Feb 9, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 161 additions & 70 deletions .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,62 +1,29 @@
# Start from Ubuntu 22.04 (Jammy Jellyfish)
FROM ubuntu:22.04
# Builder stage
FROM ubuntu:22.04 AS builder

# Add LLVM and GCC repositories
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive && apt-get -y install \
wget \
gnupg \
software-properties-common \
&& wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \
&& add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main" \
&& add-apt-repository ppa:ubuntu-toolchain-r/test

# Update the system and install utils
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y \
sudo \
cmake \
meson \
valgrind \
# Install build dependencies
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
build-essential \
binutils \
clang \
clang-14 \
clang-12 \
lldb-12 \
gdb \
gcc-11=11.4.0-1ubuntu1~22.04 \
g++-11=11.4.0-1ubuntu1~22.04 \
gcc-10=10.5.0-1ubuntu1~22.04 \
g++-10=10.5.0-1ubuntu1~22.04 \
zsh \
ca-certificates \
gcc \
git \
make \
wget \
curl \
python3 python3-venv python3-pip \
libreadline-dev \
libreadline8 \
xorg libxext-dev zlib1g-dev libbsd-dev \
libcmocka-dev \
pkg-config \
cppcheck \
clangd \
# Minilibx dependencies
libbsd-dev \
libx11-dev \
libxext-dev \
xorg \
zlib1g-dev \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*

# Set up compiler aliases
RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-12 100 \
&& update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-12 100 \
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 \
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 100 \
&& update-alternatives --install /usr/bin/cc cc /usr/bin/clang-12 100 \
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-12 100

# Valgrind 3.18.1
RUN wget https://sourceware.org/pub/valgrind/valgrind-3.18.1.tar.bz2 \
&& tar -xjf valgrind-3.18.1.tar.bz2 \
&& cd valgrind-3.18.1 \
&& ./configure \
&& make \
&& make install \
&& sudo ldconfig \
&& make -j \
&& make -j install DESTDIR=/install \
&& cd .. \
&& rm -rf valgrind-3.18.1*

Expand All @@ -65,8 +32,8 @@ RUN wget http://ftp.gnu.org/gnu/make/make-4.3.tar.gz \
&& tar -xvzf make-4.3.tar.gz \
&& cd make-4.3 \
&& ./configure \
&& make \
&& sudo make install \
&& make -j \
&& make -j install DESTDIR=/install \
&& cd .. \
&& rm -rf make-4.3*

Expand All @@ -75,37 +42,161 @@ RUN wget https://ftp.gnu.org/gnu/readline/readline-8.1.tar.gz \
&& tar -xzvf readline-8.1.tar.gz \
&& cd readline-8.1 \
&& ./configure --enable-shared \
&& make \
&& sudo make install \
&& sudo ldconfig \
&& make -j \
&& make -j install DESTDIR=/install \
&& cd .. \
&& rm -rf readline-8.1*

# Create a virtual environment and activate it
RUN python3 -m venv /opt/venv
RUN chown -R $USER:$USER /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Install MLX library
RUN git clone https://github.com/42Paris/minilibx-linux.git \
&& cd minilibx-linux \
&& make -j \
&& mkdir -p /install/usr/local/lib \
&& mkdir -p /install/usr/local/include \
&& mkdir -p /install/usr/local/share/man/man3 \
&& cp libmlx.a /install/usr/local/lib \
&& cp mlx.h /install/usr/local/include \
&& gzip -9 man/man3/mlx*.3 \
&& cp man/man3/mlx*.3.gz /install/usr/local/share/man/man3 \
&& cd .. \
&& rm -rf minilibx-linux


# Final stage
FROM ubuntu:22.04 AS final

# Comment out man and doc exclusions from Minimal Ubuntu base image to keep documentation
RUN sed -i \
-e '/path-exclude=\/usr\/share\/man/s/^/#/' \
-e '/path-exclude=\/usr\/share\/doc/s/^/#/' \
/etc/dpkg/dpkg.cfg.d/excludes || true

# Install packages
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive && apt-get install -y \
# Man pages
man-db \
manpages \
manpages-dev \
manpages-posix \
manpages-posix-dev \
&& /usr/bin/mandb \
&& mv /usr/bin/man.REAL /usr/bin/man \
&& apt-get install -y \
# System utilities
curl \
git \
gnupg \
locales \
software-properties-common \
sudo \
wget \
zsh \
# Add LLVM and GCC repositories
&& wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add - \
&& add-apt-repository "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-12 main" \
&& add-apt-repository ppa:ubuntu-toolchain-r/test \
&& apt-get install -y \
# Build tools and compilers
binutils \
build-essential \
clang \
clang-14 \
clang-12 \
cmake \
gcc-11=11.4.0-1ubuntu1~22.04 \
g++-11=11.4.0-1ubuntu1~22.04 \
gcc-10=10.5.0-1ubuntu1~22.04 \
g++-10=10.5.0-1ubuntu1~22.04 \
meson \
# Development tools
clang-tools \
clang-tools-12 \
clangd \
cppcheck \
gdb \
lldb-12 \
valgrind \
# Libraries
libbsd-dev \
libcmocka-dev \
libreadline-dev \
libreadline8 \
libx11-dev \
libxext-dev \
pkg-config \
xorg \
zlib1g-dev \
# User utilities
fish \
python3 \
python3-pip \
python3-venv \
ncdu \
rsync \
&& apt-get autoremove -y && apt-get clean -y && rm -rf /var/lib/apt/lists/*

# Set up compiler aliases
RUN update-alternatives --install /usr/bin/clang clang /usr/bin/clang-12 100 \
&& update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-12 100 \
&& update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 100 \
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 100 \
&& update-alternatives --install /usr/bin/cc cc /usr/bin/clang-12 100 \
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++-12 100

# Upgrade pip and setuptools and install norminette
# Copy built artifacts from builder
COPY --from=builder /install /

# Install norminette
RUN python3 -m pip install --upgrade pip setuptools
RUN python3 -m pip install norminette

# Install MLX library
RUN cd $HOME \
&& git clone https://github.com/42Paris/minilibx-linux.git \
&& cd minilibx-linux \
&& make \
&& sudo cp mlx.h /usr/local/include \
&& sudo cp libmlx.a /usr/local/lib
# Configure default user and workspace paths
# These can be overridden at build time using --build-arg
ARG USERNAME=devcontainer
ARG UID=1000
ARG GID=1000

# Create the user
RUN groupadd --gid $GID $USERNAME \
&& useradd --uid $UID --gid $GID -m $USERNAME \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \
&& chmod 0440 /etc/sudoers.d/$USERNAME

# Set the default home directory
ARG HOME=/home/$USERNAME

# Install oh-my-zsh
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

# Create a virtual environment and activate it
RUN python3 -m venv /opt/venv \
&& chown -R $USERNAME:$USERNAME /opt/venv
ENV PATH="/opt/venv/bin:$PATH"

# Install francinette
RUN bash -c "$(curl -fsSL https://raw.github.com/xicodomingues/francinette/master/bin/install.sh)"

# Install oh-my-zsh
RUN sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" || true
RUN echo "source $HOME/.oh-my-zsh/oh-my-zsh.sh" >> $HOME/.zshrc
# Change ownership of installed tools to the new user
RUN chown -R $USERNAME:$USERNAME $HOME

# Change zsh history to append mode to avoid error messages
RUN echo "unsetopt HIST_SAVE_BY_COPY" >> /etc/zsh/zshrc

# Copy entrypoint script from build context
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh

# Set the default user
USER $USERNAME
ENV USER=$USERNAME

# Set useful environment variables
ENV SHELL=/bin/zsh
ENV LANG=C.UTF-8

# Set the working directory in the container
WORKDIR /app
ARG WORKSPACE_FOLDER=/app
WORKDIR "/${WORKSPACE_FOLDER#/}"

CMD ["/bin/zsh"]
ENTRYPOINT [ "/usr/local/bin/entrypoint.sh" ]
CMD [ "/bin/zsh" ]
32 changes: 23 additions & 9 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
{
"name": "42-Docker-DevEnv",
"build": {
"dockerfile": "Dockerfile"
"dockerfile": "Dockerfile",
"context": ".",
"args": {
"USERNAME": "${env:USERNAME:devcontainer}",
"UID": "${env:UID:1000}",
"GID": "${env:GID:1000}",
"WORKSPACE_FOLDER": "/workspaces/${localWorkspaceFolderBasename}"
}
},
"runArgs": ["--privileged"],
// Ensure directories and files to be mounted exist
"initializeCommand": "mkdir -p ${env:HOME}/.config/fish ${env:HOME}/.ssh && touch ${env:HOME}/.bashrc ${env:HOME}/.gitconfig ${env:HOME}/.zsh_history ${env:HOME}/.zshrc",
"postCreateCommand": "entrypoint.sh",
"mounts": [
// Synced
"source=${env:HOME}/.zsh_history,target=/home/${env:USERNAME:devcontainer}/.zsh_history,type=bind,consistency=cached",
// Read-only and copy
"source=${env:HOME}/.gitconfig,target=/mnt/.gitconfig,type=bind,consistency=cached,readonly=true",
"source=${env:HOME}/.ssh,target=/mnt/.ssh,type=bind,consistency=cached,readonly=true",
// Comment in to load shell config files from your local environment
// "source=${env:HOME}/.bashrc,target=/mnt/.bashrc,type=bind,consistency=cached,readonly=true",
// "source=${env:HOME}/.config/fish,target=/mnt/.config/fish,type=bind,consistency=cached,readonly=true",
// "source=${env:HOME}/.zshrc,target=/mnt/.zshrc,type=bind,consistency=cached,readonly=true",
],
"customizations": {
"vscode": {
"settings": {
Expand All @@ -28,11 +48,5 @@
"tomoki1207.pdf" // Display PDF files in VS Code
]
}
},
"initializeCommand": "mkdir -p ${env:HOME}/.ssh && touch ${env:HOME}/.gitconfig ${env:HOME}/.zshrc",
"mounts": [
"source=${env:HOME}/.ssh,target=/root/.ssh,type=bind,consistency=cached",
"source=${env:HOME}/.gitconfig,target=/root/.gitconfig,type=bind,consistency=cached",
"source=${env:HOME}/.zshrc,target=/root/.zshrc,type=bind,consistency=cached"
]
}
}
29 changes: 29 additions & 0 deletions .devcontainer/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

# Copy all files mounted in /mnt to user's home directory
mount_dir="/mnt"
dest_dir="$HOME"
shopt -s dotglob nullglob
for item_path in "$mount_dir"/*; do
item=$(basename "$item_path")
cp -ru "$item_path" "$dest_dir" \
&& chown -R "$USER:$USER" "$dest_dir/$item"
done
shopt -u dotglob nullglob

# Set up francinette aliases
rc_files=( "$HOME/.bashrc" "$HOME/.config/fish/config.fish" "$HOME/.zshrc" )
for rc_file in "${rc_files[@]}"; do
mkdir -p "$(dirname "$rc_file")"
if ! grep "francinette=" "$rc_file" &> /dev/null; then
printf "\nalias francinette=%s/francinette/tester.sh\n" "$HOME" >> "$rc_file"
fi
if ! grep "paco=" "$rc_file" &> /dev/null; then
printf "\nalias paco=%s/francinette/tester.sh\n" "$HOME" >> "$rc_file"
fi
first_level=${rc_file#"$HOME/"}
first_level=${first_level%%/*}
chown -R "$USER:$USER" "$HOME/$first_level"
done

exec "$@"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.DS_Store
.env
Loading