I have installed zsh and oh-my-zsh in my Docker image that I use for Lando, but I can't seem to change the default shell upon entering it with lando ssh
.
Oh-my-zsh is being installed with the CHSH=yes
parameter but it seems it has no effect.
I tried:
.profile
file with the contents:export SHELL=`which zsh`
[ -z "$ZSH_VERSION" ] && exec "$SHELL" -l
.bash_profile
with the contents:export SHELL=/bin/zsh
exec /bin/zsh -l
... as suggested in this answer.
But I am always logged in into /bin/bash
.
However, when I type zsh
, I enter zshell with my .zshrc
being successfully applied.
How can I fix this?
Here's the full Docker image build script. It does not contain the above mentioned attempts. I tried those in the container itself, restarting it and again ssh-ing into it. The image is public and available here: slimdeluxe/php:8.3-v1.1
FROM devwithlando/php:8.3-fpm-4
# Upgrade system
RUN apt-get update && apt-get -y upgrade
# Install system tools
RUN apt-get install -y tree nano
# Install locales
RUN apt-get install -y locales locales-all
# Add PHP extension helper
ADD https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/
# Install PHP extensions
RUN chmod +x /usr/local/bin/install-php-extensions && sync && \
install-php-extensions sqlsrv pdo_sqlsrv
# Install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs
# Instal/update NPM
RUN npm install npm --global
# Install build dependencies for screen
RUN apt-get install -y build-essential libncurses5-dev automake texinfo wget \
git libtool pkg-config m4 perl
# Install newer Autoconf version
RUN wget https://ftp.gnu.org/gnu/autoconf/autoconf-2.71.tar.gz && \
tar -xzf autoconf-2.71.tar.gz && \
cd autoconf-2.71 && \
./configure && \
make && \
make install && \
cd .. && \
rm -rf autoconf-2.71 autoconf-2.71.tar.gz
# Download, compile and install screen 5.0.0
RUN wget https://ftp.gnu.org/gnu/screen/screen-5.0.0.tar.gz && \
tar -xzf screen-5.0.0.tar.gz && \
cd screen-5.0.0 && \
./autogen.sh && \
./configure && \
make && \
make install && \
cd .. && \
rm -rf screen-5.0.0 screen-5.0.0.tar.gz
# Install zsh and ohmyzsh
RUN apt-get install -y zsh
USER www-data
RUN cd /var/www && \
wget https://install.ohmyz.sh -O install.sh && \
CHSH=yes RUNZSH=no KEEP_ZSHRC=no sh install.sh && \
rm install.sh
# Create default .zshrc in home directory
RUN echo 'export ZSH="$HOME/.oh-my-zsh"\n\
ZSH_THEME="crunch"\n\
plugins=(git laravel)\n\
source $ZSH/oh-my-zsh.sh\n' > ~/.zshrc
USER root
The problem is that lando ssh
ignores those profile files you created.
When you SSH into a Docker container, it looks at the shell specified in /etc/passwd
for that user, not your dotfiles. Your .profile
or .bash_profile
tricks won't work because the SSH session is already started with bash before those files get sourced.
Solution that worked for me before:
# You should change the shell in /etc/passwd for www-data
RUN chsh -s /bin/zsh www-data
Add this to your Dockerfile right after installing zsh but before you switch to the www-data user. This actually modifies the user's shell at the system level.
If you can't rebuild the image for some reason, you can also tell Lando specifically to use zsh by adding this to your .lando.yml:
services:
appserver:
shell: /bin/zsh
That way when Lando SSHs in, it explicitly uses zsh regardless of what's in /etc/passwd.
Alternatively, you could just create a bash alias in your host machine:
alias lzsh='lando ssh -c "exec /bin/zsh"'
Then use lzsh
instead of lando ssh
when you want zsh.
Hope that helps!