0

I have developed and dockerised two applications web (react) and api (laravel, mysql), they have separate codebases and separate directories.

Could somebody please help explain how I can get my web application talking to my api whilst using docker at the same time

Update: Ultimately what I want to achieve is to have both my frontend and backend running on port 80 without having to have two web servers running as containers so that my docker development environment will work the same as using valet or mamp etc.

Starks
  • 37
  • 4
  • 1
    You can try `docker-compose`? – Sithroo Feb 26 '20 at 16:11
  • 1
    docker-compose? – Burak Serdar Feb 26 '20 at 16:11
  • Can you share a minimal efforts you have put to try to make them communicate? Apart from this, normally both apps normally would have an exposed ips and ports that you can use. – Oluwatobi Samuel Omisakin Feb 26 '20 at 16:19
  • The other part of this is that the React application will ultimately run in a browser, not in Docker (even if the files are getting served out of a Docker container) and so it needs to see host names and ports that are visible at the host level. – David Maze Feb 26 '20 at 16:52
  • I am already using docker-compose. Ultimately what I want to achieve is to have both my frontend and backend running on port 80 without having to have two webservers running as containers – Starks Feb 27 '20 at 15:24

1 Answers1

1

For development you could make use of docker-compose.

Key benefits:

  • Configure your app's services in YAML.
  • Single command to create/start the services defined on this configuration.
  • Compose creates a default network for your app. Each container joins this default network and they can see each other.

I use the following structure for a project.

projectFolder
  |_backend (laravel app)
  |_frontend (react app)
  |_docker-compose.yml
  |_backend.dockerfile
  |_frontend.dockerfile

My docker-compose.yml

version: "3.3"
  services:
    frontend:
      build:
        context: ./
        dockerfile: frontend.dockerfile
        args:
          - NODE_ENV=development
      ports:
        - "3000:3000"
      volumes:
        - ./frontend:/opt/app
        - ./frontend/package.json:/opt/package.json
      environment:
        - NODE_ENV=development
    backend:
      build:
        context: ./
        dockerfile: backend.dockerfile
      working_dir: /var/www/html/actas
      volumes:
        - ./backend:/var/www/html/actas
      environment:
        - "DB_PORT=3306"
        - "DB_HOST=mysql"
      ports:
        - "8000:8000"
    mysql:
      image: mysql:5.6
      ports:
        - "3306:3306"
      volumes:
        - dbdata:/var/lib/mysql
      environment:
        - "MYSQL_DATABASE=homestead"
        - "MYSQL_USER=homestead"
        - "MYSQL_PASSWORD=secret"
        - "MYSQL_ROOT_PASSWORD=secret"

  volumes:
    dbdata:

Each part of the application is defined by a service in the docker-compose file. E.g.

  • frontend
  • backend
  • mysql

Docker-compose will create a default network and add each container to it. The hostname for each container will be the service name defined in the yml file.

For example, the backend container access the mysql server with the name mysql. You can see this on the service definition itself:

backend:
...
  environment:
  - "DB_PORT=3306"
  - "DB_HOST=mysql" <-- The hostname for the mysql container is the name of the service

With this, in the react app, I can setup the proxy configuration in package.json as follows

"proxy": "http://backend:8000",

One last thing, as mentioned by David Maze in the comments. Add the backend to your hosts file, so the browser could resolve that name.

E.g /etc/hosts on ubuntu

127.0.1.1       backend
theBittor
  • 652
  • 1
  • 9
  • 19
  • Thanks, this makes a lot of sense. What would the best practice be in this situation assuming that my front end and backend are both served using nginx. Is it possible to have my webapp and api share the same nginx container? – Starks Feb 27 '20 at 15:19