I love ZSH. I love my colorful terminal prompts, I love my indicators, I love my icons. That's all very well on my computer, but what about inside Docker containers?
Well, turns out it's actually really easy to set up ZSH in Docker, it just requires a bit of doing. This post will explain how to do just that! I'll use a non-root user because that's safer, but if you want to use root
to do everything, just ignore the user switching and permissions changing, it should all work fine.
I've set this up as a multi-stage build layer, but you can get rid of the AS setup
in the first line if you want to do something else.
TL;DR: Here's the Gist! (If you're using NodeJS, there's a special one for you here!)
Let's break that down. We start off by using the Alpine Linux image, but this should work for any Linux image, you might just need to modify apk add
to be apt install
or something else. If you're using NodeJS in Docker, use node:14-alpine
instead.
FROM alpine:latest AS setup
Then we set the environment variable RUNNING_IN_DOCKER
to true. I do this with all my Dockerfiles just because it's sometimes really useful to be able to tell easily if a script is running in Docker or on the host (e.g. testing automatically before a commit made in the container vs through VS Code on the host).
ENV RUNNING_IN_DOCKER true
Next, we create a new unprivileged user called main
for security (using -D
to not give a password). Then we just create a a folder to put our app in, and give ownership of it to that user.
RUN adduser -D main
RUN mkdir -p /app \
&& chown -R main:main /app
if you're using NodeJS, don't bother creating a new user, you already have the node
user created for you by the NodeJS base image. That user also already has the setup to install packages without any extra config. Just get rid of the first line and change main:main
to node:node
.
After that, we install the dependencies for ZSH and then download Antigen (used for managing ZSH plugins) from GitHub.
RUN apk --no-cache add zsh curl git
RUN mkdir -p /home/main/.antigen
RUN curl -L git.io/antigen > /home/main/.antigen/antigen.zsh
With Antigen installed, we copy over our ZSH configuration, which I like to store in .dockershell.sh
, but it will be copied to .zshrc
in the container. I have an example configuration in this Gist if you need inspiration!
COPY .dockershell.sh /home/main/.zshrc
Then we just give the main
user ownership of both the Antigen config and .zshrc
.
RUN chown -R main:main /home/main/.antigen /home/main/.zshrc
Now, we can actually run ZSH, which will automatically pull everything we need to fulfill our configuration! This may take some time depending on how complex your config is, but after you've done it once, it's the same for every other container that ever uses it! Also note that you will have to rebuild whenever you change your ZSH config of course. Anyway, we run ZSH as the main
user so it sets it up with the right permissions (that's the user we'll interact with the container with). After that, we switch back to root
for any remaining stages.
USER main
RUN /bin/zsh /home/main/.zshrc
USER root
And that'll give you ZSH in Docker! Just remember to add this when you want a prompt:
ENTRYPOINT [ "/bin/zsh" ]
Here are three Gists that might help in getting everything operational:
Thanks for reading! Happy ZSHing! ๐
Top comments (0)