From 0d60fe7a65186e2e0f6b7f749309adb77ef26221 Mon Sep 17 00:00:00 2001 From: Rudy Marchandise Date: Sat, 3 May 2025 22:46:49 +0200 Subject: [PATCH 1/6] feat: ubuntu 24.04 with golang and neovim --- .devcontainer/Dockerfile | 143 +++++++++-------- .devcontainer/devcontainer.json | 59 +++---- .devcontainer/etc/sudoers.d/override | 2 - .devcontainer/home/.config/starship.toml | 2 +- .devcontainer/home/.profile | 15 -- .devcontainer/home/.zshrc | 26 ++- .github/workflows/docker.yml | 81 +++++++--- README.md | 193 +++++++++-------------- example/.devcontainer/devcontainer.json | 53 ++++--- nvim.png | Bin 0 -> 75242 bytes 10 files changed, 286 insertions(+), 288 deletions(-) delete mode 100644 .devcontainer/etc/sudoers.d/override delete mode 100644 .devcontainer/home/.profile create mode 100644 nvim.png diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index fc015a9..608fde7 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM ubuntu:24.04 # ------------------------------ # Labels @@ -10,145 +10,150 @@ LABEL github="https://github.com/Ealenn/codespaces-typescript" # Configuration # ------------------------------ ARG USER -ENV USER ${USER:-user} - -ARG PUID -ENV PUID ${PUID:-1000} - -ARG PGID -ENV PGID ${PGID:-1000} - -ENV HOME /home/${USER} +ENV USER=${USER:-ubuntu} +ENV HOME=/home/${USER} ARG TZ -ENV TZ ${TZ:-Europe/Paris} +ENV TZ=${TZ:-Europe/Paris} ARG LOCAL -ENV LOCAL ${LOCAL:-en_GB.UTF-8} +ENV LOCAL=${LOCAL:-en_GB.UTF-8} ENV DEBIAN_FRONTEND=noninteractive # ------------------------------ -# System +# User Setup +# ------------------------------ +RUN useradd -m -s /bin/zsh ${USER} && passwd -d ${USER} || true + +# ------------------------------ +# APT # ------------------------------ -WORKDIR /root +RUN apt update && apt upgrade -y +RUN apt install gpg ubuntu-keyring apt-transport-https ca-certificates curl wget -y +# ------------------------------ +# System +# ------------------------------ # TimeZone RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ && echo $TZ > /etc/timezone -RUN apt update && apt upgrade -y RUN apt install sudo screen tzdata locales lsb-release software-properties-common -y -# APT -RUN apt install ca-certificates gnupg -y - # Essential -RUN apt install build-essential git curl wget vim jq -y +RUN apt install build-essential git vim jq fd-find -y # Locale RUN locale-gen $LOCAL && update-locale LANG=$LOCAL -# Bash | Starship +# ZSH | OhMyZSH | Starship RUN apt install zsh -y RUN sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" RUN curl -sS https://starship.rs/install.sh | sh -s - --yes RUN rm /bin/sh && ln -s /bin/zsh /bin/sh +# ------------------------------ +# Rust / Cargo +# ------------------------------ +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y + +# ------------------------------ +# Go +# ------------------------------ +ENV GOROOT=/usr/local/go +RUN ARCH=$(uname -m) && \ + case "$ARCH" in \ + x86_64) GO_ARCH="amd64" ;; \ + aarch64) GO_ARCH="arm64" ;; \ + armv7l) GO_ARCH="armv6l" ;; \ + ppc64le) GO_ARCH="ppc64le" ;; \ + s390x) GO_ARCH="s390x" ;; \ + *) echo "Unsupported architecture: $ARCH" && exit 1 ;; \ + esac && \ + GO_VERSION=$(curl -s "https://go.dev/dl/?mode=json" | jq -r '.[0].version') && \ + GO_URL="https://go.dev/dl/${GO_VERSION}.linux-${GO_ARCH}.tar.gz" && \ + echo "Downloading Go ${GO_VERSION} for ${GO_ARCH} from ${GO_URL}" && \ + wget -q "${GO_URL}" -O go.tar.gz && \ + tar -C /usr/local -xzf go.tar.gz && \ + rm go.tar.gz + # ------------------------------ # Python # ------------------------------ RUN apt install python3-dev python3-pip python3-setuptools -y +RUN curl -LsSf https://astral.sh/uv/install.sh | sh # ------------------------------ # Docker # ------------------------------ -WORKDIR /usr/local/docker - -# Install Docker -RUN apt install docker.io -y +RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg && chmod a+r /etc/apt/keyrings/docker.gpg +RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null -# Install Docker Compose -RUN LATEST_COMPOSE_VERSION=$(curl -sSL "https://api.github.com/repos/docker/compose/releases/latest" | grep -o -P '(?<="tag_name": ").+(?=")') \ - && curl -sSL "https://github.com/docker/compose/releases/download/${LATEST_COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose \ - && chmod +x /usr/local/bin/docker-compose +RUN apt update --allow-insecure-repositories +RUN apt install -y --allow-unauthenticated docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +RUN usermod -aG docker ${USER} # ------------------------------ # NodeJS - NVM # ------------------------------ -WORKDIR /usr/local/nvm -ENV NVM_DIR /usr/local/nvm +ENV NVM_DIR=/usr/local/nvm +RUN mkdir -p $NVM_DIR RUN curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash RUN source $NVM_DIR/nvm.sh \ && nvm install --lts \ && nvm alias default lts/* \ && nvm use default -ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules -ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH - # ------------------------------ # NPM Global Packages # ------------------------------ RUN [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" \ - && npm install --global gi-gitignore-generator zx \ + && npm install --global zx \ && npm cache clean --force # ------------------------------ # LSD # ------------------------------ -WORKDIR /usr/local/lsd -ENV LSD_VERSION 0.20.1 -ADD https://github.com/Peltoche/lsd/releases/download/${LSD_VERSION}/lsd_${LSD_VERSION}_amd64.deb /usr/local/lsd/lsd.deb -RUN dpkg -i ./lsd.deb -RUN rm ./lsd.deb +RUN apt install lsd -y # ------------------------------ # TheFuck # ------------------------------ -RUN pip3 install thefuck +RUN $HOME/.local/bin/uv tool install --python 3.11 thefuck --force # ------------------------------ -# User +# NeoVIM # ------------------------------ -WORKDIR ${HOME} -RUN useradd -u ${PUID} -U -d ${HOME} -s /bin/zsh ${USER} \ - && groupmod -o -g ${PUID} ${USER} \ - && usermod -o -u ${PGID} ${USER} \ - && usermod -aG sudo ${USER} \ - && echo ${USER}:${USER} | chpasswd \ - && echo root:root | chpasswd \ - && mkdir -p ${HOME} $HOME/.vim/backup -p $HOME/.vim/swap -p $HOME/.vim/undo +RUN apt install neovim -y +RUN git clone --dept 1 https://github.com/ecosse3/nvim.git $HOME/.config/nvim +RUN nvim --headless -c 'Lazy sync' -c 'qa' # ------------------------------ -# User Permissions +# Clean # ------------------------------ -RUN adduser $USER sudo -RUN addgroup --system docker \ - && adduser $USER docker \ - && newgrp docker -RUN addgroup wsl \ - && adduser $USER wsl \ - && newgrp wsl \ - && groupmod --gid 1001 wsl +RUN apt autoremove \ + && apt autoclean \ + && apt clean # ------------------------------ -# User Configuration +# User Setup # ------------------------------ -COPY home/ ${HOME}/ -COPY etc /etc -RUN chown -R ${PUID}:${PGID} $HOME -RUN chown -R ${PUID}:${PGID} /usr/local/nvm +RUN sed -i "s#${USER}:x:.*:/bin/sh#${USER}:x:$(id -u ${USER}):$(id -g ${USER}):,,,:/home/${USER}:/bin/zsh#" /etc/passwd && \ + echo "${USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \ + echo "%sudo ALL = (ALL) NOPASSWD: ALL" >> /etc/sudoers && \ + usermod --shell /bin/zsh ${USER} && \ + chsh -s /bin/zsh ${USER} # ------------------------------ -# Clean +# User Home # ------------------------------ -RUN apt autoremove \ - && apt autoclean \ - && apt clean +COPY home/ /home/${USER} +RUN chown -R ${USER}:${USER} /home/${USER} # ------------------------------ -# Ready +# Export # ------------------------------ -WORKDIR ${HOME} USER ${USER} +WORKDIR /home/${USER} +CMD ["zsh", "--login"] diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4b2ff15..0871654 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -14,36 +14,39 @@ } }, - // Set *default* container specific settings.json values on container create. - "settings": { - "eslint.alwaysShowStatus": true, - "workbench.iconTheme": "vscode-icons", - "editor.fontFamily": "Consolas, 'Courier New', monospace, 'Hack Nerd Font Mono'", - "terminal.integrated.fontFamily": "Consolas, 'Hack Nerd Font Mono'", - "terminal.integrated.fontSize": 14 + "customizations": { + "vscode": { + // Set *default* container specific settings.json values on container create. + "settings": { + "eslint.alwaysShowStatus": true, + "workbench.iconTheme": "vscode-icons", + "editor.fontFamily": "Consolas, 'Courier New', monospace, 'Hack Nerd Font Mono'", + "terminal.integrated.fontFamily": "Consolas, 'Hack Nerd Font Mono'", + "terminal.integrated.fontSize": 14 + }, + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + // TypeScript + "dbaeumer.vscode-eslint", + "oouo-diogo-perdigao.docthis", + // Files + "bungcip.better-toml", + "yzhang.markdown-all-in-one", + // Global + "editorconfig.editorconfig", + "gruntfuggly.todo-tree", + "eamodio.gitlens", + // Front + "naumovs.color-highlight", + "octref.vetur", + // Theme + "vscode-icons-team.vscode-icons", + // Docker + "ms-azuretools.vscode-docker" + ] + } }, - // Add the IDs of extensions you want installed when the container is created. - "extensions": [ - // TypeScript - "dbaeumer.vscode-eslint", - "oouo-diogo-perdigao.docthis", - // Files - "bungcip.better-toml", - "yzhang.markdown-all-in-one", - // Global - "editorconfig.editorconfig", - "gruntfuggly.todo-tree", - "eamodio.gitlens", - // Front - "naumovs.color-highlight", - "octref.vetur", - // Theme - "vscode-icons-team.vscode-icons", - // Docker - "ms-azuretools.vscode-docker" - ], - // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], diff --git a/.devcontainer/etc/sudoers.d/override b/.devcontainer/etc/sudoers.d/override deleted file mode 100644 index 1eac729..0000000 --- a/.devcontainer/etc/sudoers.d/override +++ /dev/null @@ -1,2 +0,0 @@ -# Allow members of group sudo to execute any command without password -%sudo ALL = (ALL) NOPASSWD: ALL diff --git a/.devcontainer/home/.config/starship.toml b/.devcontainer/home/.config/starship.toml index d1d927a..6a93da2 100644 --- a/.devcontainer/home/.config/starship.toml +++ b/.devcontainer/home/.config/starship.toml @@ -17,7 +17,7 @@ only_nonzero_diffs = true disabled = false [cmd_duration] -format = '[祥$duration ]($style)' +format = '[󰔛 $duration ]($style)' [status] style = "bg:blue" diff --git a/.devcontainer/home/.profile b/.devcontainer/home/.profile deleted file mode 100644 index 1efaee5..0000000 --- a/.devcontainer/home/.profile +++ /dev/null @@ -1,15 +0,0 @@ -# Bash -if [ -n "$BASH_VERSION" ]; then - if [ -f "$HOME/.bashrc" ]; then - . "$HOME/.bashrc" - fi -fi - -# Path -if [ -d "$HOME/bin" ] ; then - PATH="$HOME/bin:$PATH" -fi - -if [ -d "$HOME/.local/bin" ] ; then - PATH="$HOME/.local/bin:$PATH" -fi diff --git a/.devcontainer/home/.zshrc b/.devcontainer/home/.zshrc index 70bad62..929ac7c 100644 --- a/.devcontainer/home/.zshrc +++ b/.devcontainer/home/.zshrc @@ -7,8 +7,27 @@ export SAVEHIST=10000 export HISTFILE=~/.zsh_history export EDITOR=vim +# PATH +if [ -d "$HOME/bin" ] ; then + PATH="$HOME/bin:$PATH" +fi + +if [ -d "$HOME/.local/bin" ] ; then + PATH="$HOME/.local/bin:$PATH" +fi + # Oh-My-ZSH -plugins=(git docker docker-compose node nvm npm) +plugins=(sudo aliases git docker docker-compose node nvm npm) + +# Python +echo 'eval "$(uv generate-shell-completion zsh)"' >> ~/.zshrc +echo 'eval "$(uvx --generate-shell-completion zsh)"' >> ~/.zshrc + +# Rust +export PATH="$HOME/.cargo/bin:$PATH" + +# Go +export PATH=$PATH:/usr/local/go/bin # NVM [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm @@ -16,12 +35,11 @@ plugins=(git docker docker-compose node nvm npm) # LSD alias ls='lsd -A' -alias ll='ls -lA' -alias lt='ls --tree' +alias ll='lsd -lA' +alias lt='lsd --tree' # TheFuck eval $(thefuck --alias) # Starship -source ~/.profile eval "$(starship init zsh)" diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 19d3a54..d2b3315 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -1,43 +1,76 @@ -name: docker +name: Docker + on: + pull_request: + branches: + - master + - develop push: branches: - - 'master' + - develop tags: - '*' - pull_request: - branches: - - 'master' jobs: docker: runs-on: ubuntu-latest steps: - - - name: Checkout - uses: actions/checkout@v3 - - - name: Docker meta + - uses: actions/checkout@v4 + + - name: Docker meta id: meta - uses: docker/metadata-action@v3 + uses: docker/metadata-action@v5 with: - images: ealen/codespaces-typescript + # list of Docker images to use as base name for tags + images: | + ealen/codespaces + ghcr.io/Ealenn/codespaces + # generate Docker tags based on the following events/attributes tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - - - name: Login to DockerHub + type=raw,value=latest,enable=${{ github.ref_type == 'tag' }} + type=raw,value=develop,enable=${{ github.ref == format('refs/heads/{0}', 'develop') }} + type=semver,pattern={{version}},enable=${{ github.ref_type == 'tag' }} + type=semver,pattern={{major}}.{{minor}},enable=${{ github.ref_type == 'tag' }} + type=semver,pattern={{major}},enable=${{ github.ref_type == 'tag' }} + + - name: Login to Docker Hub if: github.event_name != 'pull_request' - uses: docker/login-action@v1 + uses: docker/login-action@v3 with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v3 + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Login to GHCR + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 with: - context: ./.devcontainer + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Build and push + uses: docker/build-push-action@v6 + with: + sbom: true + platforms: 'linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x' push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + annotations: ${{ steps.meta.outputs.annotations }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Docker Hub Description + if: success() && github.ref == format('refs/heads/{0}', 'master') + uses: peter-evans/dockerhub-description@v4 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + short-description: ${{ github.event.repository.description }} + repository: ealen/codespaces diff --git a/README.md b/README.md index c7b12f2..81d55b4 100644 --- a/README.md +++ b/README.md @@ -1,169 +1,118 @@ -# TypeScript DevContainer Workspace +# 🧑‍💻 Codespace - Development Environment -[![GitHub stars](https://img.shields.io/github/stars/Ealenn/codespaces-typescript?style=for-the-badge)](https://github.com/Ealenn/codespaces-typescript/stargazers) -[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/ealen/codespaces-typescript?color=blue&style=for-the-badge)](https://hub.docker.com/r/ealen/codespaces-typescript/tags) -[![Docker Pulls](https://img.shields.io/docker/pulls/ealen/codespaces-typescript?style=for-the-badge)](https://hub.docker.com/r/ealen/codespaces-typescript/tags) +[![GitHub stars](https://img.shields.io/github/stars/Ealenn/codespaces?style=for-the-badge)](https://github.com/Ealenn/codespaces/stargazers) +[![Docker Pulls](https://img.shields.io/docker/pulls/ealen/codespaces?style=for-the-badge)](https://hub.docker.com/r/ealen/codespaces) -![](./vscode.png) +> A modern developer-friendly environment optimized for containers, VS Code Remote Containers, and GitHub Codespaces. -The Visual [Studio Code Remote Containers extension](https://code.visualstudio.com/docs/remote/containers) lets you use a Docker container as a full-featured development environment. It allows you to open any folder inside (or mounted into) a container and take advantage of Visual Studio Code's full feature set. +## 📦 Environment -A `devcontainer.json` file in your project tells VS Code how to access a development container with a well-defined tool and runtime stack. This container can be used to run an application or to separate tools, libraries, or runtimes needed for working with a codebase. +- **Base:** [Ubuntu 24.04](https://hub.docker.com/_/ubuntu) -[More information](https://code.visualstudio.com/docs/remote/containers) +### 🖥 Terminal + - [ZSH](https://www.zsh.org/) & [Oh-My-ZSH](https://github.com/ohmyzsh/ohmyzsh) Zsh is a shell designed for interactive use, although it is also a powerful scripting language. + - [Starship](https://starship.rs/) The minimal, blazing-fast, and infinitely customizable prompt for any shell! + - [LSD](https://github.com/Peltoche/lsd) Colorizes the ls output with color and icons. + - [TheFuck](https://github.com/nvbn/thefuck#installation) The Fuck is a magnificent app, that corrects errors in previous console commands. + - [JQ](https://github.com/stedolan/jq) jq is a lightweight and flexible command-line JSON processor. + - [fd-find](https://github.com/sharkdp/fd) A simple, fast and user-friendly alternative to 'find' -> Table of contents +### 🔧 Tools + - [Vim](https://www.vim.org/) Vim is a highly configurable text editor built to make creating and changing any kind of text very efficient. + - [NeoVim](https://github.com/neovim/neovim) Vim-fork focused on extensibility and usability + - [ecosse3/nvim](https://github.com/ecosse3/nvim) A non-minimal Neovim config built to work most efficiently with Frontend Development +- But also `git`, `gpg`, `curl`, `wget`, etc. -- [TypeScript DevContainer Workspace](#typescript-devcontainer-workspace) -- [Dev-Container](#dev-container) - - [How to use](#how-to-use) - - [Environment](#environment) - - [CLI](#cli) - - [Libs](#libs) - - [Essential](#essential) - - [Others](#others) - - [How to customize](#how-to-customize) -- [VSCode Extensions](#vscode-extensions) - - [TypeScript](#typescript) - - [Files](#files) - - [Global](#global) - - [Front](#front) - - [Theme](#theme) - - [Docker](#docker) +### 🧑‍💻 Languages & Runtimes +- [Go](https://go.dev) A simple, fast, and reliable language designed for scalable and efficient software development. +- [Rust](https://www.rust-lang.org) A language empowering everyone to build reliable and efficient software. +- [NVM](https://github.com/nvm-sh/nvm) with [Node LTS](https://nodejs.dev/) installed by default. NVM is a version manager for NodeJS. +- [ZX](https://github.com/google/zx) Bash is great, but when it comes to writing scripts, people usually choose a more convenient programming language. +- [Python3](https://www.python.org) Python is a programming language that lets you work quickly and integrate systems more effectively. + - [UV](https://github.com/astral-sh/uv) An extremely fast Python package and project manager, written in Rust. -# Dev-Container +### 🐳 Docker-in-Docker +- Full Docker CLI and Compose support inside container +- `docker.sock` ready for volume mount -## How to use +## 💡 Remote Containers (VS Code) -In your project, create `.devcontainer/devcontainer.json` [[?]](https://aka.ms/devcontainer.json) : +![Remote Container](./vscode.png) -``` js -{ - "name": "TypeScript", - "image": "ealen/codespaces-typescript", +This image is compatible with [VS Code Remote Containers](https://code.visualstudio.com/docs/remote/containers), enabling a full development experience using a containerized environment. +### Example `.devcontainer/devcontainer.json`: + +```json +{ + "name": "codespaces", + "image": "ealen/codespaces", "extensions": [ - // TypeScript + "golang.go", "dbaeumer.vscode-eslint", "oouo-diogo-perdigao.docthis", - // Files "bungcip.better-toml", + "redhat.vscode-yaml", "yzhang.markdown-all-in-one", - // Global "editorconfig.editorconfig", "gruntfuggly.todo-tree", "eamodio.gitlens", - // Front "naumovs.color-highlight", - "octref.vetur", - // Theme "vscode-icons-team.vscode-icons", - // Docker "ms-azuretools.vscode-docker" ], - "settings": { - "eslint.alwaysShowStatus": true, "workbench.iconTheme": "vscode-icons", "editor.fontFamily": "Consolas, 'Courier New', monospace, hack, 'Hack Nerd Font Mono'", "terminal.integrated.fontFamily": "Consolas, 'Hack Nerd Font Mono'", - "terminal.integrated.fontSize": 14 + "terminal.integrated.fontSize": 14, + "files.autoSave": "onFocusChange", + "editor.tabSize": 2, + "eslint.format.enable": true, }, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Uncomment the next line to run commands after the container is created - for example installing curl. - // "postCreateCommand": "npm ci", // You can also use ZX script or MAKE command - "mounts": [ - "source=/home/ealen/.ssh,target=/home/user/.ssh,type=bind,readonly", - "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" + "source=/home/YOUR_USER/.ssh,target=/home/ubuntu/.ssh,type=bind,readonly", + "source=/home/YOUR_USER/.gnupg,target=/home/ubuntu/.gnupg,type=bind,readonly", + "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ] } ``` -An example is available [here](./example). +> 💡 You must install a Nerd Font such as [Hack Nerd Font Mono](https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/Hack/Regular/complete/Hack%20Regular%20Nerd%20Font%20Complete%20Mono.ttf) -> /!\ You must install Nerd Font "[Hack Nerd Font Mono](https://github.com/ryanoasis/nerd-fonts/raw/master/patched-fonts/Hack/Regular/complete/Hack%20Regular%20Nerd%20Font%20Complete%20Mono.ttf)" /!\ +# 🐋 Raw Docker Usage -### Environment +![NVIM](./nvim.png) -Based on [Ubuntu 22.04](https://hub.docker.com/_/ubuntu) __ +You can run the image without VS Code using standard Docker commands. -- [ZSH](https://www.zsh.org/) & [Oh-My-ZSH](https://github.com/ohmyzsh/ohmyzsh) Zsh is a shell designed for interactive use, although it is also a powerful scripting language. -- [Starship](https://starship.rs/) The minimal, blazing-fast, and infinitely customizable prompt for any shell! -- [LSD](https://github.com/Peltoche/lsd) Colorizes the ls output with color and icons. +**Example**: Run with persistent volumes and access to Docker -### CLI - -- [Vim](https://www.vim.org/) Vim is a highly configurable text editor built to make creating and changing any kind of text very efficient. -- [TheFuck](https://github.com/nvbn/thefuck#installation) The Fuck is a magnificent app, that corrects errors in previous console commands. -- [JQ](https://github.com/stedolan/jq) jq is a lightweight and flexible command-line JSON processor. -- [gi](https://github.com/Ealenn/gi-gitignore-generator) CLI to generate .gitignore or .gitignore_global files -- [ZX](https://github.com/google/zx) Bash is great, but when it comes to writing scripts, people usually choose a more convenient programming language. - -### Libs - -- [Docker](https://www.docker.com/) & [Docker-Compose](https://docs.docker.com/compose/) Lets you run Docker within Docker. -- [NVM](https://github.com/nvm-sh/nvm) with [Node LTS](https://nodejs.dev/) installed by default. NVM is a version manager for NodeJS. -- [Python3](https://www.python.org) Python is a programming language that lets you work quickly and integrate systems more effectively. - -### Essential - -- [Git](https://git-scm.com/) Git is a free and open source distributed version control system. -- [Curl](https://curl.se/) Command line tool for transferring data with URLs. -- [Wget](https://www.gnu.org/software/wget/) GNU Wget is a free software package for retrieving files using HTTP, HTTPS, FTP and FTPS. - -### Others - -- [ca-certificates](https://packages.debian.org/en/sid/ca-certificates) Contains the certificate authorities shipped with Mozilla's browser to allow SSL-based applications to check for the authenticity of SSL connections. -- [gnupg](https://packages.debian.org/en/sid/gnupg) GnuPG is GNU's tool for secure communication and data storage. - -## How to customize - -Create `.devcontainer/Dockerfile` and extend this codespace : - -```dockerfile -FROM ealen/codespaces-typescript - -# Add your changes -``` - -Update your `.devcontainer/decontainer.json` to build your custom image : - -```js -{ - "name": "TypeScript", - "build": { - "context": ".", - "dockerfile": "./Dockerfile" - } - ... -} +```sh +docker run -it --rm \ + -v ~/.ssh:/home/ubuntu/.ssh:ro \ + -v ~/.gnupg:/home/ubuntu/.gnupg:ro \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v $(pwd):/workspace \ + -e PUID=$(id -u) \ + -e PGID=$(id -g) \ + -w /workspace \ + ealen/codespaces ``` -# VSCode Extensions +> You can now launch nvim from inside the container, and work on your project directly from the mounted volume. -## TypeScript -- [dbaeumer.vscode-eslint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) Integrates ESLint JavaScript into VS Code. -- [oouo-diogo-perdigao.docthis](https://marketplace.visualstudio.com/items?itemName=oouo-diogo-perdigao.docthis) Automatically generates detailed JSDoc comments in TypeScript and JavaScript files. +# 💻 GitHub Codespaces Support -## Files -- [bungcip.better-toml](https://marketplace.visualstudio.com/items?itemName=bungcip.better-toml) Better TOML Language support -- [yzhang.markdown-all-in-one](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) All you need to write Markdown +This image is fully compatible with [GitHub Codespaces](https://docs.github.com/en/codespaces)! -## Global -- [editorconfig.editorconfig](https://marketplace.visualstudio.com/items?itemName=editorconfig.editorconfig) EditorConfig Support for Visual Studio Code -- [gruntfuggly.todo-tree](https://marketplace.visualstudio.com/items?itemName=gruntfuggly.todo-tree) Show TODO, FIXME, etc. comment tags in a tree view -- [eamodio.gitlens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) Supercharge the Git capabilities built into Visual Studio Code +To use: +1. Create a .devcontainer/devcontainer.json in your repo (as shown above). +2. Push to GitHub. +3. Open the repo in Codespaces. -## Front -- [naumovs.color-highlight](https://marketplace.visualstudio.com/items?itemName=naumovs.color-highlight) Highlight web colors in your editor -- [octref.vetur](https://marketplace.visualstudio.com/items?itemName=octref.vetur) Vue tooling for VS Code +That's it! You'll get a fully functional container with Docker, ZSH, Starship, Go, Rust, Node, and Python already configured. -## Theme -- [vscode-icons-team.vscode-icons](https://marketplace.visualstudio.com/items?itemName=vscode-icons-team.vscode-icons) Icons for Visual Studio Code +# 📁 Example Repo -## Docker -- [ms-azuretools.vscode-docker](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker) Makes it easy to create, manage, and debug containerized applications. +You can find a working example inside the [example/](/example/) folder. diff --git a/example/.devcontainer/devcontainer.json b/example/.devcontainer/devcontainer.json index 14977dc..60c22c4 100644 --- a/example/.devcontainer/devcontainer.json +++ b/example/.devcontainer/devcontainer.json @@ -1,33 +1,40 @@ { - "name": "TypeScript", - "image": "ealen/codespaces-typescript", - "extensions": [ - // TypeScript - "dbaeumer.vscode-eslint", - "oouo-diogo-perdigao.docthis", - // Files - "yzhang.markdown-all-in-one", - // Global - "editorconfig.editorconfig", - "gruntfuggly.todo-tree", - // Theme - "vscode-icons-team.vscode-icons", - // Docker - "ms-azuretools.vscode-docker" + "name": "codespaces", + "image": "ealen/codespaces", + "customizations": { + "vscode": { + "extensions": [ + "dbaeumer.vscode-eslint", + "oouo-diogo-perdigao.docthis", + "bungcip.better-toml", + "redhat.vscode-yaml", + "yzhang.markdown-all-in-one", + "editorconfig.editorconfig", + "gruntfuggly.todo-tree", + "eamodio.gitlens", + "naumovs.color-highlight", + "vscode-icons-team.vscode-icons", + "ms-azuretools.vscode-docker" + ], + "settings": { + "eslint.alwaysShowStatus": true, + "workbench.iconTheme": "vscode-icons", + "editor.fontFamily": "Consolas, 'Courier New', monospace, 'Hack Nerd Font Mono'", + "terminal.integrated.fontFamily": "Consolas, 'Hack Nerd Font Mono'", + "terminal.integrated.fontSize": 14 + }, + } + }, + + "forwardPorts": [ + 8080 ], - "settings": { - "eslint.alwaysShowStatus": true, - "workbench.iconTheme": "vscode-icons", - "editor.fontFamily": "Consolas, 'Courier New', monospace, 'Hack Nerd Font Mono'", - "terminal.integrated.fontFamily": "Consolas, 'Hack Nerd Font Mono'", - "terminal.integrated.fontSize": 14 - }, - "forwardPorts": [ 8080 ], "postCreateCommand": "npm ci", "mounts": [ "source=/home/ealen/.ssh,target=/home/user/.ssh,type=bind,readonly", + "source=/home/ealen/.gnupg,target=/home/user/.gnupg,type=bind,readonly", "source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" ] } diff --git a/nvim.png b/nvim.png new file mode 100644 index 0000000000000000000000000000000000000000..7368fa905c7f444e23dcd1ab3be047d983b6d8b3 GIT binary patch literal 75242 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 literal 0 HcmV?d00001 From 833cdd083439892fa5db839b3b63bf1a938204d1 Mon Sep 17 00:00:00 2001 From: Rudy Marchandise Date: Sat, 3 May 2025 22:52:37 +0200 Subject: [PATCH 2/6] fix: docker context --- .github/workflows/docker.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index d2b3315..c391f02 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -57,6 +57,7 @@ jobs: - name: Build and push uses: docker/build-push-action@v6 with: + context: "{{defaultContext}}:.devcontainer" sbom: true platforms: 'linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x' push: ${{ github.event_name != 'pull_request' }} From e447d56caf01744305c77870900711c0104943dc Mon Sep 17 00:00:00 2001 From: Rudy Marchandise Date: Sat, 3 May 2025 23:09:03 +0200 Subject: [PATCH 3/6] fix: remove riscv64 platform --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index c391f02..6c132cb 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -59,7 +59,7 @@ jobs: with: context: "{{defaultContext}}:.devcontainer" sbom: true - platforms: 'linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/riscv64,linux/s390x' + platforms: 'linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x' push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From 9d7e68d8bd5b91b31cc298f77cbfc46b7d850f03 Mon Sep 17 00:00:00 2001 From: Rudy Marchandise Date: Sat, 3 May 2025 23:22:50 +0200 Subject: [PATCH 4/6] fix: remove ppc64le platform --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6c132cb..fec12c3 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -59,7 +59,7 @@ jobs: with: context: "{{defaultContext}}:.devcontainer" sbom: true - platforms: 'linux/amd64,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x' + platforms: 'linux/amd64,linux/arm/v7,linux/arm64/v8,linux/s390x' push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From 5b615063a4b2a855956dc01c2053ecd7e0b48360 Mon Sep 17 00:00:00 2001 From: Rudy Marchandise Date: Sat, 3 May 2025 23:33:39 +0200 Subject: [PATCH 5/6] fix: remove s390x platform --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index fec12c3..6efa0bd 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -59,7 +59,7 @@ jobs: with: context: "{{defaultContext}}:.devcontainer" sbom: true - platforms: 'linux/amd64,linux/arm/v7,linux/arm64/v8,linux/s390x' + platforms: 'linux/amd64,linux/arm/v7,linux/arm64/v8' push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} From 945272596f88d1fb21d9904553ece66fdaaa8108 Mon Sep 17 00:00:00 2001 From: Rudy Marchandise Date: Sun, 4 May 2025 12:52:27 +0200 Subject: [PATCH 6/6] feat(actions): auto release --- .github/workflows/github-bump.yml | 29 +++++++++++++++++++++++++++++ .github/workflows/pull-request.yml | 19 +++++++++++++++++++ README.md | 14 ++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 .github/workflows/github-bump.yml create mode 100644 .github/workflows/pull-request.yml diff --git a/.github/workflows/github-bump.yml b/.github/workflows/github-bump.yml new file mode 100644 index 0000000..061c972 --- /dev/null +++ b/.github/workflows/github-bump.yml @@ -0,0 +1,29 @@ +name: Bump + +on: + push: + branches: + - master + +jobs: + bump: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Bump version and push tag + id: tag_version + uses: mathieudutour/github-tag-action@v6.1 + with: + github_token: ${{ secrets.PAT }} + tag_prefix: '' + + - name: Create a GitHub release + uses: ncipollo/release-action@v1 + with: + token: ${{ secrets.PAT }} + tag: ${{ steps.tag_version.outputs.new_tag }} + name: ${{ steps.tag_version.outputs.new_tag }} + body: ${{ steps.tag_version.outputs.changelog }} + allowUpdates: true + generateReleaseNotes: true diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 0000000..effa655 --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,19 @@ +name: "Pull Request" + +on: + pull_request_target: + types: + - opened + - edited + - reopened + +jobs: + main: + name: Validate PR title + runs-on: ubuntu-latest + permissions: + pull-requests: read + steps: + - uses: amannn/action-semantic-pull-request@v5 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 81d55b4..b9c2bc0 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,20 @@ docker run -it --rm \ > You can now launch nvim from inside the container, and work on your project directly from the mounted volume. +💡 **Note**: The Codespaces Docker image is also available on GitHub Container Registry. + +If your company restricts access to docker.io, you can use the GitHub-hosted image instead by replacing `ealen/codespaces` with `ghcr.io/ealenn/codespaces`. + +```sh +alias codespaces='docker run -it --rm \ + -v "$HOME/.ssh:/home/ubuntu/.ssh:ro" \ + -v "$HOME/.gnupg:/home/ubuntu/.gnupg:ro" \ + -v "/var/run/docker.sock:/var/run/docker.sock" \ + -v "$PWD:/workspace" \ + -w /workspace \ + ghcr.io/ealenn/codespaces' +``` + # 💻 GitHub Codespaces Support This image is fully compatible with [GitHub Codespaces](https://docs.github.com/en/codespaces)!