简体   繁体   English

如何通过 digitalOcean droplet 将 Node express server-docker-image 连接到 mysql docker 图像?

[英]How to connect Node express server-docker-image to mysql docker image via digitalOcean droplet?

I have an experimental app where I am working with images.我有一个实验性应用程序,我在其中处理图像。 The goal is to make a full working app with docker containers and images which I have managed to do on my local machine.目标是使用 docker 个容器和图像制作一个完整的工作应用程序,我已设法在本地计算机上完成这些操作。 The issue im having is when im deploying it to digitalocean.我遇到的问题是当我将它部署到 Digitalocean 时。

from the node-express-server im getting this error response:node-express-server我得到这个错误响应:

{
    "status": "error",
    "statusCode": 500,
    "message": {
        "errno": "ENOTFOUND",
        "code": "ENOTFOUND",
        "syscall": "getaddrinfo",
        "hostname": "dbcontainer",
        "fatal": true
    }
}

Im using docker-compose file:我正在使用 docker-compose 文件:

services:
  mysql:
    build:
      context: ./DbScripts
      dockerfile: ./Dockerfile.prod
    command:
      - "--default-authentication-plugin=mysql_native_password"
    container_name: dbcontainer
    cap_add:
      - SYS_NICE 
    ports:
      - 3307:3306
    restart: always
    networks:
      - mynetwork
    environment:
      MYSQL_DATABASE: todo
      MYSQL_USER: produser
      MYSQL_ROOT_PASSWORD: Password!
      MYSQL_PASSWORD: Password!
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 1s
      retries: 120
  phpmyadmin:
    # build: .
    image: phpmyadmin/phpmyadmin
    container_name: dev_pma
    networks:
      - mynetwork
    environment:
      PMA_HOST: dbcontainer
      PMA_PORT: 3307
      PMA_ARBITRARY: 1
    restart: always
    ports:
      - 8183:80
  server:
    container_name: server
    build:
      context: ./BE
      dockerfile: ./Dockerfile.prod
    networks:
      - mynetwork
    ports:
      - 4000:4000
  client:
    container_name: FE
    build:
      context: ./FE
      dockerfile: ./Dockerfile.prod
    networks:
      - mynetwork
    ports:
      - 3000:3000
    environment:
      - CHOKIDAR_USEPOLLING=true
    tty: true
volumes:
  db_data:
networks:
  mynetwork:

Im also using dockerfiles inside of the docker-compose. The releveant ones are:我还在 docker-compose 内部使用 dockerfiles。相关的是:

mysql Dockerfile: mysql Dockerfile:

FROM mysql

ENV MYSQL_ROOT_PASSWORD Dsb2016!
ADD /DumpTodoOnly.sql /docker-entrypoint-initdb.d

EXPOSE 3306

Above im using a sql file to create database and user:上面我使用 sql 文件创建数据库和用户:

CREATE USER 'produser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Password!';

GRANT ALL PRIVILEGES ON *.* TO 'produser'@'localhost' WITH GRANT OPTION;

CREATE DATABASE  IF NOT EXISTS `todo` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
USE `todo`;
-- MySQL dump 10.13  Distrib 8.0.18, for Win64 (x86_64)
--
-- Host: localhost    Database: todo
-- ------------------------------------------------------
-- Server version   8.0.18

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!50503 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `todos`
--


DROP TABLE IF EXISTS `todos`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `todos` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `todotext` varchar(200) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=23 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `users`
--

DROP TABLE IF EXISTS `users`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!50503 SET character_set_client = utf8mb4 */;
CREATE TABLE `users` (
  `Id` varchar(36) NOT NULL,
  `Email` varchar(200) NOT NULL,
  `Password` binary(60) NOT NULL,
  `ChangedPassword` bit(1) NOT NULL,
  `FirstName` varchar(45) NOT NULL,
  `LastName` varchar(45) NOT NULL,
  `ImageId` varchar(36) DEFAULT NULL,
  `SeqRef` varchar(36) DEFAULT NULL,
  PRIMARY KEY (`Id`),
  UNIQUE KEY `Email_UNIQUE` (`Email`),
  UNIQUE KEY `Id_UNIQUE` (`Id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci KEY_BLOCK_SIZE=2;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Dumping routines for database 'todo'
--
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2022-04-12  0:18:13

The connection in my node express:我的节点表达中的连接:

const connector = mysql.createPool({
  connectionLimit: 20,
  host: "dbcontainer",
  database: "todo",
  user: "produser",
  password: "Password!",
});

Images图片

I run docker-compose up -d --build and get this:我运行docker-compose up -d --build并得到这个:

在此处输入图像描述

I copy the imageId of the server, sql and php and for each of these I tag it:我复制了服务器的 imageId sql 和 php 并为其中的每一个标记了它:

docker tag imageId ghcr.io/userName/imageName:1

And push it to github packages:并推送到github个包:

 docker push ghcr.io/userName/imageName:1

DigitalOcean数字海洋

I connect to my github account and pull the images from github packages.我连接到我的 github 帐户并从 github 包中提取图像。

I run mysql image first and after doing that I enter the container to see if my database and user got created which I can verify that they have since both the Todo db and user "produser" are created on digitalOcean:我首先运行 mysql 图像,然后进入容器以查看我的数据库和用户是否已创建,我可以验证它们是否已创建,因为 Todo 数据库和用户“produser”都是在 digitalOcean 上创建的:

--------------------
| Database |
--------------------
| information_schema |
| mysql |
| performance_schema |
| sys |
| todo |
--------------------

------------------
| user |
------------------
| root |
| mysql.infoschema |
| mysql.session |
| mysql.sys |
| produser |
| root |
------------------

The containers on digitalocean look like this: digitalocean 上的容器如下所示:

CONTAINER ID   IMAGE                              COMMAND                  CREATED          STATUS          PORTS                                                  NAMES
e8fc8145a30c   ghcr.io/username/phpnewest:1      "/docker-entrypoint.…"   10 minutes ago   Up 10 minutes   0.0.0.0:8183->80/tcp, :::8183->80/tcp                  agitated_antonelli
dab65fd84ddb   ghcr.io/username/serverlatest:1   "docker-entrypoint.s…"   11 minutes ago   Up 11 minutes   0.0.0.0:4000->4000/tcp, :::4000->4000/tcp              unruffled_goldberg
cc3fdf91e7ab   dbcontainer                        "docker-entrypoint.s…"   13 minutes ago   Up 13 minutes   33060/tcp, 0.0.0.0:3307->3306/tcp, :::3307->3306/tcp   friendly_ardinghelli

Again everything worked on my machine but when pushing to digitalocean I get the server error above and on the phpAdmin I get:同样,一切都在我的机器上运行,但是当推送到 digitalocean 时,我在上面和 phpAdmin 上收到服务器错误,我得到:

mysqli::real_connect(): php.network_getaddresses: getaddrinfo failed: Name or service not known mysqli::real_connect(): (HY000/2002): php.network_getaddresses: getaddrinfo failed: Name or service not known mysqli::real_connect(): php.network_getaddresses: getaddrinfo 失败:名称或服务未知 mysqli::real_connect(): (HY000/2002): php.network_getaddresses: getaddrinfo 失败:名称或服务未知

Where have I gone wrong?我哪里出错了? Have I missed a configuration somewhere on the server?我错过了服务器某处的配置吗? Im running a droplet with Docker 19.03.12 on ubuntu.我在 ubuntu 上运行 Docker 19.03.12 的 Droplet。

Im new to docker-compose and as I said im building it and then tagging the images seperatly and pushing them, is this correct?我是 docker-compose 的新手,正如我所说,我正在构建它,然后分别标记图像并推送它们,这是正确的吗? Any guidence is appreciated.任何指导表示赞赏。

EDIT:编辑:

Dont know how relevant this is but when I was inside of the dbcontainer I checked to see hon what host the mysql was running and it was "localhost".不知道这有什么关系,但是当我进入 dbcontainer 时,我检查了 mysql 正在运行的主机,它是“localhost”。

Doing the same for the node-express with the following command:使用以下命令对 node-express 执行相同的操作:

docker exec -it serverid /bash/sh

And then hostname I just got back the container id.然后是hostname ,我刚刚取回了容器 ID。

EDIT2:编辑2:

Maybe to ultral clear about this: I run docker-compose on my local machine(my pc) only.也许要非常清楚这一点:我只在我的本地机器(我的电脑)上运行 docker-compose。 Then I take each image seperatly and try to connect them on a droplet on digitalOceean.然后我分别拍摄每张图像并尝试将它们连接到 digitalOceean 上的一个 droplet 上。

I have also tried to change my docker-compose to this:我还尝试将我的 docker-compose 更改为:

version: "3.7"

networks:
  mynet:

volumes:
  mysqldb_data:
  phpmyadmin_data:

services:
  mysql:
    build:
      context: ./DbScripts
      dockerfile: ./Dockerfile.prod
    command:
      - "--default-authentication-plugin=mysql_native_password"
    environment:
      MYSQL_DATABASE: todo
      MYSQL_USER: produser
      MYSQL_ROOT_PASSWORD: Password!
      MYSQL_PASSWORD: Password!
    volumes:
      - ./DbScripts/DumpTodoOnly.sql:/docker-entrypoint-initdb.d/DumpTodoOnly.sql
      - mysqldb_data:/var/lib/mysql
    networks:
      - mynet
  phpmyadmin:
    image: phpmyadmin/phpmyadmin:fpm-alpine
    environment:
      PMA_HOST: mysql
    volumes:
      - phpmyadmin_data:/var/www/html/
    networks:
      - mynet
    depends_on:
      - mysql
    ports:
      - 8183:80
  nginx:
    image: nginx:1.17.4-alpine
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf:ro
      - phpmyadmin_data:/var/www/html/:ro
    ports:
      - "90:80"
    networks:
      - mynet
    depends_on:
      - mysql
      - phpmyadmin

Sadly this docker-compose attempt resulted in the php admin not working where I get connection_refused both on localhost and on the droplet.遗憾的是,这次 docker-compose 尝试导致 php 管理员无法工作,我在本地主机和 Droplet 上都得到了 connection_refused。 the datbase and user still get created on the server and local machine.数据库和用户仍然在服务器和本地计算机上创建。 The nginx did not run on local enviorment but did run on the droplet. nginx 没有在本地环境中运行,而是在 droplet 上运行。 Not sure what it should do in this scenario though.虽然不确定在这种情况下应该做什么。

For anyone attempting an ansewr please give me a step by step guide.对于任何尝试回答的人,请给我一步一步的指导。

Right now I am doing the following:现在我正在做以下事情:

  1. Run docker-compose on local enviorment在本地环境运行 docker-compose
  2. Push each individual image to github packages将每个单独的图像推送到 github 个包
  3. Connect to digitalOcean连接到数字海洋
  4. Pull the images拉取图像
  5. Run each image on specific port.在特定端口上运行每个图像。

My process must be obviosly faulty since it does not work.我的过程肯定是明显错误的,因为它不起作用。

After 2 weeks of trying I managed to get this spinning.经过 2 周的尝试,我设法让这个旋转起来。

The core problem was that I did not quite understand the use of docker-compose. My intial thought was that the images it created could just be used as standalone and then they would autmactially link.核心问题是我不太了解docker-compose的用途。我最初的想法是它创建的图像可以单独使用,然后自动链接。

The solution is quite simple解决方法很简单

I use this docker-compose:我用这个 docker-compose:

services:
  mysql:
    build:
      context: ./DbScripts
      dockerfile: ./Dockerfile.prod
    command:
      - "--default-authentication-plugin=mysql_native_password"
    container_name: dbcontainer
    cap_add:
      - SYS_NICE # CAP_SYS_NICE
    ports:
      - 3307:3306
    restart: always
    networks:
      - mynetwork
    environment:
      MYSQL_DATABASE: todo
      MYSQL_USER: produser
      MYSQL_ROOT_PASSWORD: Password!
      MYSQL_PASSWORD: Password!
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 1s
      retries: 120
  phpmyadmin:
    # build: .
    image: phpmyadmin/phpmyadmin
    container_name: dev_pma
    networks:
      - mynetwork
    environment:
      PMA_HOST: dbcontainer
      PMA_PORT: 3307
      PMA_ARBITRARY: 1
    restart: always
    ports:
      - 8183:80
  server:
    container_name: server
    build:
      context: ./BE
      dockerfile: ./Dockerfile.prod
    networks:
      - mynetwork
    ports:
      - 4000:4000
  client:
    container_name: FE
    build:
      context: ./FE
      dockerfile: ./Dockerfile.prod
    networks:
      - mynetwork
    ports:
      - 3000:3000
    environment:
      - CHOKIDAR_USEPOLLING=true
    tty: true
volumes:
  db_data:
networks:
  mynetwork: 

I list my images with docker image ls我用docker image ls列出我的图像

I tag these images and push them to my github repo.我标记这些图像并将它们推送到我的 github 存储库。

Now I create a new docker-compose file for production which refers to my finished images:现在我为生产创建一个新的 docker-compose 文件,它引用我完成的图像:

services:
  mysql:
    build: .
    image: ghcr.io/githubusername/mysql:1
    command:
      - "--default-authentication-plugin=mysql_native_password"
    container_name: dbcontainer
    cap_add:
      - SYS_NICE 
    ports:
      - 3307:3306
    restart: always
    networks:
      - mynetwork
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 1s
      retries: 120
  phpmyadmin:
    build: .
    image: ghcr.io/githubusername/php:1
    container_name: dev_pma
    networks:
      - mynetwork
    environment:
      PMA_HOST: dbcontainer
      PMA_PORT: 3307
      PMA_ARBITRARY: 1
    restart: always
    ports:
      - 8183:80
  server:
    container_name: server
    build: .
    image: ghcr.io/githubusername/server:1
    networks:
      - mynetwork
    ports:
      - 4000:4000
  client:
    build: .
    image: ghcr.io/githubusername/client:1
    container_name: FE
    networks:
      - mynetwork
    ports:
      - 3000:3000
    environment:
      - CHOKIDAR_USEPOLLING=true
    tty: true
volumes:
  db_data:
networks:
  mynetwork:

Now this is basically where the magic happened:现在这基本上就是魔法发生的地方:

Once inside of DigitalOcean droplet I created a docker-compose file by nano docker.compose.yml一旦进入 DigitalOcean 液滴,我通过nano docker.compose.yml创建了一个 docker-compose 文件

I add the contents of the production file inside and on the droplet I run docker-compose up我将生产文件的内容添加到运行docker-compose up的 Droplet 中

Now I can not say how optimal all of this is at this moment more than you should not show your enviorment variables directly in the docker-compose file but It works.现在我不能说此时所有这些是多么优化,而不是你不应该直接在 docker-compose 文件中显示你的环境变量,但它有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM