0

I'm starting to learn docker and I wanted to start with getting-started examples from docker docs. Everything works fine until I tried to use docker compose. I use the suggested YAML file.

services:
  app:
    image: node:18-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:8.0
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

Then I tried to compose docker compose up -d then checked the logs docker compose logs -f and says that the todo app can't reach the mysql container IDK why this happen, hope that you could help me. Sorry if I paste evrithing, is because I honestly don't know where's the problem.

app-app-1    | yarn install v1.22.19
app-app-1    | [1/4] Resolving packages...
app-app-1    | success Already up-to-date.
app-app-1    | Done in 0.47s.
app-app-1    | yarn run v1.22.19
app-app-1    | $ nodemon src/index.js
app-app-1    | [nodemon] 2.0.20
app-app-1    | [nodemon] to restart at any time, enter `rs`
app-app-1    | [nodemon] watching path(s): *.*
app-app-1    | [nodemon] watching extensions: js,mjs,json
app-app-1    | [nodemon] starting `node src/index.js`
app-app-1    | Waiting for mysql:3306............
app-app-1    | Timeout
app-app-1    | Error: connect ECONNREFUSED 172.20.0.3:3306
app-app-1    |     at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16) {
app-app-1    |   errno: -111,
app-app-1    |   code: 'ECONNREFUSED',
app-app-1    |   syscall: 'connect',
app-app-1    |   address: '172.20.0.3',
app-app-1    |   port: 3306,
app-app-1    |   fatal: true
app-app-1    | }
app-app-1    | [nodemon] app crashed - waiting for file changes before starting...
app-mysql-1  | 2023-03-24 17:31:32+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.32-1.el8 started.
app-mysql-1  | 2023-03-24 17:31:32+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
app-mysql-1  | 2023-03-24 17:31:32+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.32-1.el8 started.
app-mysql-1  | 2023-03-24 17:31:32+00:00 [Note] [Entrypoint]: Initializing database files
app-mysql-1  | 2023-03-24T17:31:32.540256Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
app-mysql-1  | 2023-03-24T17:31:32.540331Z 0 [System] [MY-013169] [Server] /usr/sbin/mysqld (mysqld 8.0.32) initializing of server in progress as process 79
app-mysql-1  | 2023-03-24T17:31:32.547603Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
app-mysql-1  | 2023-03-24T17:31:33.570965Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
app-mysql-1  | 2023-03-24T17:31:35.250031Z 6 [Warning] [MY-010453] [Server] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
app-mysql-1  | 2023-03-24 17:31:38+00:00 [Note] [Entrypoint]: Database files initialized
app-mysql-1  | 2023-03-24 17:31:38+00:00 [Note] [Entrypoint]: Starting temporary server
app-mysql-1  | 2023-03-24T17:31:38.708101Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
app-mysql-1  | 2023-03-24T17:31:38.709884Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.32) starting as process 122
app-mysql-1  | 2023-03-24T17:31:38.725648Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
app-mysql-1  | 2023-03-24T17:31:39.009193Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
app-mysql-1  | 2023-03-24T17:31:39.351324Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
app-mysql-1  | 2023-03-24T17:31:39.351394Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
app-mysql-1  | 2023-03-24T17:31:39.353972Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
app-mysql-1  | 2023-03-24T17:31:39.373215Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: /var/run/mysqld/mysqlx.sock
app-mysql-1  | 2023-03-24T17:31:39.373388Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.32'  socket: '/var/run/mysqld/mysqld.sock'  port: 0  MySQL Community Server - GPL.
app-mysql-1  | 2023-03-24 17:31:39+00:00 [Note] [Entrypoint]: Temporary server started.
app-mysql-1  | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
app-mysql-1  | Warning: Unable to load '/usr/share/zoneinfo/iso3166.tab' as time zone. Skipping it.
app-mysql-1  | Warning: Unable to load '/usr/share/zoneinfo/leapseconds' as time zone. Skipping it.
app-mysql-1  | Warning: Unable to load '/usr/share/zoneinfo/tzdata.zi' as time zone. Skipping it.
app-mysql-1  | Warning: Unable to load '/usr/share/zoneinfo/zone.tab' as time zone. Skipping it.
app-mysql-1  | Warning: Unable to load '/usr/share/zoneinfo/zone1970.tab' as time zone. Skipping it.
app-mysql-1  | 2023-03-24 17:31:42+00:00 [Note] [Entrypoint]: Creating database todos
app-mysql-1  | 
app-mysql-1  | 2023-03-24 17:31:42+00:00 [Note] [Entrypoint]: Stopping temporary server
app-mysql-1  | 2023-03-24T17:31:42.287782Z 11 [System] [MY-013172] [Server] Received SHUTDOWN from user root. Shutting down mysqld (Version: 8.0.32).
app-mysql-1  | 2023-03-24T17:31:44.092300Z 0 [System] [MY-010910] [Server] /usr/sbin/mysqld: Shutdown complete (mysqld 8.0.32)  MySQL Community Server - GPL.
app-mysql-1  | 2023-03-24 17:31:44+00:00 [Note] [Entrypoint]: Temporary server stopped
app-mysql-1  | 
app-mysql-1  | 2023-03-24 17:31:44+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
app-mysql-1  | 
app-mysql-1  | 2023-03-24T17:31:44.483284Z 0 [Warning] [MY-011068] [Server] The syntax '--skip-host-cache' is deprecated and will be removed in a future release. Please use SET GLOBAL host_cache_size=0 instead.
app-mysql-1  | 2023-03-24T17:31:44.484177Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.32) starting as process 1
app-mysql-1  | 2023-03-24T17:31:44.490900Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
app-mysql-1  | 2023-03-24T17:31:44.600233Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
app-mysql-1  | 2023-03-24T17:31:44.773495Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
app-mysql-1  | 2023-03-24T17:31:44.773543Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
app-mysql-1  | 2023-03-24T17:31:44.776254Z 0 [Warning] [MY-011810] [Server] Insecure configuration for --pid-file: Location '/var/run/mysqld' in the path is accessible to all OS users. Consider choosing a different directory.
app-mysql-1  | 2023-03-24T17:31:44.792749Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
app-mysql-1  | 2023-03-24T17:31:44.793079Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for connections. Version: '8.0.32'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server - GPL.

I want to know why isn't connecting because apparently it should work. Also, it works when I try to run each container separately.

docker run -dp 3000:3000 \
  -w /app -v "$(pwd):/app" \
  --network todo-app \
  -e MYSQL_HOST=mysql \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD=secret \
  -e MYSQL_DB=todos \
  node:18-alpine \
  sh -c "yarn install && yarn run dev"
docker run -d \
  --network todo-app --network-alias mysql \
  -v todo-mysql-data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=todos \
  mysql:8.0
  • The important thing in that `docker-compose up` output is that the application tries to start and fails before the database is initialized; you see the `app crashed` message before any of the MySQL messages. Also see [Docker Compose wait for container X before starting Y](https://stackoverflow.com/questions/31746182/docker-compose-wait-for-container-x-before-starting-y). – David Maze Mar 24 '23 at 23:36
  • (Consider using `docker-compose up -d mysql` to start the database, then just using `yarn run dev` to launch the Node application without involving Docker. That will be a simpler setup. Your logs mention `nodemon`, and I also see a lot of questions go by about live-reloading code not working reliably when injected through a bind mount.) – David Maze Mar 24 '23 at 23:40

1 Answers1

0

I'm not sure why the example doesn't include this, but it can be resolved by using the depends_on element in the docker-compose.yml file to make the app service wait on the mysql service:

services:
  app:
    image: node:18-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos
    depends_on:
      - mysql

  mysql:
    image: mysql:8.0
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

Then when you check the logs you will see that it explicitly waited for the mysql service to come up:

app-app-1    | yarn install v1.22.19
app-app-1    | [1/4] Resolving packages...
app-app-1    | success Already up-to-date.
app-app-1    | Done in 0.63s.
app-app-1    | yarn run v1.22.19
app-app-1    | $ nodemon src/index.js
app-app-1    | [nodemon] 2.0.20
app-app-1    | [nodemon] to restart at any time, enter `rs`
app-app-1    | [nodemon] watching path(s): *.*
app-app-1    | [nodemon] watching extensions: js,mjs,json
app-app-1    | [nodemon] starting `node src/index.js`
app-app-1    | Waiting for mysql:3306.
app-app-1    | Connected!
app-app-1    | Connected to mysql db at host mysql
app-app-1    | Listening on port 3000

What I don't understand is why the Getting Started directions include the statement:

Docker doesn’t have any built-in support to wait for another container to be fully up, running, and ready before starting another container.

when that is pretty much exactly what depends_on does.

nigh_anxiety
  • 1,428
  • 2
  • 4
  • 12