Search code examples
laraveldockercontainersdevelopment-environment

How to get docker containers from different projects speaking to each other


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.


Solution

  • 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