package.json: 프로젝트 정보 & 패키지 & 의존성 관리
server.js: 시작점으로 가장 먼저 시작되는 파일
[1] 실습
[2] dockerfile 작성하기
nodejs를 도커 환경에서 실행하려면...
dockerfile 작성 -> 이미지 생성 -> 이미지를 이용해 컨테이너 실행 -> 컨테이너 안에서 nodejs 앱 실행
Q) 저번에는 FROM alpine했는데 왜 이번에는 FROM node:10 인가요?
A) FROM alpine하면 npm not found 에러가 뜬다. 즉 alpine은 경량화된 파일이므로 npm을 위한 파일이 없어서 실행이 불가하다.
npm이 들어있는 베이스 이미지 중 하나가 node 이미지이다.
Q) RUN npm install이 뭔가요?
A) npm은 nodejs로 만들어진 모듈을 웹에서 받아서 설치하고 관리하는 프로그램이다
npm install로 package.json에 적혀있는 종속성들을 웹에서 자동으로 다운받아서 설치해준다.
즉) nodejs앱을 만들 때 필요한 모듈들을 다운받아 설치하는 역할임!
[3] 이미지를 빌드할 때 package.json이 없다고 나오는 이유
실행 과정)
node 이미지를 컨테이너에 넣음 -> npm install할때 package.json이 없다고 나온다.
왜?) package.json이 컨테이너 안에 없고 컨테이너 밖에 있어서 찾을 수 없다고 나온다.
해결) COPY pakckage*.json ./으로 컨테이너 안으로 넣어준다.
FROM node:10
COPY package.json ./
RUN npm install
CMD ["node", "server.js"] 이렇게 실행해주고
docker build -t jangmj80/nodejs ./ 해줘서 build한다.
이후에 docker run jangmj80/nodejs:latest 이렇게 하면 error가 난다 (server.js를 찾을 수 없다는..)
이유) server.js도 컨테이너 밖에 있기 때문에 컨테이너 안에서 찾을 수 없다고 나온다.
해결) FROM node:10
COPY ./ ./. <--- 처럼 이렇게 바꾼다.
RUN npm install
CMD ["node", "server.js"]
[3-1] 콘솔로 서버가 동작하는지 확인
server.js에 console.log("server is running !") 추가하기 !
이후에 다시 docker run jangmj80/nodejs:latest 해주기
[4] 생성한 이미지로 어플리케이션 실행 시 접근이 안 되는 이유
문제) localhost:8080 했는데 run이 안된다.
그동안: docker run 이미지 이름
앞으로: docker run -p 49160:8080 이미지 이름
이미지를 만들 때 로컬에 있는 파일을 컨테이너에 복사해준 것처럼
네트워크도 로컬 네트워크에 있던 것을 컨테이너 내부에 있는 네트워크에 연결해줘야 한다.
49160: 브라우저(localhost)
8080: 컨테이너 안의 port
49160대신 5001을 사용함 -> 명령어: docker run -p 5001:8080 jangmj80/nodejs
[5] working directory 명시해주기
WORKDIR: 이미지 안에서 어플리케이션 소스 코드를 갖고 있을 디렉토리를 생성하는 것
이 디렉토리가 어플리케이션에 working 디렉토리가 된다.
따로 workingdirectory가 있어야 하는 이유)
-docker run -it node ls하면 bin, dev, home, var 등등 root 디렉토리 안에 기본적인 OS 파일들이 있다.
-docker run jangmj80/nodejs ls 하면 Dockerfile, dev, bin, boot, server.js 등등 COPY한 파일들이 나온다
문제1) 카피할 파일들의 이름이 원래 파일 시스템의 이름과 같으면 원래 있던 파일은 없애고 새로운 파일이 덮어진다.
문제2) 정리가 안 된다.
해결) WORKDIR /usr/src/app을 추가한다. -- 도커가 /usr/src/app 폴더 안에서만 작업한다.
docker build -t jangmj80/nodejs ./ 해서 다시 build (Dockerfile을 보고 새로운 컨테이너의 내용을 만들고 저장)
docker run -it jangmj80/nodejs sh 로 shell 환경(컨테이너 안)에 접근한다.
-> /usr/src/app안에는 copy된 파일들만 보이고 Root 디렉토리에 있는 파일들은 안 보임
# cd 하고 #ls하면 리눅스의 기본 폴더(bin, home)도 볼 수 있다.
[6] 어플리케이션 소스 변경으로 다시 빌드하는 것의 문제점
단어) daemon: 백그라운드에서 Docker 컨테이너를 관리하는 프로세스(네트워크 설정, 컨테이너 실행, 포트 바인딩 등을 처리) NCP
-d: detach(백그라운드 실행), 즉 컨테이너를 CL한 다음에 바로 그 터미널에서 빠져나오게 해줌
명령어: docker run -d -p 5001:8080 jangmj80/nodejs
1) 컨테이너의 id만 배출하고 터미널을 차지하기 않고 컨테이너가 실행된 상태를 유지하고 나온다
2) 도커 컨테이너를 백그라운드에서 실행함
3) host(5001) <-> 컨테이너 (8080) 포트 매핑
4) jangmj80/nodejs: 실행할 도커 이미지
실습)
server.js에서
const app = express();
app.get('/',(req,res)=>{
res.send("안녕")
}); 에서 send 부분을 바꾼 걸 바로 반영해보기
-docker ps로 실행중인 container id 찾기
-docker stop <container id>
-docker build -t jangmj80/nodejs ./
-docker run -d -p 4000:8080 jangmj80/nodejs
소스 하나를 변경할 때마다 이미지부터 새로 빌드하는 번거로움 존재
-> COPY ./ ./ 때문에 server.js만 바뀌었는데 모든 종속성들까지 다시 다운받고 이미지를 다시 생성하고 다시 컨테이너를 동작시켜야 함
[6-1] 어플리케이션 소스 변경으로 재빌드 시 효율적으로 하는 법
기존)
- COPY ./ ./로 모든 파일(package.json, server.js, node_modules)을 한번에 복사
- RUN npm install로 의존성을 다운받는데 소스 코드(server.js, app.js)만 바뀌어도 이전 build한 캐시가 날라가고 npm install 재실행됨
변경)
- COPY package.json ./ : package.json만 먼저 복사함 -- npm 패키지(express, axios)는 package.json을 보고 설치하기
Docker는 package.json을 복사하고 이걸 캐시함
- RUN npm install: package.json이 변경되지 않았다면 이 단계는 실행하지 않고 캐시가 재사용됨
- COPY ./ ./: 모든 소스 코드(server.js, app.js) 복사, 소스코드가 변경되어도 캐시 덕분에 npm install이 재실행되지 않음 !
작동)
docker build ./하면 cached된 걸 사용할 수 있게 된다.
[7] Docker Volume -- 이미지를 build하지 않아도 server.js의 코드를 바꾸면 바로 반영되도록
코드를 변경하면 이미지를 다시 빌드해줘야 컨테이너에 복사할 수 있다.
도커 컨테이너에서 로컬에 있는 걸 참조한다.
- node_module: npm install로 컨테이너 안에서 종속성을 다운 받는데 그런 모든 종속성들이 모아져있는 곳
이건 로컬에 없으니까 참조하지 말자는 명령어
- 참조할 부분:
pwd - 현재 작업 중인 디렉터리의 이름을 출력
명령어) docker run -d -p 5001:8080 -v/usr/src/app/node_modules -v $(pwd):/usr/src/app jangmj80/nodejs
'개발 > Docker' 카테고리의 다른 글
[6] 도커로 간단한 앱 배포하기 (0) | 2025.03.10 |
---|---|
[5] Docker Compose (0) | 2025.03.10 |
[3] 도커 이미지 (0) | 2025.03.09 |
[2] 도커 client 명령어 (0) | 2025.03.08 |
[1] 도커 기본 (0) | 2025.03.08 |