mirror of
https://github.com/tiennm99/composes.git
synced 2026-10-11 03:13:16 +00:00
refactor(code-server): install Docker CLI, plugins and gh into home
- Drop the Docker and GitHub apt repositories and the Ruby build headers from the image; keep build-essential, bubblewrap, zip and unzip. - Document home installs for the Docker CLI with its Compose and Buildx plugins, gh, Go, Rust, Python, Node and Java, ordered so each installer writes to ~/.zshrc and SDKMAN stays last. - Drop the Ruby, GitLab CLI and jq instructions.
This commit is contained in:
1 parent
c1ef9e7680
commit
ee2f92de19
2 files changed
+79
-83
No files matched your search
@@ -6,30 +6,6 @@ USER root
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
build-essential bubblewrap unzip zip \
|
||||
libffi-dev libssl-dev libyaml-dev zlib1g-dev \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Docker CLI with the Compose and Buildx plugins, from Docker's apt repository,
|
||||
# and GitHub CLI, from GitHub's apt repository.
|
||||
RUN install -m 0755 -d /etc/apt/keyrings \
|
||||
&& curl -fsSL https://download.docker.com/linux/debian/gpg \
|
||||
-o /etc/apt/keyrings/docker.asc \
|
||||
&& curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
|
||||
-o /etc/apt/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& chmod a+r /etc/apt/keyrings/docker.asc /etc/apt/keyrings/githubcli-archive-keyring.gpg \
|
||||
&& printf '%s\n' \
|
||||
'Types: deb' \
|
||||
'URIs: https://download.docker.com/linux/debian' \
|
||||
"Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")" \
|
||||
'Components: stable' \
|
||||
"Architectures: $(dpkg --print-architecture)" \
|
||||
'Signed-By: /etc/apt/keyrings/docker.asc' \
|
||||
> /etc/apt/sources.list.d/docker.sources \
|
||||
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" \
|
||||
> /etc/apt/sources.list.d/github-cli.list \
|
||||
&& apt-get update \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
docker-ce-cli docker-buildx-plugin docker-compose-plugin gh \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Workspace directory, owned by the container user.
|
||||
|
||||
+79
-59
@@ -4,17 +4,25 @@
|
||||
official `codercom/code-server` image.
|
||||
|
||||
The image ships code-server on Debian with `git`, `zsh`, `curl`, `sudo` and a
|
||||
few editors. The `Dockerfile` adds `build-essential`, `bubblewrap`, `zip`,
|
||||
`unzip`, the headers Ruby builds against, the Docker CLI with its Compose and
|
||||
Buildx plugins, and the GitHub CLI, and wraps the entrypoint so it starts in
|
||||
`/workspace` and `coder` can use the Docker socket. Language toolchains and
|
||||
other CLIs are installed into home, below.
|
||||
few editors. The `Dockerfile` adds `build-essential`, `bubblewrap`, `zip` and
|
||||
`unzip`, and wraps the entrypoint so it starts in `/workspace` and `coder` can
|
||||
use the Docker socket. Language toolchains and CLIs are installed into home,
|
||||
below.
|
||||
|
||||
## Toolchains
|
||||
|
||||
Only `/home/coder` and `/workspace` survive a redeploy, so install toolchains
|
||||
and CLIs into home from the editor's terminal. Each command below was tested in
|
||||
the image. Open a new terminal afterwards so the `PATH` changes apply.
|
||||
the image, in this order. Open a new terminal afterwards so the `PATH` changes
|
||||
apply.
|
||||
|
||||
The terminal is zsh, and the image ships no `~/.zshrc`. Create it first, with
|
||||
`~/.local/bin` on `PATH` for the binaries below:
|
||||
|
||||
```sh
|
||||
mkdir -p ~/.local/bin
|
||||
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
|
||||
```
|
||||
|
||||
### Official install methods
|
||||
|
||||
@@ -43,38 +51,36 @@ curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
uv python install 3.13
|
||||
```
|
||||
|
||||
Ruby, with rbenv and its ruby-build plugin, each cloned with git as their
|
||||
READMEs document ([rbenv](https://github.com/rbenv/rbenv#basic-git-checkout),
|
||||
[ruby-build](https://github.com/rbenv/ruby-build#clone-as-rbenv-plugin-using-git)).
|
||||
Debian's `ruby` package is 3.3, several releases behind. Rubies are compiled into
|
||||
`~/.rbenv/versions` against the headers the `Dockerfile` installs.
|
||||
`rbenv init` adds itself to the login shell's startup file, `~/.zprofile`:
|
||||
Rust, with rustup, from the [install page](https://rustup.rs/). The toolchain
|
||||
lives in `~/.rustup`, and `cargo` with the tools it installs in `~/.cargo/bin`;
|
||||
rustup adds itself to `~/.zshenv`. `-y` accepts the default install:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
|
||||
~/.rbenv/bin/rbenv init
|
||||
eval "$(~/.rbenv/bin/rbenv init - zsh)"
|
||||
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build
|
||||
V=$(rbenv install -l 2>/dev/null | grep -E '^[0-9]+\.[0-9]+\.[0-9]+$' | tail -1)
|
||||
rbenv install "$V" && rbenv global "$V"
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
. "$HOME/.cargo/env"
|
||||
```
|
||||
|
||||
To get newer Ruby versions listed, `git -C "$(rbenv root)"/plugins/ruby-build pull`.
|
||||
|
||||
Java, with SDKMAN, from its [install guide](https://sdkman.io/install/).
|
||||
SDKMAN and every JDK it installs live in `~/.sdkman`; the installer adds itself
|
||||
to `~/.bashrc` and `~/.zshrc`, and needs the `zip` and `unzip` the `Dockerfile`
|
||||
installs. `sdk install java` with no version takes SDKMAN's default, the
|
||||
current Temurin LTS:
|
||||
Docker Compose and Buildx, as CLI plugins in `~/.docker/cli-plugins`, the
|
||||
manual install from the
|
||||
[Compose docs](https://docs.docker.com/compose/install/linux/#install-the-plugin-manually)
|
||||
and the [Buildx README](https://github.com/docker/buildx#manual-download). The
|
||||
Docker client itself is below:
|
||||
|
||||
```sh
|
||||
curl -s "https://get.sdkman.io" | bash
|
||||
. "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||
sdk install java
|
||||
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
|
||||
mkdir -p "$DOCKER_CONFIG/cli-plugins"
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
|
||||
V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/docker/compose/releases/latest | sed 's|.*/||')
|
||||
curl -fsSL "https://github.com/docker/compose/releases/download/$V/docker-compose-linux-$(uname -m)" -o "$DOCKER_CONFIG/cli-plugins/docker-compose"
|
||||
|
||||
V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/docker/buildx/releases/latest | sed 's|.*/||')
|
||||
curl -fsSL "https://github.com/docker/buildx/releases/download/$V/buildx-$V.linux-$ARCH" -o "$DOCKER_CONFIG/cli-plugins/docker-buildx"
|
||||
|
||||
chmod +x "$DOCKER_CONFIG/cli-plugins/docker-compose" "$DOCKER_CONFIG/cli-plugins/docker-buildx"
|
||||
```
|
||||
|
||||
`sdk list java` shows other vendors and versions, and `sdk install gradle` or
|
||||
`sdk install maven` adds a build tool the same way.
|
||||
To upgrade them, run the same commands again.
|
||||
|
||||
### Suggested by AI, may not be the optimal way
|
||||
|
||||
@@ -90,29 +96,52 @@ puts tools in `~/go/bin`:
|
||||
|
||||
```sh
|
||||
V=$(curl -fsSL 'https://go.dev/VERSION?m=text' | head -1)
|
||||
mkdir -p ~/.local
|
||||
curl -fsSL "https://go.dev/dl/$V.linux-$(dpkg --print-architecture).tar.gz" | tar -C ~/.local -xzf -
|
||||
echo 'export PATH="$HOME/.local/go/bin:$HOME/go/bin:$PATH"' >> ~/.bashrc
|
||||
echo 'export PATH="$HOME/.local/go/bin:$HOME/go/bin:$PATH"' >> ~/.zshrc
|
||||
```
|
||||
|
||||
To upgrade Go, `rm -rf ~/.local/go` and run the same commands again, without
|
||||
the `echo` line.
|
||||
|
||||
jq, the binary from its
|
||||
[releases page](https://github.com/jqlang/jq/releases), into `~/.local/bin`,
|
||||
with no documented location:
|
||||
Docker CLI and GitHub CLI, as the release binaries each project publishes,
|
||||
into `~/.local/bin`:
|
||||
|
||||
- Docker: [static binaries](https://docs.docker.com/engine/install/binaries/),
|
||||
documented for `/usr/bin`. Only the client is taken; the daemon is the
|
||||
host's, through the socket.
|
||||
- GitHub CLI: the `.tar.gz` on [cli.github.com](https://cli.github.com/), with
|
||||
no documented location.
|
||||
|
||||
```sh
|
||||
mkdir -p ~/.local/bin
|
||||
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
|
||||
ARCH=$(dpkg --print-architecture)
|
||||
|
||||
V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/jqlang/jq/releases/latest | sed 's|.*/||')
|
||||
curl -fsSL "https://github.com/jqlang/jq/releases/download/$V/jq-linux-$ARCH" -o ~/.local/bin/jq && chmod +x ~/.local/bin/jq
|
||||
V=$(curl -fsSL https://download.docker.com/linux/static/stable/$(uname -m)/ | grep -o 'docker-[0-9.]*\.tgz' | sort -V | tail -1)
|
||||
curl -fsSL "https://download.docker.com/linux/static/stable/$(uname -m)/$V" | tar -C ~/.local/bin -xzf - --strip-components=1 docker/docker
|
||||
|
||||
V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/cli/cli/releases/latest | sed 's|.*/v||')
|
||||
curl -fsSL "https://github.com/cli/cli/releases/download/v$V/gh_${V}_linux_$ARCH.tar.gz" | tar -C ~/.local/bin -xzf - --strip-components=2 "gh_${V}_linux_$ARCH/bin/gh"
|
||||
```
|
||||
|
||||
To upgrade it, run the same commands again, without the `echo` line; the new
|
||||
binary overwrites the old one.
|
||||
To upgrade one, run the `ARCH=` line and that tool's two lines again; the
|
||||
new binary overwrites the old one.
|
||||
|
||||
### Java, last
|
||||
|
||||
Java, with SDKMAN, from its [install guide](https://sdkman.io/install/).
|
||||
SDKMAN and every JDK it installs live in `~/.sdkman`; it needs the `zip` and
|
||||
`unzip` the `Dockerfile` installs. Its installer appends to `~/.zshrc` and
|
||||
requires its lines to stay at the end of the file, so install it after
|
||||
everything above. `sdk install java` with no version takes SDKMAN's default,
|
||||
the current Temurin LTS:
|
||||
|
||||
```sh
|
||||
curl -s "https://get.sdkman.io" | bash
|
||||
. "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||
sdk install java
|
||||
```
|
||||
|
||||
`sdk list java` shows other vendors and versions, and `sdk install gradle` or
|
||||
`sdk install maven` adds a build tool the same way.
|
||||
|
||||
## Environment
|
||||
|
||||
@@ -141,8 +170,8 @@ its `\h` uses the real hostname.
|
||||
|
||||
## Docker access
|
||||
|
||||
The host's Docker socket is bind-mounted at `/var/run/docker.sock`. The
|
||||
`Dockerfile` installs the client only; the daemon is the host's. Containers
|
||||
The host's Docker socket is bind-mounted at `/var/run/docker.sock`. The image
|
||||
ships no Docker CLI; install the client into home as above. Containers
|
||||
started through it are siblings on the host, not children, so bind mounts in
|
||||
them resolve against host paths.
|
||||
|
||||
@@ -197,23 +226,14 @@ The home volume needs no such step, because the image already ships
|
||||
|
||||
`build-essential`, `bubblewrap`, `zip` and `unzip` are in the `Dockerfile`
|
||||
rather than home because their projects publish no standalone binaries;
|
||||
Debian's packages are the install method, and they land outside home.
|
||||
`build-essential` supplies the `gcc` and `make` that native builds expect:
|
||||
node-gyp addons, Python sdists, Rust crates using `cc`, and Ruby built by
|
||||
rbenv. `libffi-dev`, `libssl-dev`, `libyaml-dev` and `zlib1g-dev` are the
|
||||
headers a rbenv-built Ruby needs for its `fiddle`, `openssl`, `psych` and
|
||||
`zlib` extensions; without them `rbenv install` fails or leaves those out.
|
||||
Debian's packages are the install method, and they land outside home. The base
|
||||
image ships none of them. `build-essential` supplies the `gcc` and `make` that
|
||||
native builds expect: the linker `cargo` calls, node-gyp addons and Python
|
||||
sdists.
|
||||
|
||||
The Docker CLI, its Compose and Buildx plugins, and the GitHub CLI come from
|
||||
Docker's and GitHub's signed apt repositories, which is each vendor's documented
|
||||
install for Debian. Neither documents an install into home, and Coolify builds
|
||||
with `--pull`, so they update with each rebuild rather than by hand. The GitLab
|
||||
CLI is not in the image: GitLab publishes no apt repository, only Homebrew and
|
||||
a community one.
|
||||
|
||||
Copies of `docker`, `gh` or the plugins left in `~/.local/bin` or
|
||||
`~/.docker/cli-plugins` from an older setup take precedence over the image's
|
||||
and should be deleted.
|
||||
Everything else lives in home rather than the image, so the image build stays
|
||||
small and a redeploy does not reinstall or upgrade tools behind your back;
|
||||
upgrading is the same commands run again.
|
||||
|
||||
## Shell
|
||||
|
||||
|
||||
Reference in new issue
Block a user