Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions containers/base/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,10 @@ RUN echo "$DEV_USER ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
ENV VOLS_DIR="/vols"
RUN mkdir -m 755 $VOLS_DIR

# Create directory to hold volume initialization data
ENV VOLS_INIT_DIR="$VOLS_DIR/.init"
RUN mkdir -m 755 $VOLS_INIT_DIR

# Make a directory for shell config
ENV SHELL_CONFIG_DIR="$VOLS_DIR/shell"
RUN mkdir -m 755 $SHELL_CONFIG_DIR \
Expand Down
57 changes: 30 additions & 27 deletions containers/emacs/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,33 +63,47 @@ RUN curl -fL -o $FD_FILE "$FD_URL" \
&& dpkg -i $FD_FILE \
&& rm -f $FD_FILE

# Switch to non-root user
USER $DEV_USER
WORKDIR $DEV_USER_HOME

# Doom Emacs variables
# Doom Emacs variables from the cache image
ARG DE_EMACS_DIR="/vols/emacs.d"
ARG DE_DOOM_DIR="/vols/doom.d"

# Straight makes heavy use of symlinks with absolute paths for its internal
# organization. Copying those symlinks will break them, unless the absolute
# paths stay the same. That is to say, $DE_EMACS_DIR must equal
# $EMACS_CONFIG_DIR, etc.
ENV EMACS_CONFIG_DIR="$DE_EMACS_DIR"
ENV DOOM_CONFIG_DIR="$DE_DOOM_DIR"
ENV EMACS_CONFIG_DIR=$DE_EMACS_DIR
ENV DOOM_CONFIG_DIR=$DE_DOOM_DIR

# Make blank directories to ensure permissions are set correctly
RUN sudo mkdir -m 755 $EMACS_CONFIG_DIR $DOOM_CONFIG_DIR \
&& sudo chown $DEV_USER:$DEV_USER $EMACS_CONFIG_DIR $DOOM_CONFIG_DIR
RUN mkdir -m 755 $EMACS_CONFIG_DIR $DOOM_CONFIG_DIR \
&& chown $DEV_USER:$DEV_USER $EMACS_CONFIG_DIR $DOOM_CONFIG_DIR

# Add Doom executables to PATH
ENV PATH=$EMACS_CONFIG_DIR/bin:$PATH

# Set environment variables used by Doom
ENV EMACSDIR=$EMACS_CONFIG_DIR
ENV DOOMDIR=$DOOM_CONFIG_DIR

# Tarballs which will be made to initialize Emacs volumes
ENV EMACS_CONFIG_TARBALL="$VOLS_INIT_DIR/emacs.d.tar.gz"
ENV DOOM_CONFIG_TARBALL="$VOLS_INIT_DIR/doom.d.tar.gz"

# Create tarballs for the Emacs Doom config files
RUN --mount=type=bind,from=doom-cache,src=$DE_EMACS_DIR,dst=$EMACS_CONFIG_DIR \
tar -C $EMACS_CONFIG_DIR --create -z -f $EMACS_CONFIG_TARBALL .
RUN --mount=type=bind,from=doom-cache,src=$DE_DOOM_DIR,dst=$DOOM_CONFIG_DIR \
tar -C $DOOM_CONFIG_DIR --create -z -f $DOOM_CONFIG_TARBALL .

# Switch to non-root user
USER $DEV_USER
WORKDIR $DEV_USER_HOME

# Add links to the home directory
RUN ln -s $EMACS_CONFIG_DIR $DEV_USER_HOME/.emacs.d \
&& ln -s $DOOM_CONFIG_DIR $DEV_USER_HOME/.doom.d

# Copy files from the build layer
COPY --from=doom-cache --chown=$DEV_USER:$DEV_USER $DE_EMACS_DIR $EMACS_CONFIG_DIR
COPY --from=doom-cache --chown=$DEV_USER:$DEV_USER $DE_DOOM_DIR $DOOM_CONFIG_DIR

# Doom font variables
ARG DE_NERDFONT_URL="https://raw.githubusercontent.com/rainstormstudio/nerd-icons.el/main/fonts/NFM.ttf"
ARG DE_NERDFONT_FILE="$DEV_USER_HOME/.local/share/fonts/NFM.ttf"
Expand All @@ -99,20 +113,6 @@ RUN mkdir -p $(dirname $DE_NERDFONT_FILE) \
&& curl -fL -o $DE_NERDFONT_FILE "$DE_NERDFONT_URL" \
&& fc-cache -f

# Add Doom executables to PATH
ENV PATH=$EMACS_CONFIG_DIR/bin:$PATH

# Set environment variables used by Doom
ENV EMACSDIR=$DE_EMACS_DIR
ENV DOOMDIR=$DE_DOOM_DIR

# Build the VTerm module. We must locate the exact build directory because it's
# name depends on the Emacs version, e.g., `build-28.1`, etc.
RUN VTERM_BUILD_DIR=$(fd -uu -p "build-[0-9.]+/vterm$" $EMACS_CONFIG_DIR) \
&& cd $VTERM_BUILD_DIR \
&& cmake -S . -B build \
&& cmake --build build

# Add VTerm integration to Bash config
RUN { \
echo; \
Expand All @@ -124,11 +124,14 @@ RUN { \
echo "fi"; \
} >> $DEV_USER_HOME/.bashrc

# Copy entry point for config initialization
COPY emacs_init.sh $ENTRYPOINT_DIR/80_emacs_init.sh

# Persistent storage for the Emacs and Doom config directories. These
# directories will be initialized with the Doom files from above.
VOLUME ["$EMACS_CONFIG_DIR", "$DOOM_CONFIG_DIR"]

# Copy the Emacs shim for the entry point
# Copy the Emacs shim for the default command
COPY emacs_shim.sh /emacs_shim.sh

# Launch Emacs by default
Expand Down
15 changes: 15 additions & 0 deletions containers/emacs/doom_cache/Containerfile
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,18 @@ RUN mkdir -p $DE_DOOM_DIR \
&& cp $DE_EMACS_DIR/static/packages.example.el $DE_DOOM_DIR/packages.el \
&& sed -e "s/[(]\?evil/;;&/" -e "s/;;\([(]\?vterm\)/\1/" -i $DE_DOOM_DIR/init.el \
&& doom install --force --verbose --no-config --no-env --no-hooks

# Install dependencies for building VTerm
RUN apt-get update \
&& apt-get install -y \
build-essential \
cmake \
libtool-bin \
&& rm -rf /var/lib/apt/lists/*

# Build the VTerm module. We must locate the exact build directory because it's
# name depends on the Emacs version, e.g., `build-28.1`, etc.
RUN VTERM_BUILD_DIR=$(find "$DE_EMACS_DIR" -path "*/build-[0-9.]*/vterm") \
&& cd $VTERM_BUILD_DIR \
&& cmake -S . -B build \
&& cmake --build build
31 changes: 31 additions & 0 deletions containers/emacs/emacs_init.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/bin/bash

# Copyright (c) 2023 Tim Perkins

set -o errexit
set -o nounset
set -o pipefail
IFS=$'\n\t'

# This should never happen, but check anyway
if [ -z "${EMACS_CONFIG_DIR:-}" -o -z "${EMACS_CONFIG_TARBALL:-}" \
-o -z "${DOOM_CONFIG_DIR:-}" -o -z "${DOOM_CONFIG_TARBALL:-}" ]; then
echo "ERROR: Essential Emacs variables are not defined!" >&2
exit 1
fi

is_empty_dir() {
find "$1" -maxdepth 0 -type d -empty | grep -q .
}

if is_empty_dir $EMACS_CONFIG_DIR; then
echo "Initializing Emacs config: $EMACS_CONFIG_DIR"
tar -C $EMACS_CONFIG_DIR --extract -f $EMACS_CONFIG_TARBALL
fi

if is_empty_dir $DOOM_CONFIG_DIR; then
echo "Initializing Doom config: $DOOM_CONFIG_DIR"
tar -C $DOOM_CONFIG_DIR --extract -f $DOOM_CONFIG_TARBALL
fi

exec "$@"
11 changes: 6 additions & 5 deletions containers/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ DEFAULT_TARGET_TAG="main"

# The names of the volumes
SHELL_CONFIG_VOL="shell-config"
EMACS_CONFIG_VOL="emacs-config"
DOOM_CONFIG_VOL="doom-config"

# The default projects directory
DEFAULT_PROJECTS_DIR="$HOME/Projects"
Expand Down Expand Up @@ -141,7 +139,7 @@ EMACS_CONFIG_DIR=$(get_from_env "$IMAGE_ENV" "EMACS_CONFIG_DIR" || true)
DOOM_CONFIG_DIR=$(get_from_env "$IMAGE_ENV" "DOOM_CONFIG_DIR" || true)

# Check for volumes, create them if necessary
vols=($SHELL_CONFIG_VOL $EMACS_CONFIG_VOL $DOOM_CONFIG_VOL)
vols=($SHELL_CONFIG_VOL)
for vol in "${vols[@]}"; do
if ! docker volume ls -q | grep -q $vol; then
echo "Creating volume: $vol" >&2
Expand All @@ -157,6 +155,9 @@ ensure_exists f 644 $HOME/.gitconfig
ensure_exists d 700 $HOME/.xpra
ensure_exists f 600 $HOME/.claude.json
ensure_exists d 700 $HOME/.claude
ensure_exists d 700 $HOME/.taughz
ensure_exists d 700 $HOME/.taughz/emacs.d
ensure_exists d 700 $HOME/.taughz/doom.d

# Get the user data ready
passwd_ent=$(getent passwd $(id -u))
Expand Down Expand Up @@ -214,8 +215,8 @@ SHELL_FLAGS=(

emacs_flags=()
if [ -n "$EMACS_CONFIG_DIR" -a -n "$DOOM_CONFIG_DIR" ]; then
emacs_flags+=(--mount "type=volume,src=$EMACS_CONFIG_VOL,dst=$EMACS_CONFIG_DIR")
emacs_flags+=(--mount "type=volume,src=$DOOM_CONFIG_VOL,dst=$DOOM_CONFIG_DIR")
emacs_flags+=(--mount "type=bind,src=$HOME/.taughz/emacs.d,dst=$EMACS_CONFIG_DIR")
emacs_flags+=(--mount "type=bind,src=$HOME/.taughz/doom.d,dst=$DOOM_CONFIG_DIR")
fi

projects_flags=()
Expand Down