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

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

我有一个实验性应用程序,我在其中处理图像。目标是使用 docker 容器和图像制作一个完整的工作应用程序,我已经设法在我的本地机器上完成了。我遇到的问题是当我将它部署到 digitalocean 时。

来自 node-express-server 我收到此错误响应:

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

我正在使用 docker-撰写文件:

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:

我还在 docker-compose 中使用 docker 文件。相关的是:

mysql Docker文件:

FROM mysql

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

EXPOSE 3306

以上我使用 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

我节点快递中的连接:

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

图片

我 运行 docker-compose up -d --build 得到这个:

我复制了服务器的 imageId,sql 和 php 并为其中的每一个标记了它:

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

并将其推送到 github 个包:

 docker push ghcr.io/userName/imageName:1

数字海洋

我连接到我的 github 帐户并从 github 包中提取图像。

我先 运行 mysql 图像,然后我进入容器以查看我的数据库和用户是否已创建,我可以验证它们是否已创建,因为 Todo 数据库和用户“ produser”是在 digitalOcean 上创建的:

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

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

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

再次在我的机器上一切正常,但是当推送到 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

我哪里做错了?我错过了服务器某处的配置吗? 我 运行 在 ubuntu.

上使用 Docker 19.03.12 创建一个 droplet

我是 docker-compose 的新手,正如我所说,我正在构建它,然后分别标记图像并推送它们,这是否正确?任何指导表示赞赏。

编辑:

不知道这有什么关系,但是当我在 dbcontainer 中时,我检查了一下 mysql 是什么主机 运行ning 并且它是“本地主机”。

使用以下命令对 node-express 执行相同操作:

docker exec -it serverid /bash/sh

然后 hostname 我刚刚取回容器 ID。

编辑 2:

也许要非常清楚这一点: 我 运行 docker-仅在我的本地计算机(我的电脑)上撰写。然后我分别拍摄每张图片并尝试将它们连接到 digitalOceean 上的一个 droplet 上。

我也尝试将我的 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

遗憾的是,此 docker-compose 尝试导致 php 管理员无法工作,而我在本地主机和 Droplet 上都得到了 connection_refused。 数据库和用户仍然在服务器和本地计算机上创建。 nginx 在本地环境上没有 运行 但在 droplet 上 运行。不过不确定在这种情况下它应该做什么。

对于任何尝试回答的人,请给我一步一步的指导。

现在我正在做以下事情:

  1. 运行 docker-根据本地环境编写
  2. 将每个单独的图像推送到 github 个包
  3. 连接到 digitalOcean
  4. 拉取镜像
  5. 运行 特定端口上的每个图像。

我的过程肯定有问题,因为它不起作用。

经过 2 周的尝试,我设法让它旋转起来。

核心问题是我不太明白docker-compose的用法。我最初的想法是,它创建的图像可以单独使用,然后它们会自动 link.

解决方法很简单

我用这个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: 

我用 docker image ls

列出我的图片

我标记这些图像并将它们推送到我的 github 存储库。

现在我创建一个新的 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:

现在这基本上就是魔法发生的地方:

进入 DigitalOcean Droplet 后,我​​通过 nano docker.compose.yml

创建了一个 docker-compose 文件

我在 droplet I 内部和上面添加了生产文件的内容 运行 docker-compose up

现在我不能说此时此刻所有这些有多优化,而不是你不应该直接在 docker-compose 文件中显示你的环境变量,但它有效。