1

I am getting this message nc command is missing and by doing some R&D, I got to know that in order to resolve this, (I think) I need to run below command in MySQL container in docker-compose

RUN apt-get -q update && apt-get -qy install netcat

But the issue is I don't have it's docker file else I could have written this command in docker file and might have called docker file from docker-compose

Does anyone have any idea how can I run this command from docker-compose?

Edit 1: I have made separate the DockerFile for mysql which consists of

FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .

and then called this docker file from docker-compose which goes like this...

version: "3"
services:
    mysql-standalone:
        image: mysql:8.0.25
        environment:
            - MYSQL_ROOT_PASSWORD=********
            - MYSQL_DATABASE=usermanagementappdp
        ports:
            - 3306:3306
        depends_on: ['eureka-server']
        build:
            context: "./mysqlDockerFile2"
            dockerfile: "Dockerfile"
        volumes:
            - ./wait-for:/docker-entrypoint-initdb.d
        entrypoint: ["/docker-entrypoint-initdb.d/wait-for.sh", "eureka-server:8761", "--", "docker-entrypoint.sh"]

    phpmyadmin:
        image: phpmyadmin/phpmyadmin:latest
        restart: always
        environment:
            PMA_HOST: mysql-standalone
            PMA_USER: root
            PMA_PASSWORD: root123M.
        ports:
            - 8085:80

    eureka-server:
        image: eureka-server
        ports:
            - 8761:8761
        build:
            context: "../Eureka-Server-For-User-Management-App"
            dockerfile: "Dockerfile"


    usermanagementapp-docker:
        image: usermanagementapp-docker:latest
        ports:
            - 8089:8089
        links:
            - eureka-server
        environment:
            EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka
            SPRING_DATASOURCE_URL: jdbc:mysql://mysql-standalone:3306/usermanagementappdp?allowPublicKeyRetrieval=true&autoReconnect=true&useSSL=false
        build:
            context: "./"
            dockerfile: "Dockerfile"
        restart: on-failure
        entrypoint: ["/wait-for.sh", "mysql-standalone:3306", "--", "['java','-jar','/app.jar']"]
        depends_on: ['mysql-standalone','eureka-server']


Docker file for User management app is:

FROM openjdk:8
Add target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
VOLUME /tmp
EXPOSE 8089
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .
COPY target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

Docker file for Eureka- server

FROM openjdk:8
EXPOSE 8761
ADD /target/Eureka-Server-For-User-Management-App-0.0.1-SNAPSHOT.jar netflix-eureka-server-1.0.jar
COPY wait-for.sh .
netflix-eureka-server-1.0.jar
ENTRYPOINT ["java","-jar","netflix-eureka-server-1.0.jar"]

Edit 2 I just edited mysql docker file to check if it is even getting executed or not

RUN echo "'Entered in docker file of mysql'"
FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat
COPY wait-for.sh .

RUN echo "'Exiting docker file of mysql'"

and found that on doing docker-compose up it is not echoing the text

  • Why do you need `nc` in a MySQL server container? Do you maybe need this in your application container instead, to support something like the `wait-for-it` script? (And that you should have the Dockerfile for.) – David Maze Dec 17 '21 at 14:15
  • @DavidMaze Yes. I am using wait-for.sh script. I have updated the question. Please recheck the "Edit 1 " section. When I am using wait-for.sh script. It is giving me "nc is missing error". I am suffering from this error since 5 days and haven't found solution. Please help if you have knowledge about it. –  Dec 18 '21 at 15:48
  • You are using both `image` and `build` in a single service definition. I think `docker-compose` skip `build` section because requested `image` are presented locally. Try to remove `image: ...`. – Anton Dec 19 '21 at 19:02
  • @Anton if I would remove "image" then it wont pull the image file from docker hub I think. Build I am using to run Docker file. Let me know if I am wrong? –  Dec 21 '21 at 08:05
  • @user123 `docker` will pull it while building your custom image from your `Dockerfile` (because you set `mysql:8` as base image in `FROM mysql:8` line) – Anton Dec 21 '21 at 08:11
  • @Anton I tried what you said.. On doing so it has stopped giving 'nc command is missing ' error. But it is now exiting like "user-management-app_mysql-standalone_1 exited with code 0" without showing any reason. Earlier I knew it was happening due to 'nc command is missing'. But this time there is no reason in the logs. Any Pointers? –  Dec 21 '21 at 09:00
  • @user123 Use `docker-compose logs` to see what happens – Anton Dec 21 '21 at 09:01
  • @Anton No logs are printed there for MySQL. The logs printed there are only for Eureka-server, phpMyAdmin and myApp. –  Dec 21 '21 at 09:07

3 Answers3

2

You don't need to install netcat in the database server container. There are a couple of other things you can clean up to simplify this setup.

Let's start by thinking through what needs to happen when you run docker-compose up. The application container can't function until the database is up and running; for that, the application container is using the wait-for script, which in turn uses nc. The database itself doesn't need to make any outbound connections, though; it needs to start up and accept inbound connections so the rest of the system can proceed. So you don't need nc in the database server container, and you can just use the standard unmodified mysql image.

(In your Dockerfile you show the database depending on the Eureka service registry; but the database itself won't do anything to connect to it, and you're using a direct connection to the database from your application. It doesn't need to be part of this stack.)

Your Compose setup also overrides the image's entrypoint:. This shouldn't usually be necessary. I'd suggest a pattern where the image's ENTRYPOINT is a self-contained script that ends with a shell exec "$@" command, which will let it run the CMD passed to it as arguments. So that script could look something like

#!/bin/sh
# ./entrypoint.sh

# Set defaults for common environment variables
: ${MYSQL_PORT:=3306}
: ${MYSQL_DATABASE:=usermanagementappdp}

# Wait for the database to be ready
./wait-for.sh "$MYSQL_HOST:$MYSQL_PORT"

# Dynamically set the Spring database URL
export SPRING_DATASOURCE_URL="jdbc:mysql://$MYSQL_HOST:$MYSQL_PORT/$MYSQL_DATABASE?allowPublicKeyRetrieval=true&autoReconnect=true&useSSL=false"

# Run the main container command
exec "$@"

Then in your application's Dockerfile -- again, you don't need to change anything in the database's Dockerfile -- set this script as the ENTRYPOINT, and make your java -jar command the CMD.

FROM openjdk:8

# Install OS-level dependencies before COPYing anything in
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install --no-install-recommends --assume-yes \
      netcat

# COPY in the actual application (don't usually ADD things)
WORKDIR /app
COPY target/User-Management-App-0.0.1-SNAPSHOT.jar app.jar
COPY wait-for.sh entrypoint.sh .

# Set metadata for how to run the application
EXPOSE 8089
ENTRYPOINT ["./entrypoint.sh"]  # must be JSON-array syntax
CMD ["java", "-jar", "app.jar"]

Now in your docker-compose.yml setup you can get rid of most of the overrides. Run an unmodified mysql image and don't override the command: or entrypoint: of anything.

version: "3.8"
services:
    mysql-standalone:
        image: mysql:8.0.25
        environment:
            - MYSQL_ROOT_PASSWORD=********
            - MYSQL_DATABASE=usermanagementappdp
        ports:
            - 3306:3306

    phpmyadmin: { image: phpmyadmin/phpmyadmin, ... }

    eureka-server:
        build: ../Eureka-Server-For-User-Management-App

    usermanagementapp-docker:
        ports:
            - 8089:8089
        environment:
            EUREKA_CLIENT_SERVICEURL_DEFAULTZONE: http://eureka-server:8761/eureka
            MYSQL_HOST: mysql-standalone
        build: .
        restart: on-failure
        depends_on: [mysql-standalone, eureka-server]

The setup you show above will contaminate your local copy of the MySQL image, so before you start, you should clean it up

docker pull mysql:8.0.25

If you need to do some sort of registration in the MySQL image at startup time, then you can follow this same basic approach. It is helpful to look up the Docker Hub mysql image page and from there its Dockerfile because you will need to know the original ENTRYPOINT and CMD.

In the ENTRYPOINT wrapper script, at the end, run the original entrypoint:

#!/bin/sh
# my-entrypoint.sh
...
exec docker-entrypoint.sh "$@" # running the original entrypoint

In your derived Dockerfile, you'll need to repeat the original CMD

FROM mysql:8.0.27
...
COPY wait-for.sh my-entrypoint.sh /usr/local/bin
ENTRYPOINT ["my-entrypoint.sh"]
CMD ["mysqld"]

In your Compose file, do not specify both image: mysql and a build: block. This will overwrite your local copy of the Docker Hub image with your custom build. For most purposes you can only specify build: and ignore image:. You do not need to use volumes: to inject code, that's contained within the custom Dockerfile.

services:
    mysql-standalone:
        build: ./mysql
        # no image:
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Thanks for your so deeply explained answer. I found you have written ".... which in turn uses nc. The database itself doesn't need to make any outbound connections, though; it needs to start up and accept inbound connections so the rest of the system can proceed..." I think you didn't get the flow of the app properly. Its right that my app is waiting for MySQL to startup but further MySql IS WAITING for Eureka-server to startup. Means first Eureaka should start completely then MySQl complete and THEN myApp. I think that's why it needs nc command to be there in MySQL container. Isn't it? –  Dec 21 '21 at 07:01
  • Also @David Maze ,the entrypoint.sh The script code which you provided, in that you have told "# Run the main container command exec "$@"" . So do I need to put something after $@? Do I need to put container ID of myApp container, MySQL container or Eureka-server container? –  Dec 21 '21 at 08:12
  • As I implemented your code.. Eureka server and MySQL has started succefully but for myApp It is giving me this error "usermanagementapp-docker_1 | standard_init_linux.go:211: exec user process caused "no such file or directory"". I think I need to add something in last line of entrypoint.sh... after $@... but not sure what is that. Please let me know if there is something else which is causing this error. –  Dec 21 '21 at 08:40
  • In an entrypoint script, `exec "$@"` will run the image's `CMD` (or an overridden Compose `command:`). You don't need to put anything after it. – David Maze Dec 21 '21 at 10:57
  • Okay. But now I am getting "usermanagementapp-docker_1 | standard_init_linux.go:211: exec user process caused "no such file or directory"" as I told in above comment. would be very helpful if you can help with this? Eureka server and MySQL has started successfully, but MySQL is starting before Eureka server. Where as it should have waited for Eureka server to start first completely. –  Dec 21 '21 at 11:10
  • https://stackoverflow.com/questions/51508150/standard-init-linux-go190-exec-user-process-caused-no-such-file-or-directory The first answer in this solution solved my issue of "standard_init_linux.go:211: exec user process caused "no such file or directory"" –  Dec 22 '21 at 07:52
0

You could build and publish your own container image if you wanted with a dockerfile like this

FROM mysql:8
RUN apt-get -q update && apt-get -qy install netcat

and build it like docker build . -t user123/mysql:8

and push it like docker push user123/mysql:8

then switch your docker compose to use your custom container.

if you just need to pop in temporarily to install netcat, you can do that by doing

docker exec -it --user=root ContainerHashOrName /bin/bash where ContainerHashOrName can be retrieved from docker ps then just run your commands like you would on any other distro. Just be aware that you are only making changes to the specific instance of a container and that any rescheduling will bring up a different instance of the container.

Junkiebev
  • 143
  • 9
  • Thanks for your response @Junkiebev. But I am still facing the same issue. mysql-standalone_1 | nc command is missing! I have updated the question in Edit1 section. Please check –  Dec 18 '21 at 15:39
  • I am building docker file for mysql using this command --- "docker build -f Dockerfile -t mysql:8.0.25 ." and it says "Sending build context to Docker daemon 7.168kB Error response from daemon: No build stage in current context" –  Dec 18 '21 at 16:56
0

You can use "build" option of compose file, https://docs.docker.com/compose/compose-file/compose-file-v3/#build and use your own Dockerfile starts with FROM mysql:8 and then install all additional stuff you need.

Anton
  • 728
  • 3
  • 8
  • Thanks for your response @Junkiebev. But I am still facing the same issue. mysql-standalone_1 | nc command is missing! I have updated the question in Edit1 section. Please check –  Dec 18 '21 at 15:44