Visual Studio Code Remote - Containers - change shell

When launching an attached container in "VS Code Remote Development", has anyone found a way to change the container's shell when launching the vscode integrated terminal.

It seems to run something similar to.

docker exec -it <containername> /bin/bash

I am looking for the equivalent of

docker exec -it <containername> /bin/zsh

The only settings I found for Attached containers are

"remote.containers.defaultExtensions": []

I worked around it with

RUN echo "if [ -t 1 ]; then" >> /root/.bashrc
RUN echo "exec zsh" >> /root/.bashrc
RUN echo "fi" >> /root/.bashrc

Still would be interested in knowing if there was a way to set this per container.


I use a Docker container for my development environment and set the shell to bash in my Dockerfile:

# …
ENTRYPOINT ["bash"]

Yet when VS Code was connecting to my container it was insisting on using the /bin/ash shell which was driving me crazy... However the fix (at least for me) was very simple but not obvious:

enter image description here

From the .devcontainer.json reference.

All I needed to do in my case was to add the following entry in my .devcontainer.json file:

{
  …
  "settings": {
    "terminal.integrated.shell.*": "/bin/bash"
  }
  …
}

Complete .devcontainer.json file (FYI)

{
  "name": "project-blueprint",
  "dockerComposeFile": "./docker-compose.yml",
  "service": "dev",
  "workspaceFolder": "/workspace/dev",
  "postCreateCommand": "yarn",
  "settings": {
    "terminal.integrated.shell.*": "/bin/bash"
  }
}

I'd like to contribute to this thread since I spent a decent amount of time combing the web for a good solution to this involving VS Code's new API for terminal.integrated.profiles.linux

Note as of 20 Jan 2022 both the commented and the uncommented json work. The uncommented out lines is the new non deprecated way to get this working with Dev containers.

{
"settings": { 
        // "terminal.integrated.shell.linux": "/bin/zsh"
        "terminal.integrated.defaultProfile.linux": "zsh", 
        "terminal.integrated.profiles.linux": {
            "zsh": {
                "path": "/bin/zsh"
            },
        }
    }
}

if any one is interested I also figured out how to get oh my ZSH built into the image.

Dockerfile:

# Setup Stage - set up the ZSH environment for optimal developer experience
FROM node:16-alpine AS setup

RUN npm install -g expo-cli
# Let scripts know we're running in Docker (useful for containerized development)
ENV RUNNING_IN_DOCKER true
# Use the unprivileged `node` user (pre-created by the Node image) for safety (and because it has permission to install modules)
RUN mkdir -p /app \
    && chown -R node:node /app
# Set up ZSH and our preferred terminal environment for containers
RUN apk --no-cache add zsh curl git
# Set up ZSH as the unprivileged user (we just need to start it, it'll initialize our setup itself)
USER node
# set up oh my zsh
RUN cd ~ && wget https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh && sh install.sh
# initialize ZSH
RUN /bin/zsh ~/.zshrc

# Switch back to root
USER root