搜尋

首頁  >  問答  >  主體

無法在 docker 容器上啟動 mysql 伺服器

我有一個 NestJS 應用程序,我想要對其進行 dockerize。我是docker的新手,我必須這麼做。在我的 NestJS 應用程式中,我使用帶有 Typeorm 的 mysql 資料庫。這個 mysql 本身來自 docker 映像,也就是我的電腦上沒有安裝 mysql。

我有這個 docker-compose.yml 檔案:

# docker-compose.yml

version: '3.3'
services:
  mysql:
    image: mysql:latest
    restart: always
    environment:
      - MYSQL_USER=myuser
      - MYSQL_PASSWORD=mypassword
      - MYSQL_DATABASE=db
      - MYSQL_ROOT_USER=myuser
      - MYSQL_ROOT_PASSWORD=root

    volumes:
      - mysql:/var/lib/mysql
    ports:
      - '3306:3306'

volumes:
  mysql:

我可以運行 docker-compose up -d 並使用我電腦上的資料庫。現在,我還有一個正在嘗試編寫的 Dockerfle。

在過去 5 個小時左右的時間裡我改變了很多事情,但總的來說,它是這樣的:

FROM ubuntu:18.04

# Set the working directory to  /usr/src/app
WORKDIR  /usr/src/app

# Copy the package.json and package-lock.json files into the container
COPY package*.json ./

RUN apt-get update
RUN apt-get -y install curl
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash
RUN apt install -y nodejs

# Install the app dependencies
RUN npm install

# Copy the rest of the app files into the container
COPY . .

# Set environment variables for the MySQL connection
ENV MYSQL_HOST=mysql
ENV MYSQL_USER=myuser
ENV MYSQL_PASSWORD=mypassword
ENV MYSQL_DATABASE=db

# Install the MySQL server
RUN apt-get update -qq && apt-get install -y mysql-server

# Expose the app's port
EXPOSE 3000

# Start the app in development mode
CMD ["npm", "run", "start:dev"]

我在上面的Docekerfile中嘗試做的是在主機上建立一個ubuntu映像並分別安裝curl、node和mysql,以便該應用程式可以與mysql一起使用。 我可以透過 docker build -t my-app 建立此映像。

然後,我執行 image docker run my-app 並收到以下錯誤:

[Nest] 29  - 04/02/2023, 7:37:26 PM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...
Error: connect ECONNREFUSED 127.0.0.1:3306
    at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1494:16)

我不知道如何處理這個問題。

作為參考,這是我的 app.module.ts 檔案

import { Module, OnModuleInit } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module';
import { ArtworksModule } from './artworks/artworks.module';
import { User } from './users/entities/user.entity';
import { Artwork } from './artworks/entities/artwork.entity';
import { AuthModule } from './auth/auth.module';
import { ConfigModule } from '@nestjs/config';
import { SeedService } from './users/seedService/seedService';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'myuser',
      password: 'mypassword',
      database: 'db',
      entities: [User, Artwork],
      synchronize: false,
      autoLoadEntities: true,
      logging: true,
    }),
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    UsersModule,
    ArtworksModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService, SeedService],
})
export class AppModule implements OnModuleInit {
  constructor(private seedService: SeedService) {}

  async onModuleInit() {
    await this.seedService.seedUsers();
  }
}

這個錯誤是怎麼回事?我要怎麼解決這個問題?感謝所有幫助。

乾杯

編輯:現在我想我已經對這個問題有了更多的了解,所以我正在嘗試編寫一個 docker-compose-yml 文件,該文件將同時啟動我的 NestJS 應用程式和 mysql 映像。首先,我將 dockerfile 更改為 =>

# Use the official Node.js 14 image as the base image
FROM node:14

# Create a working directory for the app
WORKDIR /app

# Copy the package.json and package-lock.json files into the container
COPY package*.json ./

# Install app dependencies
RUN npm install

# Copy the rest of the app code into the container
COPY . .

# Expose port 3000 (the port that the app listens on)
EXPOSE 3000

# Specify the command to run when the container starts
CMD [ "npm", "run", "start:prod" ]

然後寫了這個docker-compose.yml檔=>

services:
  app:
    build: .
    command: npm run start:prod
    restart: always
    ports:
      - '3000:3000'
    environment:
      - DB_HOST=mysql
      - DB_PORT=3306
      - DB_USER=myuser
      - DB_PASSWORD=mypassword
      - DB_NAME=db
    depends_on:
      - mysql

  mysql:
    image: mysql:latest
    restart: always
    environment:
      - MYSQL_USER=myuser
      - MYSQL_PASSWORD=mypassword
      - MYSQL_DATABASE=db
      - MYSQL_ROOT_USER=myuser
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - mysql:/var/lib/mysql

volumes:
  mysql:

networks:
  default:
    driver: bridge

現在,當我在 bash 上執行 sudo docker-compose up 時(如果沒有 sudo,它會給出權限被拒絕的錯誤),我收到以下錯誤

my-app-1    | [Nest] 19  - 04/03/2023, 8:28:03 AM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...
my-app-1    | Error: connect ECONNREFUSED 127.0.0.1:3306
my-app-1    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16)
my-app-1    | [Nest] 19  - 04/03/2023, 8:28:06 AM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (2)...
my-app-1    | Error: connect ECONNREFUSED 127.0.0.1:3306
my-app-1    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16)

據我所知,它無法連接到資料庫。我究竟做錯了什麼?我該如何解決這個問題?

編輯2:根據評論,我做了更多修改。這些是我的發現:

DB_HOST 值似乎並不重要。

# docker-compose.yml

version: '3.3'
services:
  mysql:
    image: mysql:latest
    restart: always
    environment:
      - DB_HOST=localhost
      - MYSQL_ROOT_USER=myuser
      - MYSQL_ROOT_PASSWORD=root

    volumes:
      - mysql:/var/lib/mysql
    ports:
      - '3306:3306'

volumes:
  mysql:

我可以將此值更改為我想要的任何值,並且該腳本將在我的本機電腦上運行。

這又是我的 app.module.ts 檔案 =>

import { Module, OnModuleInit } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersModule } from './users/users.module';
import { ArtworksModule } from './artworks/artworks.module';
import { User } from './users/entities/user.entity';
import { Artwork } from './artworks/entities/artwork.entity';
import { AuthModule } from './auth/auth.module';
import { ConfigModule } from '@nestjs/config';
import { SeedService } from './users/seedService/seedService';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: process.env.DB_HOST,
      port: 3306,
      username: 'myuser',
      password: 'mypassword',
      database: 'db',
      entities: [User, Artwork],
      synchronize: false,
      autoLoadEntities: true,
      logging: true,
    }),
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    UsersModule,
    ArtworksModule,
    AuthModule,
  ],
  controllers: [AppController],
  providers: [AppService, SeedService],
})
export class AppModule implements OnModuleInit {
  constructor(private seedService: SeedService) {}

  async onModuleInit() {
    await this.seedService.seedUsers();
  }
}

當我嘗試對這個應用程式進行 dockerize 以便它可以在僅安裝了 Docker 的電腦上運行時,我嘗試更改 docker-compose.yml 文件,例如 =>

version: '3.8'

services:
  app:
    build: .
    command: npm run start:prod
    restart: always
    ports:
      - '3000:3000'
    environment:
      - DB_HOST=localhost
      - DB_PORT=3306

    depends_on:
      - mysql

  mysql:
    image: mysql:latest
    restart: always
    environment:
      - MYSQL_ROOT_USER=myuser
      - MYSQL_ROOT_PASSWORD=root

    volumes:
      - mysql:/var/lib/mysql
    ports:
      - '3306:3306'

volumes:
  mysql:

networks:
  default:
    driver: bridge

這會導致兩個不同的行為:我無法再執行 docker-compose up,它給出以下錯誤 =>

=> [internal] load build definition from Dockerfile                                                           0.0s
 => => transferring dockerfile: 32B                                                                            0.0s
 => [internal] load .dockerignore                                                                              0.0s
 => => transferring context: 34B                                                                               0.0s
 => [internal] load metadata for docker.io/library/node:14                                                     1.4s
 => [1/5] FROM docker.io/library/node:14@sha256:a97048059988c65f974b37dfe25a44327069a0f4f81133624871de0063b98  0.0s
 => ERROR [internal] load build context                                                                        0.1s
 => => transferring context: 402.84kB                                                                          0.0s
------
 > [internal] load build context:
------
failed to solve: error from sender: open /home/sirius/coding/my-app/mysql/#innodb_redo: permission denied

我使用的是Fish 終端,因此出於某種原因,我需要更改為bash 來運行sudo docker-compose up,這又會給出以下錯誤,表明連接到資料庫時出現問題=>

e dependencies initialized +0ms
budapest-icf-recruitment-backend-app-1    | [Nest] 19  - 04/03/2023, 9:26:34 AM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (1)...
budapest-icf-recruitment-backend-app-1    | Error: connect ECONNREFUSED 127.0.0.1:3306
budapest-icf-recruitment-backend-app-1    |     at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16)
budapest-icf-recruitment-backend-app-1    | [Nest] 19  - 04/03/2023, 9:26:37 AM   ERROR [TypeOrmModule] Unable to connect to the database. Retrying (2)...
budapest-icf-recruitment-backend-app-1    | Error: connect ECONN

我真的被困住了。

P粉021854777P粉021854777262 天前2653

全部回覆(1)我來回復

  • P粉541796322

    P粉5417963222024-04-01 12:22:14

    透過更改 docker-compose.yml 檔案解決了所有問題,如下所示 =>

    version: '3.8'
    
    services:
      app:
        image: my-app
        build: .
        volumes:
          - .:/app
        command: npm run start:dev
        restart: always
        ports:
          - '3000:3000'
        environment:
          - DB_HOST=mysql
          - DB_PORT=3306
    
        depends_on:
          - mysql
    
      mysql:
        image: mysql:latest
        restart: always
        environment:
          - MYSQL_ROOT_USER=myuser
          - MYSQL_ROOT_PASSWORD=root
    
        volumes:
          - mysql:/var/lib/mysql
        ports:
          - '3306:3306'
    
    volumes:
      mysql:
    
    networks:
      default:
        driver: bridge

    這是我的 Dockerfile =>

    # Use the official Node.js 14 image as the base image
    FROM node:14
    
    # Create a working directory for the app
    WORKDIR /app
    
    # Copy the package.json and package-lock.json files into the container
    COPY package*.json ./
    
    # Install app dependencies
    RUN npm install
    
    # Copy the rest of the app code into the container
    COPY . .
    
    # Expose port 3000 (the port that the app listens on)
    EXPOSE 3000
    
    # Specify the command to run when the container starts
    CMD [ "npm", "run", "start:dev" ]

    回覆
    0
  • 取消回覆