Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
d5e82c8
Add Apple Container toolkit for macOS VM-isolated development
deviantony Jan 15, 2026
9cf08a8
Add documentation clarifications and CLI check to ccm script
deviantony Jan 16, 2026
43b7c9f
Enhance container toolkit with conditional Docker socket mounting and…
deviantony Jan 24, 2026
348dcca
Update Apple Container toolkit documentation for Docker socket limita…
deviantony Jan 24, 2026
c04c88f
Update Apple Container port range to avoid host conflicts
deviantony Jan 24, 2026
016f635
Fix fzf integration and enhance devbox-apple script
deviantony Jan 24, 2026
a41af21
Update devbox-apple rebuild and destroy commands for safer operation
deviantony Jan 24, 2026
cf5c54d
Improve devbox-apple destroy command with conditional stop logic
deviantony Jan 24, 2026
8a55c79
Update Apple Container toolkit with hostname display and builder mana…
deviantony Jan 24, 2026
c55f075
Update Apple Container toolkit with improved glow installation and bu…
deviantony Jan 24, 2026
bedb127
Improve builder configuration detection and add mismatch warning
deviantony Jan 24, 2026
363694a
Update builder mismatch prompt to use zsh-compatible read syntax
deviantony Jan 24, 2026
c60e91b
Update devbox-apple script to use generic builder deletion
deviantony Jan 24, 2026
a47ee19
Refactor devbox-apple script to improve code organization and resourc…
deviantony Jan 24, 2026
f209f6d
Update Apple Container toolkit builder configuration to use preset pr…
deviantony Jan 24, 2026
6db159a
Update credential protection and directory copy logic
deviantony Jan 25, 2026
f970e6f
Update devbox-apple to support nested credential directories
deviantony Jan 25, 2026
6206a45
Update Apple Container toolkit documentation for clarity and organiza…
deviantony Jan 25, 2026
80ca2cd
Add git configuration synchronization to Apple Container toolkit
deviantony Jan 25, 2026
2a2bff9
Update Apple Container toolkit with first-time setup documentation an…
deviantony Jan 25, 2026
b491d66
Improve GitHub CLI authentication flow in Apple Container toolkit
deviantony Jan 25, 2026
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
348 changes: 348 additions & 0 deletions user-toolkits/alapenna-container/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,348 @@
FROM portainer/dev-toolkit:2025.12

ENV HOME=/root
ENV TERM=xterm-256color

# Detect architecture for binary downloads
ARG TARGETARCH

# ============================================
# System packages (combined, with cleanup)
# ============================================
RUN apt-get update && apt-get install -y --no-install-recommends \
zsh \
wget \
curl \
git \
file \
fzf \
ripgrep \
fd-find \
bat \
jq \
lsof \
unzip \
&& rm -rf /var/lib/apt/lists/* \
&& ln -sf $(which fdfind) /usr/local/bin/fd \
&& ln -sf $(which batcat) /usr/local/bin/bat \
&& mkdir -p /usr/share/fzf \
&& curl -fsSL https://raw.githubusercontent.com/junegunn/fzf/refs/heads/master/shell/key-bindings.zsh -o /usr/share/fzf/key-bindings.zsh

# ============================================
# zsh plugins (no oh-my-zsh) + starship prompt
# ============================================
RUN mkdir -p /root/.zsh \
&& git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions /root/.zsh/zsh-autosuggestions \
&& git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting /root/.zsh/zsh-syntax-highlighting \
&& git clone --depth=1 https://github.com/zsh-users/zsh-history-substring-search /root/.zsh/zsh-history-substring-search \
&& rm -rf /root/.zsh/*/.git \
&& curl -sS https://starship.rs/install.sh | sh -s -- -y

# Starship config (two-line minimal)
RUN mkdir -p /root/.config && cat > /root/.config/starship.toml <<'EOF'
format = """
$directory\
$hostname\
$git_branch\
$git_status\
$line_break\
$character"""

[directory]
style = "cyan bold"
truncation_length = 5
truncate_to_repo = false

[hostname]
ssh_only = false
format = "[ @ $hostname]($style)"
style = "yellow bold"

[git_branch]
style = "purple bold"
format = "[ │ $symbol$branch]($style)"
symbol = ""

[git_status]
style = "red bold"
format = "[$all_status$ahead_behind]($style)"
conflicted = "="
ahead = "⇡${count}"
behind = "⇣${count}"
diverged = "⇕"
untracked = "?"
stashed = ""
modified = "!"
staged = "+"
renamed = "»"
deleted = "✘"

[character]
success_symbol = "[>](green bold)"
error_symbol = "[>](red bold)"
EOF

# ============================================
# fresh (terminal editor with LSP)
# ============================================
RUN FRESH_VERSION=$(curl -s "https://api.github.com/repos/sinelaw/fresh/releases/latest" | grep -Po '"tag_name": "v\K[^"]*') \
&& ARCH=$([ "$TARGETARCH" = "arm64" ] && echo "arm64" || echo "amd64") \
&& curl -Lo fresh.deb "https://github.com/sinelaw/fresh/releases/download/v${FRESH_VERSION}/fresh-editor_${FRESH_VERSION}-1_${ARCH}.deb" \
&& dpkg -i fresh.deb \
&& rm fresh.deb \
&& npm install -g typescript-language-server typescript \
&& npm cache clean --force \
&& mkdir -p /root/.config/fresh && cat > /root/.config/fresh/config.json <<'EOF'
{
"editor": {
"tab_size": 2
}
}
EOF

# ============================================
# CLI tools (lazygit, delta, yazi, zoxide, eza)
# ============================================
RUN LAZYGIT_VERSION=$(curl -s "https://api.github.com/repos/jesseduffield/lazygit/releases/latest" | grep -Po '"tag_name": "v\K[^"]*') \
&& ARCH=$([ "$TARGETARCH" = "arm64" ] && echo "arm64" || echo "x86_64") \
&& curl -Lo lazygit.tar.gz "https://github.com/jesseduffield/lazygit/releases/latest/download/lazygit_${LAZYGIT_VERSION}_Linux_${ARCH}.tar.gz" \
&& tar xf lazygit.tar.gz lazygit \
&& install lazygit /usr/local/bin \
&& rm lazygit.tar.gz lazygit

RUN DELTA_VERSION=$(curl -s "https://api.github.com/repos/dandavison/delta/releases/latest" | grep -Po '"tag_name": "\K[^"]*') \
&& ARCH=$([ "$TARGETARCH" = "arm64" ] && echo "arm64" || echo "amd64") \
&& curl -Lo delta.deb "https://github.com/dandavison/delta/releases/latest/download/git-delta_${DELTA_VERSION}_${ARCH}.deb" \
&& dpkg -i delta.deb \
&& rm delta.deb

RUN ARCH=$([ "$TARGETARCH" = "arm64" ] && echo "aarch64" || echo "x86_64") \
&& curl -Lo yazi.zip "https://github.com/sxyazi/yazi/releases/latest/download/yazi-${ARCH}-unknown-linux-gnu.zip" \
&& unzip yazi.zip \
&& mv yazi-${ARCH}-unknown-linux-gnu/yazi /usr/local/bin/ \
&& mv yazi-${ARCH}-unknown-linux-gnu/ya /usr/local/bin/ \
&& rm -rf yazi.zip yazi-*-unknown-linux-gnu

RUN curl -sS https://raw.githubusercontent.com/ajeetdsouza/zoxide/main/install.sh | bash

RUN ARCH=$([ "$TARGETARCH" = "arm64" ] && echo "aarch64" || echo "x86_64") \
&& curl -Lo eza.tar.gz "https://github.com/eza-community/eza/releases/latest/download/eza_${ARCH}-unknown-linux-gnu.tar.gz" \
&& tar xf eza.tar.gz \
&& mv eza /usr/local/bin/ \
&& rm eza.tar.gz

# ============================================
# GitHub CLI (gh)
# ============================================
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-get update \
&& apt-get install -y --no-install-recommends gh \
&& rm -rf /var/lib/apt/lists/*

# ============================================
# glow (markdown reader)
# ============================================
RUN GLOW_VERSION=$(curl -s "https://api.github.com/repos/charmbracelet/glow/releases/latest" | grep -Po '"tag_name": "v\K[^"]*') \
&& ARCH=$([ "$TARGETARCH" = "arm64" ] && echo "arm64" || echo "amd64") \
&& curl -Lo glow.tar.gz "https://github.com/charmbracelet/glow/releases/download/v${GLOW_VERSION}/glow_${GLOW_VERSION}_Linux_${ARCH}.tar.gz" \
&& tar xzf glow.tar.gz \
&& mv glow_*/glow /usr/local/bin/ \
&& rm -rf glow.tar.gz glow_*

# ============================================
# Claude Code + Plannotator CLI
# ============================================
RUN curl -fsSL https://claude.ai/install.sh | bash \
&& curl -fsSL https://plannotator.ai/install.sh | bash

# ============================================
# Claude Code plugins (via CLI)
# ============================================
ENV PATH="/root/.local/bin:${PATH}"
RUN claude plugin marketplace add jarrodwatts/claude-hud \
&& claude plugin marketplace add backnotprop/plannotator \
&& claude plugin marketplace add anthropics/claude-plugins-official \
&& claude plugin install claude-hud \
&& claude plugin install plannotator@plannotator \
&& claude plugin install typescript-lsp@claude-plugins-official \
&& claude plugin install gopls-lsp@claude-plugins-official

# Claude Code config files
RUN mkdir -p $HOME/.claude/plugins/claude-hud \
&& cat > $HOME/.claude/plugins/claude-hud/config.json <<'EOF'
{
"layout": "default",
"display": {
"showModel": true,
"showContextBar": true,
"showTools": false,
"showAgents": true,
"showTodos": true,
"showConfigCounts": false,
"showTokenBreakdown": true,
"showUsage": true,
"showDuration": false
},
"gitStatus": {
"enabled": true,
"showDirty": true,
"showAheadBehind": true
}
}
EOF

RUN cat > $HOME/.claude/settings.json <<'EOF'
{
"statusLine": {
"type": "command",
"command": "node \"$(ls -td ~/.claude/plugins/cache/claude-hud/claude-hud/*/ 2>/dev/null | head -1)dist/index.js\""
},
"enabledPlugins": {
"claude-hud@claude-hud": true,
"plannotator@plannotator": true
},
"alwaysThinkingEnabled": true,
"permissions": {
"deny": [
"Read(**/.env*)",
"Read(~/.ssh/**)",
"Read(~/.gnupg/**)",
"Read(~/.docker/**)"
]
}
}
EOF

# ============================================
# Git config
# ============================================
RUN git config --global core.pager delta \
&& git config --global interactive.diffFilter "delta --color-only" \
&& git config --global delta.navigate true \
&& git config --global delta.side-by-side true \
&& git config --global delta.line-numbers true \
&& git config --global merge.conflictstyle diff3 \
&& git config --global diff.colorMoved default \
&& git config --global push.autoSetupRemote true

# ============================================
# Shell configuration (.zshrc)
# ============================================
RUN cat > /root/.zshrc <<'EOF'
# ----------------------------------------
# Zsh plugins (no oh-my-zsh framework)
# ----------------------------------------
source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh
source ~/.zsh/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source ~/.zsh/zsh-history-substring-search/zsh-history-substring-search.zsh

# ----------------------------------------
# History configuration
# ----------------------------------------
HISTFILE=~/.zsh_history
HISTSIZE=50000
SAVEHIST=50000
setopt HIST_IGNORE_ALL_DUPS # Remove older duplicate entries
setopt HIST_FIND_NO_DUPS # Don't show duplicates when searching
setopt SHARE_HISTORY # Share history across terminals
setopt INC_APPEND_HISTORY # Add commands immediately

# ----------------------------------------
# Shell options
# ----------------------------------------
setopt AUTO_CD # Type directory name to cd into it
setopt AUTO_PUSHD # cd pushes to directory stack
setopt PUSHD_IGNORE_DUPS # Don't push duplicates
setopt CORRECT # Spelling correction for commands

# ----------------------------------------
# Key bindings
# ----------------------------------------
# Up/down arrow searches history with current prefix
bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down

# fzf keybindings (Ctrl+R history, Ctrl+T files, Alt+C cd)
source /usr/share/fzf/key-bindings.zsh

# ----------------------------------------
# Environment
# ----------------------------------------
export PATH="$HOME/.local/bin:$PATH"
export EDITOR="fresh"
export FZF_DEFAULT_OPTS='--height 40% --layout=reverse --border'

# Plannotator (devcontainer mode on port 17777)
export PLANNOTATOR_REMOTE=1
export PLANNOTATOR_PORT=17777

# ----------------------------------------
# Tool integrations
# ----------------------------------------
eval "$(zoxide init zsh)"
eval "$(starship init zsh)"

# ----------------------------------------
# Aliases
# ----------------------------------------
alias lg="lazygit"
alias y="yazi"
alias f="fresh"
alias e='file=$(fd --type f --hidden --no-ignore --follow --exclude .git | fzf) && [ -n "$file" ] && fresh "$file"'
alias yf='d=$(fd --type d --hidden --no-ignore --follow --exclude .git | fzf) && [ -n "$d" ] && yazi "$d"'
alias cat="bat --paging=never"
alias l="eza -la --icons"
alias br='fzf --preview "bat --color=always {}"'
alias gp="git push"

dir() { eza --tree --level="${1:-1}" --icons; }

# ----------------------------------------
# Help command for aliases
# ----------------------------------------
ha() {
echo "
Navigation & Files
l List files (eza -la --icons)
dir [N] Tree view, depth N (default: 1)
br Browse files with preview (fzf + bat)
e Fuzzy find + open in editor
y Yazi file manager
yf Fuzzy find folder + open in yazi

Tools
lg Lazygit
f Fresh editor
cat Bat (syntax highlighting)

Keybindings
Ctrl+R Fuzzy search command history
Ctrl+T Fuzzy find file, insert path
Alt+C Fuzzy find directory and cd
Up/Down Search history with current prefix

Productivity
ccm Claude commit message
"
}

EOF

# ============================================
# Custom scripts
# ============================================
COPY scripts/ccm /usr/local/bin/ccm
COPY scripts/entrypoint.sh /entrypoint.sh
RUN chmod +x /usr/local/bin/ccm /entrypoint.sh

# ============================================
# Set zsh as default shell
# ============================================
RUN chsh -s $(which zsh)

WORKDIR /workspace
SHELL ["/bin/zsh", "-c"]

ENTRYPOINT ["/entrypoint.sh"]
Loading