mirror of
https://github.com/tiennm99/composes.git
synced 2026-10-11 03:13:16 +00:00
feat(code-server): install Docker CLI and gh from vendor apt repos
- Install the Docker CLI with its Compose and Buildx plugins, and the GitHub CLI, from Docker's and GitHub's signed apt repositories; drop their home installs and the GitLab CLI from the README. - Select the shell with SHELL and the start folder with DEFAULT_WORKSPACE instead of chsh and working_dir. - Add an optional CODE_SERVER_APP_NAME. - Document installing Java with SDKMAN.
This commit is contained in:
1 parent
03a2016f23
commit
c1ef9e7680
5 files changed
+84
-58
No files matched your search
@@ -13,3 +13,6 @@ GIT_EMAIL=
|
|||||||
# Container hostname, also passed in as HOST -- the name zsh's prompt shows.
|
# Container hostname, also passed in as HOST -- the name zsh's prompt shows.
|
||||||
# Not named HOSTNAME: the deploying shell's own HOSTNAME would override it.
|
# Not named HOSTNAME: the deploying shell's own HOSTNAME would override it.
|
||||||
SERVICE_HOSTNAME=code-server
|
SERVICE_HOSTNAME=code-server
|
||||||
|
|
||||||
|
# Name shown in the title bar and welcome page.
|
||||||
|
# CODE_SERVER_APP_NAME=code-server
|
||||||
+24
-3
@@ -9,13 +9,34 @@ RUN apt-get update \
|
|||||||
libffi-dev libssl-dev libyaml-dev zlib1g-dev \
|
libffi-dev libssl-dev libyaml-dev zlib1g-dev \
|
||||||
&& rm -rf /var/lib/apt/lists/*
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
# zsh as the container user's login shell.
|
# Docker CLI with the Compose and Buildx plugins, from Docker's apt repository,
|
||||||
RUN chsh -s /usr/bin/zsh coder
|
# 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.
|
# Workspace directory, owned by the container user.
|
||||||
RUN mkdir -p /workspace && chown 1000:1000 /workspace
|
RUN mkdir -p /workspace && chown 1000:1000 /workspace
|
||||||
|
|
||||||
# Startup wrapper: joins the Docker socket's group, then runs the image's entrypoint.
|
# Startup wrapper: enters DEFAULT_WORKSPACE, joins the Docker socket's group,
|
||||||
|
# then runs the image's entrypoint.
|
||||||
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
|
||||||
USER 1000
|
USER 1000
|
||||||
|
|
||||||
|
|||||||
+49
-54
@@ -5,9 +5,10 @@ official `codercom/code-server` image.
|
|||||||
|
|
||||||
The image ships code-server on Debian with `git`, `zsh`, `curl`, `sudo` and a
|
The image ships code-server on Debian with `git`, `zsh`, `curl`, `sudo` and a
|
||||||
few editors. The `Dockerfile` adds `build-essential`, `bubblewrap`, `zip`,
|
few editors. The `Dockerfile` adds `build-essential`, `bubblewrap`, `zip`,
|
||||||
`unzip` and the headers Ruby builds against, makes zsh the login shell, and
|
`unzip`, the headers Ruby builds against, the Docker CLI with its Compose and
|
||||||
wraps the entrypoint so `coder` can use the Docker socket. Language toolchains
|
Buildx plugins, and the GitHub CLI, and wraps the entrypoint so it starts in
|
||||||
and CLIs are installed into home, below.
|
`/workspace` and `coder` can use the Docker socket. Language toolchains and
|
||||||
|
other CLIs are installed into home, below.
|
||||||
|
|
||||||
## Toolchains
|
## Toolchains
|
||||||
|
|
||||||
@@ -60,29 +61,20 @@ rbenv install "$V" && rbenv global "$V"
|
|||||||
|
|
||||||
To get newer Ruby versions listed, `git -C "$(rbenv root)"/plugins/ruby-build pull`.
|
To get newer Ruby versions listed, `git -C "$(rbenv root)"/plugins/ruby-build pull`.
|
||||||
|
|
||||||
Docker Compose and Buildx, as CLI plugins in `~/.docker/cli-plugins`, the
|
Java, with SDKMAN, from its [install guide](https://sdkman.io/install/).
|
||||||
manual install from the
|
SDKMAN and every JDK it installs live in `~/.sdkman`; the installer adds itself
|
||||||
[Compose docs](https://docs.docker.com/compose/install/linux/#install-the-plugin-manually)
|
to `~/.bashrc` and `~/.zshrc`, and needs the `zip` and `unzip` the `Dockerfile`
|
||||||
and the [Buildx README](https://github.com/docker/buildx#manual-download).
|
installs. `sdk install java` with no version takes SDKMAN's default, the
|
||||||
Nothing installs them together with the client: Docker's static archive holds
|
current Temurin LTS:
|
||||||
only the client and daemon, and the packages that bundle all three are apt
|
|
||||||
packages, which land outside home. The client itself is below:
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}
|
curl -s "https://get.sdkman.io" | bash
|
||||||
mkdir -p "$DOCKER_CONFIG/cli-plugins"
|
. "$HOME/.sdkman/bin/sdkman-init.sh"
|
||||||
ARCH=$(dpkg --print-architecture)
|
sdk install java
|
||||||
|
|
||||||
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"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
To upgrade them, run the same commands again.
|
`sdk list java` shows other vendors and versions, and `sdk install gradle` or
|
||||||
|
`sdk install maven` adds a build tool the same way.
|
||||||
|
|
||||||
### Suggested by AI, may not be the optimal way
|
### Suggested by AI, may not be the optimal way
|
||||||
|
|
||||||
@@ -106,41 +98,21 @@ echo 'export PATH="$HOME/.local/go/bin:$HOME/go/bin:$PATH"' >> ~/.bashrc
|
|||||||
To upgrade Go, `rm -rf ~/.local/go` and run the same commands again, without
|
To upgrade Go, `rm -rf ~/.local/go` and run the same commands again, without
|
||||||
the `echo` line.
|
the `echo` line.
|
||||||
|
|
||||||
Docker CLI, GitHub CLI, GitLab CLI and jq, as the release binaries each
|
jq, the binary from its
|
||||||
project publishes, into `~/.local/bin`:
|
[releases page](https://github.com/jqlang/jq/releases), into `~/.local/bin`,
|
||||||
|
with no documented location:
|
||||||
- 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.
|
|
||||||
- GitLab CLI: the binary from the
|
|
||||||
[releases page](https://gitlab.com/gitlab-org/cli/-/releases), with no
|
|
||||||
documented location.
|
|
||||||
- jq: the binary from the
|
|
||||||
[releases page](https://github.com/jqlang/jq/releases), with no documented
|
|
||||||
location.
|
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mkdir -p ~/.local/bin
|
mkdir -p ~/.local/bin
|
||||||
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
|
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
|
||||||
ARCH=$(dpkg --print-architecture)
|
ARCH=$(dpkg --print-architecture)
|
||||||
|
|
||||||
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"
|
|
||||||
|
|
||||||
V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://gitlab.com/gitlab-org/cli/-/releases/permalink/latest | sed 's|.*/v||')
|
|
||||||
curl -fsSL "https://gitlab.com/gitlab-org/cli/-/releases/v$V/downloads/glab_${V}_linux_$ARCH.tar.gz" | tar -C ~/.local/bin -xzf - --strip-components=1 bin/glab
|
|
||||||
|
|
||||||
V=$(curl -fsSLI -o /dev/null -w '%{url_effective}' https://github.com/jqlang/jq/releases/latest | sed 's|.*/||')
|
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
|
curl -fsSL "https://github.com/jqlang/jq/releases/download/$V/jq-linux-$ARCH" -o ~/.local/bin/jq && chmod +x ~/.local/bin/jq
|
||||||
```
|
```
|
||||||
|
|
||||||
To upgrade one, run the `ARCH=` line and that tool's two lines again; the
|
To upgrade it, run the same commands again, without the `echo` line; the new
|
||||||
new binary overwrites the old one.
|
binary overwrites the old one.
|
||||||
|
|
||||||
## Environment
|
## Environment
|
||||||
|
|
||||||
@@ -149,6 +121,7 @@ new binary overwrites the old one.
|
|||||||
| `PASSWORD` | Web UI login. Required. |
|
| `PASSWORD` | Web UI login. Required. |
|
||||||
| `GIT_NAME` / `GIT_EMAIL` | Git author and committer identity |
|
| `GIT_NAME` / `GIT_EMAIL` | Git author and committer identity |
|
||||||
| `SERVICE_HOSTNAME` | Container hostname, and the name the shell prompt shows (also passed as `HOST`) |
|
| `SERVICE_HOSTNAME` | Container hostname, and the name the shell prompt shows (also passed as `HOST`) |
|
||||||
|
| `CODE_SERVER_APP_NAME` | Optional. Name in the title bar and welcome page; defaults to `code-server`. |
|
||||||
|
|
||||||
Generate a password with `openssl rand -base64 24`.
|
Generate a password with `openssl rand -base64 24`.
|
||||||
|
|
||||||
@@ -168,8 +141,8 @@ its `\h` uses the real hostname.
|
|||||||
|
|
||||||
## Docker access
|
## Docker access
|
||||||
|
|
||||||
The host's Docker socket is bind-mounted at `/var/run/docker.sock`. The image
|
The host's Docker socket is bind-mounted at `/var/run/docker.sock`. The
|
||||||
ships no Docker CLI; install the client into home as above. Containers
|
`Dockerfile` installs the client only; the daemon is the host's. Containers
|
||||||
started through it are siblings on the host, not children, so bind mounts in
|
started through it are siblings on the host, not children, so bind mounts in
|
||||||
them resolve against host paths.
|
them resolve against host paths.
|
||||||
|
|
||||||
@@ -207,8 +180,12 @@ Listens on `8080`; point the domain at it.
|
|||||||
| `code-server-home` | `/home/coder` | Home directory: settings, extensions, shell history, CLI logins |
|
| `code-server-home` | `/home/coder` | Home directory: settings, extensions, shell history, CLI logins |
|
||||||
| `code-server-workspace` | `/workspace` | Code you work on |
|
| `code-server-workspace` | `/workspace` | Code you work on |
|
||||||
|
|
||||||
The image's entrypoint opens `.`, its working directory. `working_dir:
|
The image's entrypoint opens `.`, its working directory. `entrypoint.sh`
|
||||||
/workspace` makes that the folder code-server opens.
|
changes into `DEFAULT_WORKSPACE`, set to `/workspace` in `compose.yml`, before
|
||||||
|
starting it, so that is the folder code-server opens and where new terminals
|
||||||
|
start. Changing the variable moves both without editing the compose file's
|
||||||
|
structure. `docker exec` shells are not affected and start in the image's
|
||||||
|
`/home/coder`.
|
||||||
|
|
||||||
The `Dockerfile` also makes `/workspace` writable. The image does not
|
The `Dockerfile` also makes `/workspace` writable. The image does not
|
||||||
ship that directory, so a named volume mounted there comes up `root:root`,
|
ship that directory, so a named volume mounted there comes up `root:root`,
|
||||||
@@ -227,9 +204,27 @@ rbenv. `libffi-dev`, `libssl-dev`, `libyaml-dev` and `zlib1g-dev` are the
|
|||||||
headers a rbenv-built Ruby needs for its `fiddle`, `openssl`, `psych` and
|
headers a rbenv-built Ruby needs for its `fiddle`, `openssl`, `psych` and
|
||||||
`zlib` extensions; without them `rbenv install` fails or leaves those out.
|
`zlib` extensions; without them `rbenv install` fails or leaves those out.
|
||||||
|
|
||||||
The image leaves `coder` with `/bin/bash` as its login shell. The editor's
|
The Docker CLI, its Compose and Buildx plugins, and the GitHub CLI come from
|
||||||
terminal opens zsh regardless, but tools that read the login shell from
|
Docker's and GitHub's signed apt repositories, which is each vendor's documented
|
||||||
`/etc/passwd` or `$SHELL` get bash, so the `Dockerfile` sets it to zsh.
|
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.
|
||||||
|
|
||||||
|
## Shell
|
||||||
|
|
||||||
|
`SHELL=/bin/zsh` in `compose.yml` picks the shell. The editor's terminal takes
|
||||||
|
its default from `$SHELL` first and only falls back to the login shell in
|
||||||
|
`/etc/passwd`, so the variable is enough, and switching to another shell the
|
||||||
|
image ships means changing one line rather than rebuilding. `sudo -E` in
|
||||||
|
`entrypoint.sh` keeps the variable; without it sudo would replace it with
|
||||||
|
root's `/bin/bash`. The value is written literally, not read from `.env`,
|
||||||
|
because every deploying shell exports its own `SHELL`, which interpolation
|
||||||
|
would pick up first.
|
||||||
|
|
||||||
## Image
|
## Image
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,17 @@ services:
|
|||||||
build: .
|
build: .
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
hostname: ${SERVICE_HOSTNAME}
|
hostname: ${SERVICE_HOSTNAME}
|
||||||
working_dir: /workspace
|
|
||||||
environment:
|
environment:
|
||||||
- PASSWORD=${PASSWORD:?required}
|
- PASSWORD=${PASSWORD:?required}
|
||||||
- TZ=Asia/Ho_Chi_Minh
|
- TZ=Asia/Ho_Chi_Minh
|
||||||
|
- DEFAULT_WORKSPACE=/workspace
|
||||||
|
- SHELL=/bin/zsh
|
||||||
- GIT_AUTHOR_NAME=${GIT_NAME}
|
- GIT_AUTHOR_NAME=${GIT_NAME}
|
||||||
- GIT_AUTHOR_EMAIL=${GIT_EMAIL}
|
- GIT_AUTHOR_EMAIL=${GIT_EMAIL}
|
||||||
- GIT_COMMITTER_NAME=${GIT_NAME}
|
- GIT_COMMITTER_NAME=${GIT_NAME}
|
||||||
- GIT_COMMITTER_EMAIL=${GIT_EMAIL}
|
- GIT_COMMITTER_EMAIL=${GIT_EMAIL}
|
||||||
- HOST=${SERVICE_HOSTNAME}
|
- HOST=${SERVICE_HOSTNAME}
|
||||||
|
# - CODE_SERVER_APP_NAME=${CODE_SERVER_APP_NAME:-code-server}
|
||||||
volumes:
|
volumes:
|
||||||
- 'code-server-home:/home/coder'
|
- 'code-server-home:/home/coder'
|
||||||
- 'code-server-workspace:/workspace'
|
- 'code-server-workspace:/workspace'
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -eu
|
set -eu
|
||||||
|
|
||||||
|
# Start in DEFAULT_WORKSPACE, the folder code-server opens.
|
||||||
|
if [ -n "${DEFAULT_WORKSPACE:-}" ]; then
|
||||||
|
cd "$DEFAULT_WORKSPACE"
|
||||||
|
fi
|
||||||
|
|
||||||
# Add coder to the group that owns the mounted Docker socket, then restart
|
# Add coder to the group that owns the mounted Docker socket, then restart
|
||||||
# under that group.
|
# under that group.
|
||||||
if [ -S /var/run/docker.sock ]; then
|
if [ -S /var/run/docker.sock ]; then
|
||||||
|
|||||||
Reference in new issue
Block a user