이 글은 docker container를 띄운 상태에서 local에 있는 db와 접속하는 방법에 대한 글입니다.
[ 해결 전 상태 ]
NestJS로 서버를 도커 컨테이너에 띄웠는데, 이걸 내 local 컴퓨터 안에 있는 DB에 접속하기 위해 아래처럼 작성 하니, 계속 에러가 발생했습니다.
export const databaseProviders = [
{
provide: 'DATA_SOURCE',
useFactory: async () => {
const dataSource = new DataSource({
type: 'mysql',
host: 'localhost',
port: Number(process.env.DB__PORT),
username: process.env.DB__USER__NAME,
password: process.env.DB__PASSWORD,
database: process.env.DB__DATABASE,
entities: ['dist/**/entities/*.entity.js'],
// entities: [join(__dirname, '**', '*.entity{.ts,.js}')],
synchronize: true,
});
return dataSource.initialize();
},
},
];
에러 메시지는 아래와 같았습니다.
서버를 컨테이너에 띄우지 않고, 로컬에서 실행 시키면 정상적으로 작동하는 것으로 보아, host, port와 같은 DB 정보를 잘못 입력한 문제는 아닌 것으로 확인했습니다.
[ Solution ]
해결책은 간단 했습니다. host 부분을 host.docker.internal 로 바꿔주는것!
host: 'host.docker.internal',
정상적으로 접속이 되는 것을 볼 수 있었습니다.
[ 원인 ]
자, 일단 해결은 했는데 이런 현상은 왜 발생 하는 것일까 고민을 해보니,
docker container내부에서 localhost는 container 자신을 의미하게 되기 때문이었습니다.
docker exec -it [containerID] /bin/sh 명령어를 통해 docker container 접속하고,
vi /etc/hosts 를 통해 아래와 같은 정보를 볼 수 있었습니다.
이는 localhost는 컨테이너를 띄운 컴퓨터를 보고 있는 것이 아니라, docker contaier 내부를 보고 있는 것이고,
따라서 당연히 container내부에는 DB를 같이 띄우지 않았으니, 에러가 발생하는 것 이었습니다.
사실 이 문제를 해결하는 방법은 host.docker.ineternal을 사용하는 방법 외에 하나 더 있습니다.
127.0.0.1이 아닌, 컨테이너를 띄운 컴퓨터의 내부 아이피를 직접 하드코딩 하는 방법입니다.
ipconfig getifaddr en0
mac에서는 위 명령어를 통해, 쉽게 내부 아이피를 찾아 올 수 있습니다.
그리고 이 내부 아이피를 사용하면 정상적으로 DB에 접속 됨을 볼 수 있지만, 이 내부 아이피란 것은 매번 환경에 따라 변경되기 때문에
매우 번거로운 효율적이지 못한 방법이라고 할 수 있습니다.
[ 결론 ]
host.docker.internal을 이용하자!
'Docker' 카테고리의 다른 글
[Docker]docker-compose로 db, 백엔드 컨테이너 연결 (1) | 2023.10.10 |
---|---|
Docker로 Mysql 컨테이너 띄우고 접속 (0) | 2023.09.12 |
[Docker] Docker 설치하기 (특정 버전 docker 설치) (1) | 2022.10.07 |
[Docker - 3] Dockerfile 작성법 (with example) (1) | 2022.09.24 |
[Docker - 2] Container, Image 란 (0) | 2022.09.24 |