1

I'm trying to dockerize an existing adonis.js app and MySQL through docker-compose.

Here is my Dockerfile

FROM node:12.18.2-alpine3.9

ENV HOME=/app
RUN mkdir /app

COPY package.json $HOME

WORKDIR $HOME
RUN npm i -g @adonisjs/cli && npm install

CMD ["npm", "start"]

And here is my docker-compose.yml file

version: '3'

services:
  adonis-mysql:
    image: mysql:5.7
    ports:
      - '3307:3306'
    volumes:
      - $PWD/data:/var/lib/mysql
    environment:
      MYSQL_USER: ${DB_USER}
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_ALLOW_EMPTY_PASSWORD: ${DB_ALLOW_EMPTY_PASSWORD}
    networks:
      - api-network
  adonis-api:
    container_name: "${APP_NAME}-api"
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/app
      - /app/node_modules
    ports:
      - "3333:3333"
    depends_on:
      - adonis-mysql
    networks:
      - api-network

networks:
  api-network:

When running docker-compose up everything goes smoothly and the adonis-api container says that the app is running but I'm am unable to reach it, I always get:

This site can’t be reached
127.0.0.1 refused to connect.

or

This site can’t be reached
The connection was reset.

I tried with different docker-compose settings, and different dockerfiles, almost always everything starts ok but I'm just unable to access the server. Also tried different IP and ports, but still nothing.

Container logs:

testProject-api | 
testProject-api | > adonis-fullstack-app@4.1.0 start /app
testProject-api | > node server.js
testProject-api | 
adonis-mysql_1  | 2020-07-09T09:56:35.960082Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the --initialize-insecure option.
testProject-api | info: serving app on http://127.0.0.1:80

docker ps

dan@dan-Nitro-AN515-54:~/Documents/Tests/testProject$ docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                               NAMES
45f3dd21ef93        testproject_adonis-api   "docker-entrypoint.s…"   20 seconds ago      Up 19 seconds       0.0.0.0:3333->3333/tcp              testProject-api
7b40bc7c75c3        mysql:5.7                "docker-entrypoint.s…"   2 minutes ago       Up 20 seconds       33060/tcp, 0.0.0.0:3307->3306/tcp   testproject_adonis-mysql_1
Agilulfo
  • 101
  • 3
  • 10

1 Answers1

2

There's two things that jump out in this setup.

First of all, when the container startup prints:

info: serving app on http://127.0.0.1:80

That's usually an indication of a configuration issue that will make the process inaccessible. In Docker each container has its own localhost interface, so a process that's "listening on 127.0.0.1" will only be reachable from the container-private localhost interface, but not from other containers or the host (regardless of what ports: options you have). You generally need to set processes to "bind" or "listen" to the special 0.0.0.0 all-interfaces address.

Within Adonis it looks like this is controlled by the $HOST environment variable; the Adonis templates set this to 127.0.0.1. Adonis documents itself as using the dotenv library, and that in turn gives precedence to environment variables over the .env file, so it should be enough to set an environment variable HOST=0.0.0.0.

(None of the previous paragraph is discussed in the Adonis documentation!)

The second thing from that error message is that the second number in ports: needs to match the port number the container process is using. The Adonis templates all seem to default this to port 3333 but that startup message says port 80, so you need to change your ports: to be port 80 on the right-hand side. You can pick any port you want for the left-hand side.

Adding in some routine cleanups, you could replace your docker-compose.yml service block with:

adonis-api:
  build: .          # context directory only; use default Dockerfile
  environment:
    - HOST=0.0.0.0  # listen on all interfaces
  ports:
    - "3333:80"     # matches actual listener message
  depends_on:
    - adonis-mysql
  # Use "default" network (also delete other networks: blocks in the file)
  # Use Compose default container name
  # Use code from the Docker image; don't overwrite with volumes
  # (and don't tell Docker to use arbitrarily old node_modules)
David Maze
  • 130,717
  • 29
  • 175
  • 215
  • Oh my God, thank you! This was it. I spent two days troubleshooting this. Thank you. – Agilulfo Jul 09 '20 at 10:51
  • David, everything was working fine but then I moved all docker related stuff to a dedicated folder and now I cannot connect to MySQL anymore. Seems the same stuff of the host I was having with the API part. Is it too much to ask you to look at my new problem? https://stackoverflow.com/questions/62837140/cant-connect-to-dockerized-mysql – Agilulfo Jul 10 '20 at 16:13