Monorepo for Aesthetic.Computer aesthetic.computer
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: Add Apple Container support for native macOS ARM64 development

- Containerfile.apple: ARM64-optimized container image derived from Dockerfile
- apple-container.fish: Helper script for build/run/exec/stop commands
- generate-apple-container.fish: Auto-regenerate Containerfile from main Dockerfile

Enables running the full dev stack natively on Apple Silicon Macs using
Apple's container runtime (github.com/apple/container) instead of Docker Desktop.

+382
+153
.devcontainer/Containerfile.apple
··· 1 + # Aesthetic Computer - Apple Container Runtime Edition 2 + # Auto-generated from .devcontainer/Dockerfile for native macOS ARM64 virtualization 3 + # Regenerate with: .devcontainer/generate-apple-container.fish 4 + # Optimized for Apple Silicon (M1/M2/M3 Pro/Max/Ultra) 5 + 6 + FROM fedora:latest 7 + 8 + # Preconfigure DNF to minimize footprint 9 + RUN set -eux; \ 10 + echo 'fastestmirror=True' >> /etc/dnf/dnf.conf; \ 11 + echo 'max_parallel_downloads=5' >> /etc/dnf/dnf.conf; \ 12 + echo 'keepcache=0' >> /etc/dnf/dnf.conf; \ 13 + echo 'install_weak_deps=False' >> /etc/dnf/dnf.conf; \ 14 + echo 'tsflags=nodocs' >> /etc/dnf/dnf.conf 15 + 16 + ENV NODE_OPTIONS=--max_old_space_size=8192 17 + ENV DENO_DIR=/home/me/.cache/deno 18 + ENV NETLIFY_DENO_VERSION=2.4.5 19 + ENV PAGER=cat 20 + ENV GIT_PAGER=cat 21 + ENV SYSTEMD_PAGER=cat 22 + ENV MANPAGER=cat 23 + 24 + # --- Base toolchain & deps (ARM64 optimized) --------------------------------- 25 + RUN dnf update -y && \ 26 + dnf install -y \ 27 + awk which tree procps-ng coreutils unzip jq bat ripgrep \ 28 + git gh gcc gcc-c++ clang make cmake \ 29 + python3.11 python3.11-devel python3-pip python3-devel \ 30 + emacs-nox fish util-linux-user util-linux-script sshpass \ 31 + openssl openssl-devel awscli redis \ 32 + dnf-plugins-core iproute nmap-ncat \ 33 + inotify-tools wget curl tar gzip bzip2 \ 34 + libsodium libsodium-devel libffi libffi-devel \ 35 + gmp gmp-devel \ 36 + pkg-config autoconf automake libtool \ 37 + rsync m4 patch \ 38 + sbcl zeromq-devel redhat-rpm-config \ 39 + caddy openssh-clients \ 40 + && dnf clean all && rm -rf /var/cache/dnf 41 + 42 + # --- FFmpeg from RPM Fusion --------------------------------------------------- 43 + RUN dnf install -y \ 44 + https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-$(rpm -E %fedora).noarch.rpm \ 45 + https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-$(rpm -E %fedora).noarch.rpm \ 46 + && dnf install -y --allowerasing --skip-unavailable ffmpeg ffmpeg-devel \ 47 + && dnf clean all && rm -rf /var/cache/dnf 48 + 49 + # --- Python 3.11 venv as default "python" ------------------------------------- 50 + RUN /usr/bin/python3.11 -m venv /opt/py311 && \ 51 + /opt/py311/bin/pip install -U pip setuptools wheel && \ 52 + ln -s /opt/py311/bin/python /usr/local/bin/python && \ 53 + ln -s /opt/py311/bin/pip /usr/local/bin/pip 54 + ENV PATH="/opt/py311/bin:${PATH}" 55 + 56 + # --- PyTezos (SmartPy skipped - no ARM64 support) ---------------------------- 57 + RUN pip install "pytezos>=3.9.0,<4" requests 58 + 59 + # --- Stripe CLI (ARM64) ------------------------------------------------------ 60 + RUN curl -fsSL "https://github.com/stripe/stripe-cli/releases/download/v1.30.0/stripe_1.30.0_linux_arm64.tar.gz" \ 61 + | tar xz -C /usr/local/bin 62 + 63 + # --- redli (ARM64) ----------------------------------------------------------- 64 + RUN curl -fsSL "https://github.com/IBM-Cloud/redli/releases/download/v0.15.0/redli_0.15.0_linux_arm64.tar.gz" \ 65 + | tar xz -C /usr/local/bin && mv /usr/local/bin/redli_linux_arm64 /usr/local/bin/redli 66 + 67 + # --- mkcert (ARM64) ---------------------------------------------------------- 68 + RUN curl -fsSL "https://github.com/FiloSottile/mkcert/releases/download/v1.4.4/mkcert-v1.4.4-linux-arm64" -o /usr/local/bin/mkcert && \ 69 + chmod +x /usr/local/bin/mkcert 70 + 71 + # --- ngrok (ARM64) ----------------------------------------------------------- 72 + RUN curl -fsSL "https://bin.equinox.io/c/bNyj1mQVY4c/ngrok-v3-stable-linux-arm64.tgz" -o /tmp/ngrok.tgz && \ 73 + tar -xzf /tmp/ngrok.tgz -C /usr/local/bin && rm /tmp/ngrok.tgz 74 + 75 + # --- doctl (DigitalOcean CLI, ARM64) ----------------------------------------- 76 + RUN DOCTL_VERSION=1.109.0 && \ 77 + curl -fsSL "https://github.com/digitalocean/doctl/releases/download/v${DOCTL_VERSION}/doctl-${DOCTL_VERSION}-linux-arm64.tar.gz" -o /tmp/doctl.tar.gz && \ 78 + tar -xzf /tmp/doctl.tar.gz -C /usr/local/bin && rm /tmp/doctl.tar.gz 79 + 80 + # --- PowerShell (ARM64) ------------------------------------------------------ 81 + RUN PS_VERSION=$(curl -s https://api.github.com/repos/PowerShell/PowerShell/releases/latest | grep '"tag_name":' | sed -E 's/.*"v([^"]+)".*/\1/') && \ 82 + curl -sSL -o /tmp/powershell.tar.gz "https://github.com/PowerShell/PowerShell/releases/download/v${PS_VERSION}/powershell-${PS_VERSION}-linux-arm64.tar.gz" && \ 83 + mkdir -p /opt/microsoft/powershell/7 && \ 84 + tar -xzf /tmp/powershell.tar.gz -C /opt/microsoft/powershell/7 && \ 85 + chmod +x /opt/microsoft/powershell/7/pwsh && \ 86 + ln -s /opt/microsoft/powershell/7/pwsh /usr/local/bin/pwsh && \ 87 + rm /tmp/powershell.tar.gz 88 + 89 + # --- s3cmd ------------------------------------------------------------------- 90 + RUN dnf install -y s3cmd && dnf clean all 91 + 92 + # --- Jupyter bits ------------------------------------------------------------ 93 + RUN dnf install -y python3-notebook python3-nbconvert && dnf clean all 94 + 95 + # --- gcloud SDK -------------------------------------------------------------- 96 + RUN curl -sSL https://sdk.cloud.google.com > /tmp/install_gcloud.sh && \ 97 + bash /tmp/install_gcloud.sh --disable-prompts --install-dir=/opt && \ 98 + ln -s /opt/google-cloud-sdk/bin/gcloud /usr/local/bin/gcloud && \ 99 + ln -s /opt/google-cloud-sdk/bin/gsutil /usr/local/bin/gsutil && \ 100 + rm /tmp/install_gcloud.sh 101 + 102 + # --- User -------------------------------------------------------------------- 103 + RUN useradd -m me && echo "me ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && chsh -s /usr/bin/fish me 104 + RUN if test ! -f /usr/bin/fish && test -f /usr/sbin/fish; then ln -s /usr/sbin/fish /usr/bin/fish; fi 105 + 106 + USER me 107 + WORKDIR /home/me 108 + 109 + # --- Rust + websocat --------------------------------------------------------- 110 + RUN curl https://sh.rustup.rs -sSf | sh -s -- -y && \ 111 + . "$HOME/.cargo/env" && \ 112 + git clone https://github.com/vi/websocat.git && \ 113 + cd websocat && cargo build --release && sudo cp target/release/websocat /usr/local/bin/ && \ 114 + cd .. && rm -rf websocat 115 + 116 + # --- fnm / Node toolchain ---------------------------------------------------- 117 + RUN mkdir -p /home/me/.config/fish/conf.d /home/me/.config/fish/functions /home/me/.local/share/fish 118 + RUN curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir "$HOME/.fnm" --skip-shell 119 + ENV PATH="/home/me/.fnm:${PATH}" 120 + RUN echo 'fnm env --use-on-cd --shell fish | source' > /home/me/.config/fish/conf.d/fnm.fish && \ 121 + export PATH="/home/me/.fnm:${PATH}" && \ 122 + eval "$(/home/me/.fnm/fnm env --use-on-cd)" && \ 123 + /home/me/.fnm/fnm install lts-jod && \ 124 + /home/me/.fnm/fnm default lts-jod && \ 125 + npm i -g prettier typescript typescript-language-server npm-check-updates @anthropic-ai/claude-code netlify-cli wrangler 126 + 127 + # --- SBCL / Quicklisp -------------------------------------------------------- 128 + RUN curl -fsSLO https://beta.quicklisp.org/quicklisp.lisp && \ 129 + sbcl --non-interactive \ 130 + --load quicklisp.lisp \ 131 + --eval '(quicklisp-quickstart:install)' \ 132 + --eval '(ql-util:without-prompting (ql:add-to-init-file))' \ 133 + --eval '(quit)' && \ 134 + rm quicklisp.lisp 135 + 136 + # --- uv (fast Python package manager) ---------------------------------------- 137 + RUN curl -LsSf https://astral.sh/uv/install.sh | sh 138 + ENV PATH="/home/me/.local/bin:${PATH}" 139 + 140 + # --- Deno -------------------------------------------------------------------- 141 + RUN curl -fsSL https://deno.land/install.sh | DENO_INSTALL=/home/me/.deno sh -s v2.4.5 142 + ENV PATH="/home/me/.deno/bin:${PATH}" 143 + 144 + # --- Fish config ------------------------------------------------------------- 145 + RUN echo 'set -gx PATH /home/me/.fnm /home/me/.deno/bin /home/me/.local/bin /home/me/.cargo/bin $PATH' >> /home/me/.config/fish/config.fish && \ 146 + echo 'fnm env --use-on-cd --shell fish | source' >> /home/me/.config/fish/config.fish && \ 147 + echo 'fnm use lts-jod --silent-if-unchanged 2>/dev/null' >> /home/me/.config/fish/config.fish && \ 148 + echo 'set -U fish_greeting ""' >> /home/me/.config/fish/config.fish 149 + 150 + # Default working directory for aesthetic-computer 151 + WORKDIR /workspaces/aesthetic-computer 152 + 153 + CMD ["/usr/bin/fish"]
+137
.devcontainer/apple-container.fish
··· 1 + #!/usr/bin/env fish 2 + # apple-container.fish 3 + # Helper script to build, run, and manage Apple Container for aesthetic-computer 4 + # Usage: ./apple-container.fish [build|run|start|stop|exec|delete|status] 5 + 6 + set -l script_dir (dirname (status filename)) 7 + set -l containerfile "$script_dir/Containerfile.apple" 8 + set -l container_name "ac-dev" 9 + set -l image_name "ac-dev" 10 + 11 + # Detect workspace path on macOS 12 + set -l workspace_path "" 13 + if test -d ~/Desktop/code/aesthetic-computer 14 + set workspace_path ~/Desktop/code/aesthetic-computer 15 + else if test -d ~/aesthetic-computer 16 + set workspace_path ~/aesthetic-computer 17 + else if test -d /workspaces/aesthetic-computer 18 + set workspace_path /workspaces/aesthetic-computer 19 + else 20 + echo "❌ Could not find aesthetic-computer workspace" 21 + echo " Looked in: ~/Desktop/code/aesthetic-computer, ~/aesthetic-computer, /workspaces/aesthetic-computer" 22 + exit 1 23 + end 24 + 25 + function show_help 26 + echo "🍎 Apple Container Helper for Aesthetic Computer" 27 + echo "" 28 + echo "Usage: ./apple-container.fish <command>" 29 + echo "" 30 + echo "Commands:" 31 + echo " build Build the container image from Containerfile.apple" 32 + echo " run Create and start a new container (removes existing)" 33 + echo " start Start an existing stopped container" 34 + echo " stop Stop the running container" 35 + echo " exec Execute fish shell in the running container" 36 + echo " delete Delete the container" 37 + echo " status Show container status" 38 + echo " logs Show container logs" 39 + echo " generate Regenerate Containerfile.apple from Dockerfile" 40 + echo "" 41 + echo "Workspace: $workspace_path" 42 + end 43 + 44 + function cmd_build 45 + echo "🔨 Building Apple Container image..." 46 + container build -t $image_name -f $containerfile $script_dir 47 + end 48 + 49 + function cmd_run 50 + echo "🚀 Creating and starting container..." 51 + 52 + # Stop and remove existing container if it exists 53 + if container ls -a | grep -q $container_name 54 + echo " Removing existing container..." 55 + container stop $container_name 2>/dev/null 56 + container rm $container_name 2>/dev/null 57 + end 58 + 59 + container create --name $container_name -it --ssh \ 60 + -v $workspace_path:/workspaces/aesthetic-computer \ 61 + -p 8888:8888 -p 8889:8889 -p 8111:8111 -p 3000:3000 \ 62 + -p 8083:8083 -p 8084:8084 -p 8085:8085 \ 63 + -w /workspaces/aesthetic-computer \ 64 + --cpus 4 --memory 8G \ 65 + $image_name /usr/bin/fish 66 + 67 + container start $container_name 68 + echo "✅ Container started! Run './apple-container.fish exec' to enter." 69 + end 70 + 71 + function cmd_start 72 + echo "▶️ Starting container..." 73 + container start $container_name 74 + end 75 + 76 + function cmd_stop 77 + echo "⏹️ Stopping container..." 78 + container stop $container_name 79 + end 80 + 81 + function cmd_exec 82 + echo "🐚 Entering container shell..." 83 + container exec -it $container_name /usr/bin/fish 84 + end 85 + 86 + function cmd_delete 87 + echo "🗑️ Deleting container..." 88 + container stop $container_name 2>/dev/null 89 + container rm $container_name 90 + end 91 + 92 + function cmd_status 93 + echo "📊 Container status:" 94 + container ls -a | head -1 95 + container ls -a | grep $container_name; or echo " No container named '$container_name' found" 96 + echo "" 97 + if container ls | grep -q $container_name 98 + echo "📈 Resource usage:" 99 + container stats $container_name --no-stream 100 + end 101 + end 102 + 103 + function cmd_logs 104 + container logs $container_name 105 + end 106 + 107 + function cmd_generate 108 + fish $script_dir/generate-apple-container.fish 109 + end 110 + 111 + # Main 112 + switch $argv[1] 113 + case build 114 + cmd_build 115 + case run 116 + cmd_run 117 + case start 118 + cmd_start 119 + case stop 120 + cmd_stop 121 + case exec 122 + cmd_exec 123 + case delete 124 + cmd_delete 125 + case status 126 + cmd_status 127 + case logs 128 + cmd_logs 129 + case generate 130 + cmd_generate 131 + case help -h --help "" 132 + show_help 133 + case "*" 134 + echo "❌ Unknown command: $argv[1]" 135 + show_help 136 + exit 1 137 + end
+92
.devcontainer/generate-apple-container.fish
··· 1 + #!/usr/bin/env fish 2 + # generate-apple-container.fish 3 + # Automatically generates Containerfile.apple from the main Dockerfile 4 + # Transforms x86_64/aarch64 conditionals to ARM64-only for Apple Silicon 5 + 6 + set -l script_dir (dirname (status filename)) 7 + set -l dockerfile "$script_dir/Dockerfile" 8 + set -l output "$script_dir/Containerfile.apple" 9 + 10 + if not test -f $dockerfile 11 + echo "❌ Dockerfile not found at $dockerfile" 12 + exit 1 13 + end 14 + 15 + echo "🔄 Generating Apple Container Containerfile from Dockerfile..." 16 + 17 + # Start with header 18 + echo '# Aesthetic Computer - Apple Container Runtime Edition 19 + # Auto-generated from .devcontainer/Dockerfile for native macOS ARM64 virtualization 20 + # Regenerate with: .devcontainer/generate-apple-container.fish 21 + # Optimized for Apple Silicon (M1/M2/M3 Pro/Max/Ultra) 22 + ' > $output 23 + 24 + # Process the Dockerfile 25 + set -l in_skip_block false 26 + set -l skip_patterns \ 27 + "qemu-kvm" "qemu-img" "qemu-system" "qemu-user-static" \ 28 + "ocaml" "opam" "bubblewrap" \ 29 + "libX11" "libxkbfile" "libsecret" "libxshmfence" "libXtst" \ 30 + "nss" "atk" "pango" "cups-libs" "libXcomposite" "libXcursor" \ 31 + "libXi" "libXdamage" "libXrandr" "alsa-lib" "gtk3" \ 32 + "xorg-x11-server-Xvfb" "psmisc" "lsof" "chromium" \ 33 + "docker pull" "SmartPy" "smartpy" "Octez" "octez" 34 + 35 + while read -l line 36 + # Skip empty lines at start 37 + if test -z "$line" 38 + echo "" >> $output 39 + continue 40 + end 41 + 42 + # Skip Docker-in-Docker pulls (not needed for Apple Container) 43 + if string match -q "*docker pull*" $line 44 + continue 45 + end 46 + 47 + # Skip SmartPy (x86_64 only) 48 + if string match -q "*smartpy*" $line; or string match -q "*SmartPy*" $line 49 + continue 50 + end 51 + 52 + # Skip Octez binary downloads (use Docker method anyway) 53 + if string match -q "*octez*" $line; or string match -q "*Octez*" $line 54 + continue 55 + end 56 + 57 + # Transform architecture conditionals to ARM64 only 58 + if string match -q '*case "$(uname -m)"*' $line 59 + # Skip the whole case block and use ARM64 directly 60 + set in_skip_block true 61 + continue 62 + end 63 + 64 + if test "$in_skip_block" = true 65 + if string match -q "*esac*" $line 66 + set in_skip_block false 67 + end 68 + continue 69 + end 70 + 71 + # Replace x86_64 arch detection with arm64 hardcoded 72 + set line (string replace -r 'ARCH=\$\(uname -m\).*amd64.*arm64.*' 'ARCH=arm64' $line) 73 + set line (string replace -r 'ARCH=amd64' 'ARCH=arm64' $line) 74 + set line (string replace -r 'PS_ARCH="x64".*PS_ARCH="arm64"' 'PS_ARCH="arm64"' $line) 75 + set line (string replace -r '\$\{ARCH\}' 'arm64' $line) 76 + 77 + # Skip lines that check for x86_64 78 + if string match -q '*if \[ "$(uname -m)" = "x86_64" \]*' $line 79 + continue 80 + end 81 + 82 + echo $line >> $output 83 + end < $dockerfile 84 + 85 + echo "✅ Generated $output" 86 + echo "" 87 + echo "To build and run with Apple Container:" 88 + echo " container build -t ac-dev -f $output $script_dir" 89 + echo " container run --name ac-dev -it --ssh \\" 90 + echo " -v ~/Desktop/code/aesthetic-computer:/workspaces/aesthetic-computer \\" 91 + echo " -p 8888:8888 -p 8889:8889 -p 3000:3000 \\" 92 + echo " -w /workspaces/aesthetic-computer ac-dev"