loading...

How to fix the nasty ‘bash: ./wait-for-it.sh: Is a directory’ on Windows

engberrg profile image Niklas Engberg Originally published at hackernoon.com on ・3 min read

How to fix the nasty ‘bash: ./wait-for-it.sh: Is a directory’ on Windows 💪

Nowadays when building applications they’re usually built using a distributed microservice architecture that consists of many services. Many of those services have dependencies on other services, usually infrastructure that needs to be booted before. To manage multiple services in an controlled an easy way Docker and Docker Compose can help you.

Docker Compose is a tool for defining and running multi-container Docker applications. What is limited though is to know when a container is ready to start accepting traffic. You can control startup order of containers by using depends_on. So for instance:

services:
   service1:
     ...omitted
     depends\_on:
     - "rabbitmq"

   rabbitmq:
     ...omitted

This will only verify that the container is running before service1 boots. To ensure that you do not start your container before the dependency is ready to accept traffic wait-for-it is a good script to use.

services:
  service1:
    ...omitted
    volumes:
      - "./scripts/wait-for-it.sh:/app/wait-for-it.sh"
    entrypoint: ["bash", "-c", "./wait-for-it.sh rabbitmq:15672 -t 0; ./start.sh"]

  rabbitmq:
     ...omitted

This will make sure that the rabbitmq service is available on port 15672 before the next script is executed (in this case a simple start.sh-file). This approach usually works very well but you can run into trouble when you are mainly developing on Windows:

bash: ./wait-for-it.sh: Is a directory

In this post I will share how I have solved this issue. I’ve spent maaany hours troubleshooting so hopefully I can save you some time.

Wrong line endings

Your wait-for-it.sh file is using windows line endings (CRLF). Files created on Windows have different line endings than files created on Unix. If you are running Linux containers you need to make sure your script file uses LF and not CRLF. You can easily find out by opening the file in some modern text editor like Notepad++ or VSCode.

Line endings in repository

You probably version your software and when you are using git there is a setting that you can configure to handle line endings. If you are collaborating across platforms you usually have the setting configured to auto. That means that any time you add a file to the git repo that git thinks is a text file, it will turn all CRLF line endings to just LF before it stores it in the commit. Whenever you dogit checkout, all text files automatically will have their LF line endings converted to CRLF endings.

Make sure you have a present .gitattributes file in your repo that has this setting:

*.sh text eol=lf

This will tell git to apply LF line endings to all .sh files when checking out.

Shared drive

Make sure you share your driver(s). In the example above I am using a host volume mount to share files from my host into the container. To be able to do this you need to share your drive. You can do this in the Docker Settings by right clicking the icon in the tray.

https://token2shell.com/img/howto/token2shell/docker/docker-settings-shared-drives.png

In our environment (I assume that this might be the case for you) we are using specific local admin accounts for elevated permissions. To be able to share your drive you need authenticate using this account. When the password for this local account expires, Docker won’t tell you or prompt you again to enter your password — unless you untick the box, hit apply, tick the box and hit apply again. Frustrating!

Hopefully when you have fixed the line endings and shared your driver(s) your issue will go away and you’ll see something like this:

service1 | wait-for-it.sh: waiting for rabbitmq:15672 without a timeout

These are two things that might bite you. Hopefully I have saved you some time troubleshooting! 😆


Discussion

markdown guide