Saya mempunyai aplikasi NestJS yang ingin saya dok. Saya baru berlabuh dan saya perlu melakukan ini. Dalam aplikasi NestJS saya, saya menggunakan pangkalan data mysql dengan Typeorm. Mysql ini sendiri berasal dari imej docker, iaitu mysql tidak dipasang pada komputer saya.
Saya mempunyai fail docker-compose.yml ini:
# 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:
Saya boleh menjalankan docker-compose up -d dan menggunakan pangkalan data pada komputer saya. Sekarang, saya juga mempunyai Dockerfle yang saya cuba tulis.
Saya telah mengubah banyak perkara dalam tempoh 5 jam yang lalu atau lebih, tetapi secara ringkasnya, ia adalah seperti ini:
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"]
Apa yang saya cuba lakukan dalam Docekerfile di atas ialah mencipta imej ubuntu pada mesin hos dan pasang curl, nod dan mysql masing-masing supaya aplikasi boleh digunakan dengan mysql. Saya boleh membina imej ini melalui docker build -t my-app.
Kemudian saya menjalankan image docker run my-app dan mendapat ralat berikut:
[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)
Saya tidak tahu bagaimana untuk menangani masalah ini.
Untuk rujukan, berikut ialah fail app.module.ts saya
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(); } }
Apa yang berlaku dengan ralat ini? Bagaimanakah saya boleh menyelesaikan masalah ini? Terima kasih atas semua bantuan.
Sola
EDIT: Sekarang saya rasa saya mempunyai sedikit pemahaman tentang masalah ini, jadi saya cuba menulis fail docker-compose-yml yang akan melancarkan kedua-dua apl NestJS dan imej mysql saya. Mula-mula saya menukar fail docker kepada =>
# 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" ]
Kemudian saya menulis fail docker-compose.yml ini =>
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
Sekarang apabila saya menjalankan sudo docker-compose pada bash (tanpa sudo ia memberikan kebenaran dinafikan ralat) saya mendapat ralat berikut
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)
Setahu saya, ia tidak boleh menyambung ke pangkalan data. Apa yang saya buat salah? Bagaimanakah saya boleh menyelesaikan masalah ini?
Sunting 2: Berdasarkan komen, saya membuat beberapa lagi perubahan. Ini adalah penemuan saya:
Nilai DB_HOST nampaknya tidak penting.
# 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:
Saya boleh menukar nilai ini kepada apa sahaja yang saya mahu dan skrip akan dijalankan pada mesin tempatan saya.
Ini ialah fail app.module.ts saya lagi =>
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(); } }
Apabila saya cuba melabuhkan aplikasi ini supaya ia boleh dijalankan pada mesin yang hanya memasang Docker, saya cuba menukar fail docker-compose.yml seperti =>
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
Ini menghasilkan dua gelagat berbeza: Saya tidak lagi boleh menjalankan docker-compose, ia memberikan ralat berikut =>
=> [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
Saya menggunakan terminal Ikan jadi atas sebab tertentu saya perlu menukar kepada bash untuk menjalankan sudo docker-compose yang seterusnya memberikan ralat berikut yang menunjukkan masalah menyambung ke pangkalan data=>
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
Saya betul-betul buntu.
Semua isu telah diselesaikan dengan menukar fail docker-compose.yml seperti yang ditunjukkan di bawah =>
Ini ialah Dockerfile saya =>