Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions .devcontainer/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ Changes you can make are notably:

- Changes to the Docker image in [Dockerfile](Dockerfile)
- Changes to VSCode **settings** and **extensions** in [devcontainer.json](devcontainer.json).
- Change the entrypoint script by adding a bind mount in [devcontainer.json](devcontainer.json) of a shell script to `/root/.welcome.sh` to replace the [current welcome script](https://github.com/qdm12/basedevcontainer/blob/master/shell/.welcome.sh). For example:
- Change the entrypoint script by adding a bind mount in [devcontainer.json](devcontainer.json) of a shell script to `/home/user/.welcome.sh` to replace the [current welcome script](https://github.com/qdm12/basedevcontainer/blob/master/shell/.welcome.sh). For example:

```json
// Welcome script
{
"source": "/yourpath/.welcome.sh",
"target": "/root/.welcome.sh",
"target": "/home/user/.welcome.sh",
"type": "bind"
},
```
Expand Down
4 changes: 2 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@
// Zsh commands history persistence
{
"source": "${localEnv:HOME}/.zsh_history",
"target": "/root/.zsh_history",
"target": "/home/user/.zsh_history",
"type": "bind"
},
// Git configuration file
{
"source": "${localEnv:HOME}/.gitconfig",
"target": "/root/.gitconfig",
"target": "/home/user/.gitconfig",
"type": "bind"
},
// SSH directory for Linux, OSX and WSL
Expand Down
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Base Alpine development container for Visual Studio Code, used as base image by
- Contains the packages:
- `libstdc++`: needed by the VS code server
- `zsh`: main shell instead of `/bin/sh`
- `sudo`: run commands as root if needed
- `git`: interact with Git repositories
- `openssh-client`: use SSH keys
- `nano`: edit files from the terminal
Expand All @@ -59,6 +60,7 @@ Base Alpine development container for Visual Studio Code, used as base image by
- Docker uses buildkit by default, with the latest Docker client binary.
- Extensible with docker-compose.yml
- Supports SSH keys with Linux, OSX and Windows
- Runs without root as `user` (uid 1000 and gid 1000) user but you can run Docker without sudo and can use sudo if needed

## Requirements

Expand Down Expand Up @@ -130,18 +132,20 @@ You can build and extend the Docker development image to suit your needs.
RUN echo "alias ls='ls -al'" >> ~/.zshrc
```

- Add some Alpine packages:
- Add some Alpine packages, you will need to switch to `root`:

```Dockerfile
FROM qmcgaw/basedevcontainer
USER root
RUN apk add bind-tools
USER user
```

1. Modify `.devcontainer/docker-compose.yml` and add `build: .` in the vscode service.
1. Open the command palette in Visual Studio Code (CTRL+SHIFT+P)
1. Select `Dev-Containers: Rebuild Container`

- You can bind mount a file at `/root/.welcome.sh` to modify the welcome message.
- You can bind mount a file at `/home/user/.welcome.sh` to modify the welcome message (use `/root/.welcome.sh` for `root`)

## TODO

Expand Down
79 changes: 58 additions & 21 deletions alpine.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ LABEL \
org.opencontainers.image.title="Base Dev container" \
org.opencontainers.image.description="Base Alpine development container for Visual Studio Code Dev Containers development"
ENV BASE_VERSION="${VERSION}-${CREATED}-${COMMIT}"
ARG USER_UID=1000
ARG USER_GID=1000

# CA certificates
RUN apk add -q --update --progress --no-cache ca-certificates
Expand All @@ -39,57 +41,92 @@ RUN apk add -q --update --progress --no-cache ca-certificates
RUN apk add -q --update --progress --no-cache tzdata
ENV TZ=

# Setup non root user with sudo access
RUN apk add -q --update --progress --no-cache sudo
WORKDIR /home/user
RUN adduser user -s /bin/sh -D -u $USER_UID $USER_GID && \
mkdir -p /etc/sudoers.d && \
echo user ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/user && \
chmod 0440 /etc/sudoers.d/user

# Setup Git and SSH
RUN apk add -q --update --progress --no-cache git mandoc git-doc openssh-client
COPY .ssh.sh /root/
RUN chmod +x /root/.ssh.sh
# Retro-compatibility symlink
RUN ln -s /root/.ssh.sh /root/.windows.sh
COPY --chown=0:0 .ssh.sh /root/
RUN chmod +x /root/.ssh.sh && \
cp /root/.ssh.sh /home/user/.ssh.sh && \
chown ${USER_UID}:${USER_GID} /home/user/.ssh.sh && \
# Retro-compatibility symlinks
ln -s /root/.ssh.sh /root/.windows.sh && \
ln -s /home/user/.ssh.sh /home/user/.windows.sh

WORKDIR /root

# Setup shell for root and ${USERNAME}
# Setup shell for root and user
ENTRYPOINT [ "/bin/zsh" ]
RUN apk add -q --update --progress --no-cache zsh nano zsh-vcs
ENV EDITOR=nano \
LANG=en_US.UTF-8 \
# MacOS compatibility
TERM=xterm
RUN apk add -q --update --progress --no-cache shadow && \
usermod --shell /bin/zsh user && \
usermod --shell /bin/zsh root && \
apk del shadow

COPY shell/.zshrc shell/.welcome.sh /root/
RUN git clone --single-branch --depth 1 https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh

COPY shell/.p10k.zsh /root/
RUN apk add -q --update --progress --no-cache zsh-theme-powerlevel10k gitstatus && \
ln -s /usr/share/zsh/plugins/powerlevel10k ~/.oh-my-zsh/custom/themes/powerlevel10k
COPY --chown=${USER_UID}:${USER_GID} shell/.zshrc shell/.welcome.sh /home/user/
RUN cp /home/user/.zshrc /root/.zshrc && \
cp /home/user/.welcome.sh /root/.welcome.sh && \
chown 0:0 /root/.zshrc /root/.welcome.sh && \
sed -i "s/HOMEPATH/home\/user/" /home/user/.zshrc && \
sed -i "s/HOMEPATH/root/" /root/.zshrc
RUN git clone --single-branch --depth 1 https://github.com/robbyrussell/oh-my-zsh.git /home/user/.oh-my-zsh && \
chown ${USER_UID}:${USER_GID} -R /home/user/.oh-my-zsh && \
cp -r /home/user/.oh-my-zsh /root/.oh-my-zsh && \
chown 0:0 -R /root/.oh-my-zsh

COPY shell/.p10k.zsh /home/user/
RUN ln -s /home/user/.p10k.zsh /root/.p10k.zsh && \
apk add -q --update --progress --no-cache zsh-theme-powerlevel10k gitstatus && \
ln -s /usr/share/zsh/plugins/powerlevel10k /root/.oh-my-zsh/custom/themes/powerlevel10k && \
ln -s /usr/share/zsh/plugins/powerlevel10k /home/user/.oh-my-zsh/custom/themes/powerlevel10k

# Docker CLI
COPY --from=docker /bin /usr/local/bin/docker
COPY --from=docker --chown=${USER_UID}:${USER_GID} /bin /usr/local/bin/docker
ENV DOCKER_BUILDKIT=1
# All possible docker host groups
RUN G102=`getent group 102 | cut -d":" -f 1` && \
G976=`getent group 976 | cut -d":" -f 1` && \
G1000=`getent group 1000 | cut -d":" -f 1` && \
if [ -z $G102 ]; then G102=docker102; addgroup --gid 102 $G102; fi && \
if [ -z $G976 ]; then G976=docker976; addgroup --gid 976 $G976; fi && \
if [ -z $G1000 ]; then G1000=docker1000; addgroup --gid 1000 $G1000; fi && \
addgroup user $G102 && \
addgroup user $G976 && \
addgroup user $G1000

# Docker compose
COPY --from=compose /bin /usr/libexec/docker/cli-plugins/docker-compose
COPY --from=compose --chown=${USER_UID}:${USER_GID} /bin /usr/libexec/docker/cli-plugins/docker-compose
ENV COMPOSE_DOCKER_CLI_BUILD=1
RUN echo "alias docker-compose='docker compose'" >> /root/.zshrc
RUN echo "alias docker-compose='docker compose'" >> /home/user/.zshrc && \
echo "alias docker-compose='docker compose'" >> /root/.zshrc

# Buildx plugin
COPY --from=buildx /bin /usr/libexec/docker/cli-plugins/docker-buildx
COPY --from=buildx --chown=${USER_UID}:${USER_GID} /bin /usr/libexec/docker/cli-plugins/docker-buildx

# Logo ls
COPY --from=logo-ls /bin /usr/local/bin/logo-ls
RUN echo "alias ls='logo-ls'" >> /root/.zshrc
COPY --from=logo-ls --chown=${USER_UID}:${USER_GID} /bin /usr/local/bin/logo-ls
RUN echo "alias ls='logo-ls'" >> /home/user/.zshrc && \
echo "alias ls='logo-ls'" >> /root/.zshrc

# Bit
COPY --from=bit /bin /usr/local/bin/bit
COPY --from=bit --chown=${USER_UID}:${USER_GID} /bin /usr/local/bin/bit
ARG TARGETPLATFORM
RUN if [ "${TARGETPLATFORM}" != "linux/s390x" ]; then echo "y" | bit complete; fi

COPY --from=gh /bin /usr/local/bin/gh
COPY --from=gh --chown=${USER_UID}:${USER_GID} /bin /usr/local/bin/gh

COPY --from=devtainr /devtainr /usr/local/bin/devtainr
COPY --from=devtainr --chown=${USER_UID}:${USER_GID} /devtainr /usr/local/bin/devtainr

# VSCode specific (speed up setup)
RUN apk add -q --update --progress --no-cache libstdc++

USER user
85 changes: 64 additions & 21 deletions debian.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ LABEL \
org.opencontainers.image.title="Base Dev container Debian" \
org.opencontainers.image.description="Base Debian development container for Visual Studio Code Dev Containers development"
ENV BASE_VERSION="${VERSION}-${CREATED}-${COMMIT}"
ARG USER_UID=1000
ARG USER_GID=1000

# CA certificates
RUN apt-get update -y && \
Expand All @@ -43,6 +45,18 @@ RUN apt-get update -y && \
rm -r /var/cache/* /var/lib/apt/lists/*
ENV TZ=

# Setup non root user with sudo access
RUN apt-get update -y && \
apt-get install -y --no-install-recommends sudo && \
rm -r /var/cache/* /var/lib/apt/lists/*
WORKDIR /home/user
RUN addgroup --gid $USER_GID user && \
useradd user --shell /bin/sh --create-home --uid $USER_UID --gid $USER_GID && \
mkdir -p /etc/sudoers.d && \
echo user ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/user && \
chmod 0440 /etc/sudoers.d/user && \
rm /var/log/faillog /var/log/lastlog

# Setup Git and SSH
# Workaround for older Debian in order to be able to sign commits
RUN echo "deb https://deb.debian.org/debian bookworm main" >> /etc/apt/sources.list && \
Expand All @@ -52,12 +66,15 @@ RUN echo "deb https://deb.debian.org/debian bookworm main" >> /etc/apt/sources.l
RUN apt-get update -y && \
apt-get install -y --no-install-recommends man openssh-client less && \
rm -r /var/cache/* /var/lib/apt/lists/*
COPY .ssh.sh /root/
RUN chmod +x /root/.ssh.sh
# Retro-compatibility symlink
RUN ln -s /root/.ssh.sh /root/.windows.sh

# Setup shell
COPY --chown=0:0 .ssh.sh /root/
RUN chmod +x /root/.ssh.sh && \
cp /root/.ssh.sh /home/user/.ssh.sh && \
chown ${USER_UID}:${USER_GID} /home/user/.ssh.sh && \
# Retro-compatibility symlinks
ln -s /root/.ssh.sh /root/.windows.sh && \
ln -s /home/user/.ssh.sh /home/user/.windows.sh

# Setup shell for root and user
ENTRYPOINT [ "/bin/zsh" ]
RUN apt-get update -y && \
apt-get install -y --no-install-recommends zsh nano locales wget && \
Expand All @@ -72,37 +89,63 @@ RUN echo "LC_ALL=en_US.UTF-8" >> /etc/environment && \
echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen && \
echo "LANG=en_US.UTF-8" > /etc/locale.conf && \
locale-gen en_US.UTF-8
RUN usermod --shell /bin/zsh root

COPY shell/.zshrc shell/.welcome.sh /root/
RUN git clone --single-branch --depth 1 https://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh
RUN usermod --shell /bin/zsh user && \
usermod --shell /bin/zsh root

COPY --chown=${USER_UID}:${USER_GID} shell/.zshrc shell/.welcome.sh /home/user/
RUN cp /home/user/.zshrc /root/.zshrc && \
cp /home/user/.welcome.sh /root/.welcome.sh && \
chown 0:0 /root/.zshrc /root/.welcome.sh && \
sed -i "s/HOMEPATH/home\/user/" /home/user/.zshrc && \
sed -i "s/HOMEPATH/root/" /root/.zshrc
RUN git clone --single-branch --depth 1 https://github.com/robbyrussell/oh-my-zsh.git /home/user/.oh-my-zsh && \
chown ${USER_UID}:${USER_GID} -R /home/user/.oh-my-zsh && \
cp -r /home/user/.oh-my-zsh /root/.oh-my-zsh && \
chown 0:0 -R /root/.oh-my-zsh

ARG POWERLEVEL10K_VERSION=v1.16.1
COPY shell/.p10k.zsh /root/
RUN git clone --branch ${POWERLEVEL10K_VERSION} --single-branch --depth 1 https://github.com/romkatv/powerlevel10k.git ~/.oh-my-zsh/custom/themes/powerlevel10k && \
rm -rf ~/.oh-my-zsh/custom/themes/powerlevel10k/.git
COPY shell/.p10k.zsh /home/user/
RUN ln -s /home/user/.p10k.zsh /root/.p10k.zsh && \
git clone --branch ${POWERLEVEL10K_VERSION} --single-branch --depth 1 https://github.com/romkatv/powerlevel10k.git /home/user/.oh-my-zsh/custom/themes/powerlevel10k && \
rm -rf /home/user/.oh-my-zsh/custom/themes/powerlevel10k/.git && \
chown -R ${USER_UID}:${USER_GID} /home/user/.oh-my-zsh/custom/themes/powerlevel10k && \
ln -s /home/user/.oh-my-zsh/custom/themes/powerlevel10k /root/.oh-my-zsh/custom/themes/powerlevel10k

# Docker CLI
COPY --from=docker /bin /usr/local/bin/docker
ENV DOCKER_BUILDKIT=1
# All possible docker host groups
RUN G102=`getent group 102 | cut -d":" -f 1` && \
G976=`getent group 976 | cut -d":" -f 1` && \
G1000=`getent group 1000 | cut -d":" -f 1` && \
if [ -z $G102 ]; then G102=docker102; addgroup --gid 102 $G102; fi && \
if [ -z $G976 ]; then G976=docker976; addgroup --gid 976 $G976; fi && \
if [ -z $G1000 ]; then G1000=docker1000; addgroup --gid 1000 $G1000; fi && \
usermod -a -G $G102 user && \
usermod -a -G $G976 user && \
usermod -a -G $G1000 user

# Docker compose
COPY --from=compose /bin /usr/libexec/docker/cli-plugins/docker-compose
COPY --from=compose --chown=${USER_UID}:${USER_GID} /bin /usr/libexec/docker/cli-plugins/docker-compose
ENV COMPOSE_DOCKER_CLI_BUILD=1
RUN echo "alias docker-compose='docker compose'" >> /root/.zshrc
RUN echo "alias docker-compose='docker compose'" >> /home/user/.zshrc && \
echo "alias docker-compose='docker compose'" >> /root/.zshrc

# Buildx plugin
COPY --from=buildx /bin /usr/libexec/docker/cli-plugins/docker-buildx
COPY --from=buildx --chown=${USER_UID}:${USER_GID} /bin /usr/libexec/docker/cli-plugins/docker-buildx

# Logo ls
COPY --from=logo-ls /bin /usr/local/bin/logo-ls
RUN echo "alias ls='logo-ls'" >> /root/.zshrc
COPY --from=logo-ls --chown=${USER_UID}:${USER_GID} /bin /usr/local/bin/logo-ls
RUN echo "alias ls='logo-ls'" >> /home/user/.zshrc && \
echo "alias ls='logo-ls'" >> /root/.zshrc

# Bit
COPY --from=bit /bin /usr/local/bin/bit
COPY --from=bit --chown=${USER_UID}:${USER_GID} /bin /usr/local/bin/bit
ARG TARGETPLATFORM
RUN if [ "${TARGETPLATFORM}" != "linux/s390x" ]; then echo "y" | bit complete; fi

COPY --from=gh /bin /usr/local/bin/gh
COPY --from=gh --chown=${USER_UID}:${USER_GID} /bin /usr/local/bin/gh

COPY --from=devtainr --chown=${USER_UID}:${USER_GID} /devtainr /usr/local/bin/devtainr

COPY --from=devtainr /devtainr /usr/local/bin/devtainr
USER user
14 changes: 13 additions & 1 deletion shell/.zshrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ZSH=/root/.oh-my-zsh
ZSH=/HOMEPATH/.oh-my-zsh
ZSH_CUSTOM=$ZSH/custom
POWERLEVEL9K_DISABLE_CONFIGURATION_WIZARD=true
ZSH_THEME="powerlevel10k/powerlevel10k"
Expand All @@ -21,8 +21,20 @@ test -S /var/run/docker.sock
[ "$?" = 0 ] && DOCKERSOCK_OK=yes
[ -z $DOCKERSOCK_OK ] && >&2 echo "[WARNING] Docker socket not found, docker will not be available"

# Fixing permission on Docker socket
if [ ! -z $DOCKERSOCK_OK ]; then
DOCKERSOCK_USER=`stat -c "%u" /var/run/docker.sock`
DOCKERSOCK_GROUP=`stat -c "%g" /var/run/docker.sock`
if [ "$DOCKERSOCK_GROUP" != "1000" ] && [ "$DOCKERSOCK_GROUP" != "102" ] && [ "$DOCKERSOCK_GROUP" != "976" ]; then
echo "Docker socket not owned by group IDs 1000, 102 or 976, changing its group to `id -g`"
sudo chown $DOCKERSOCK_USER:`id -g` /var/run/docker.sock
sudo chmod 770 /var/run/docker.sock
fi
fi

echo
echo "Base version: $BASE_VERSION"
echo "Running as `whoami`"
where code &> /dev/null && echo "VS code server `code -v | head -n 1`"
if [ ! -z $DOCKERSOCK_OK ]; then
echo "Docker server `docker version --format {{.Server.Version}}` | client `docker version --format {{.Client.Version}}`"
Expand Down