Containers

As a DevOps engineer, you need to deploy a web application with a Node.js backend and a MySQL database using Docker. The Node.js app connects to MySQL on localhost:3306, but running docker run for each container separately fails because they can’t communicate. How would you set up these containers to work together?

Difficulty: unrated

Source: bregman-arie/devops-exercises by Arie Bregman

Answer

To make the Node.js and MySQL containers communicate:

  1. Use Docker Compose: Create a docker-compose.yml file to define and link both services:
    version: '3.8'
    services:
      node-app:
        image: my-node-app
        build: .
        ports:
          - "3000:3000"
        depends_on:
          - mysql-db
        environment:
          - DB_HOST=mysql-db
          - DB_PORT=3306
      mysql-db:
        image: mysql:8.0
        environment:
          - MYSQL_ROOT_PASSWORD=secret
        ports:
          - "3306:3306"
    
  2. Run the Application: Execute docker-compose up -d to start both containers. The node-app service connects to mysql-db using the service name (mysql-db) as the hostname, not localhost.
  3. Verify Connectivity: Check logs with docker-compose logs node-app to ensure the Node.js app connects to MySQL. If it fails, verify the environment variables and MySQL’s readiness.
  4. Alternative Without Compose: Use a custom network:
    • Create a network: docker network create my-app-network
    • Run MySQL: docker run -d --name mysql-db --network my-app-network -e MYSQL_ROOT_PASSWORD=secret mysql:8.0
    • Run Node.js: docker run -d --name node-app --network my-app-network -p 3000:3000 -e DB_HOST=mysql-db my-node-app