✅ 웹 애플리케이션 (Web Application)
웹 어플리케이션애플리케이션 = 웹에서 동작하는 애플리케이션
-> 일반적으로 웹애플리케이션은 클라이언트와 서버 간의 상호작용을 통해 데이터를 처리하고 화면에 표시하는 방식으로 작동
ex) 네이버, 쿠팡, 인스타그램
✅ 프레임워크 (Framework)
프레임워크 = 앱을 만들려면 이렇게 만들면 돼. 하는 일종의 가이드 혹은 툴.
프레임워크 = 뼈대 또는 틀이라고 생각하면 쉬움.
- 개발자가 필요한 부분만 채우면 쉽게 앱을 만들 수 있도록 도와줌.
프레임워크의 예시:
- Spring (Java)
- Django (Python)
- Flask (Python)
- Express (Node.js)
✅ 웹 애플리케이션 프레임워크 (Web Application Framework)
- 웹 어플리케이션 프레임워크는 웹 애플리케이션을 더 쉽게 만들 수 있도록 돕는 프레임워크임
- 말 그대로 웹 어플리케이션 전용 프레임워크
- 로그인, 세션관리, DB 연결, URL 설계 같은 웹 앱 필수 기능들을 편하게 쓸 수 있도록 만들어진 프레임워크
- 그래서 개발자는 핵심 기능(비즈니스 로직)에만 집중하면 됨.
✅자바에서의 웹 프레임워크
Spring (Java + Tomcat 서버 필요): 가장 유명, 대규모 기업들이 많이 씀
Spring Boot (내장 Tomcat 서버): Spring을 더 쉽게, 더 빠르게 쓸 수 있도록 만든 것
OpenJDK + Tomcat
✅파이썬 웹 프레임워크
FastAPI: 요즘 뜨는 프레임워크, 빠르고 API 서버 만들 때 좋음
Flask: 가볍고 심플, 필요한 기능만 골라 쓰기 좋음
Django: 파이썬 웹 프레임워크의 대표, 자동화 기능 많음, 빠르게 만들 수 있음
소스코드를 앱으로 만들려면?
# java 웹프레임워크인 springboot로 짜인 소스코드가 있다면, maven이나 gradle 같은 빌드툴과 자바가 설치된 상태에서 'build'를 통해 war이나 jar 같은 파일을 만들어내면 됨
# 자바의 경우, 자바의 버전(ex. openjdk-11 같은)과 빌드툴의 버전도 맞춰줘야 함
1. 물리서버(vm,211.183.3.150)에 간단한 springboot 앱을 배포.
root@ubun-tem:/home/user1# vi /etc/netplan/00-installer-config.yaml
root@ubun-tem:~# netplan apply

curl -fsSL https://get.docker.com -o get-docker.sh
root@host:~# chmod +x get-docker.sh
root@host:~#./get-docker.sh
- 소스코드 준비
git clone https://github.com/oolralra/sb_code.git
GitHub - oolralra/sb_code
Contribute to oolralra/sb_code development by creating an account on GitHub.
github.com
-> sb_code라는 디렉터리에 소스코드가 존재


pox.xml: 빌드 방식, 의존성 파일 <정보>
- 자바 설치
root@ubun-tem:~/sb_code# apt install -y openjdk-8-jdk
- 자바 8 설치
- 빌드툴 설치
springboot1.x 버전은 maven 3.x 버전의 빌드툴을 쓰면 된다는 것을 경험을 통해 터득한 상태.

- apt search maven을 통해 어떤 버전의 maven인지 확인 가능
root@ubun-tem:~/sb_code# apt install -y maven
- 설치
- 빌드

- 빌드 전 target 폴더나, jar파일이 존재하지 않음
root@m20:~/sb_code# mvn clean package

- clean: 기존 파일 삭제 후 새 파일 생성
- package: jar

- 패키징 된 앱
- 이 패키징 된 앱을 sprinboot이므로 java가 설치된 환경에서 실행시켜 주면 됨
- 앱 동작
root@m20:~/sb_code# java -jar target/springbootApp.jar
- target폴더에 존재하는 springbootApp.jar 앱을 동작
- 이 앱은 아까 README.md에서 포트가 8085인 걸 확인

- 만약 정보가 없다면, 소스코드를 뒤져서 찾아야 함.
- 이 소스코드를 컨테이너와 해보세요.

오류 /해결 방안

- 8085라는 포트번호가 이미 사용 중이라서 나온 에러였음/ 아까 실수로 두 번 정도 실행시켜서 그랬음 ㅎㅎ

root@host:/compose/fast/vue-fastapi# sudo lsof -i:8085

- 이미지는 다른 포트 번호지만 참고용
- 그래서 /sudo kill -9 PID입력 /을 사용해서 죽여주고

- root에 있는 거 죽여주면 됨
- 다시 실행시키면 됨

이 상태로 유지되고 있어야지만 웹페이지가 유지됨
2. 이 소스코드(앱)를 컨테이너화 해보세요.
위에서 구성한 환경 그대로 실행하겠음
방법 1) 호스트에서 빌드한 다음 app파일을 컨테이너 이미지에 넣어서 실행.
vi Dockerfile
FROM openjdk:8-jdk-alpine
WORKDIR /app
COPY springbootApp.jar app.jar
CMD ["java", "-jar", "app.jar"]
root@m20:~/sb_code/target# docker build -t myapp:3 .
root@m20:~/sb_code/target# docker run -dp 8000:8085 --name myapp myapp:3

강사님의 방법 1)
-> 강사님은 처음부터 하셨음
root@host:~# git clone https://github.com/oolralra/sb_code.git
root@host:~# cd sb_code
root@host:~/sb_code# apt update -y && apt install -y openjdk-8-jdk maven

# 만약 동일한 서버에 버전이 다른 자바가 설치되어 있는 경우.
1. 내가 원하는 자바 버전을 선택
update-alternatives --config java


- 변경된 자바 버전을 확인.
- 아니면 11 버전을 삭제하면 되는데, 잘 안됨
root@host:~/sb_code# mvn clean package
# 빌드


- 도커허브에서 내가 원하는 이미지의 레포를 검색해서 이동.
8-jdk-alpine
alpine: 초경량화 버전
slim: 불필요한 파일을 제거한 경량화 버전
일반: 제일 무거움
vi Dockerfile
FROM openjdk:8-jdk-alpine
WORKDIR /app
COPY target/springbootApp.jar app.jar
CMD ["java","-jar","app.jar"]
root@host:~/sb_code# docker build -t sb:1 .
root@host:~/sb_code# docker run -dp 8086:8085 --name sbapp sb:1
root@host:~/sb_code# docker exec -it sbapp sh
# alpine 버전은 쉘이 bash가 아니라 sh다.
방법 2) 빌드도 컨테이너서 한 후 app을 동작시키는 컨테이너이미지 실행
- 제일 중요한 포인트 -> 빌드하기에 적절한 이미지를 선택
- 소스 코드에 대한 이해가 필요함. = maven3.6과 openjdk-8이 필요한 소스코드임

# 우리의 소스코드를 빌드할 수 있는 컨테이너이미지
root@host:~/sb_code# vi Dockerfile
FROM maven:3.6.3-openjdk-8-slim
WORKDIR /app
COPY . .
# 호스트의 Dockerfile의 위치에 있는 모든 파일이
# 컨테이너 내부의 /app에 복사가 됨.
RUN mvn clean package
# target 폴더에 springbootApp.jar 생성
CMD ["java","-jar","target/springbootApp.jar"]
root@m20:~/sb_code# docker build -t vmim:1 .
root@m20:~/sb_code# docker run -dp 8989:8085 --name app vmim:1

dockerignore
- 컨테이너 이미지 빌드 시 넣지 않고 싶은, 불필요한 파일을 제외시킬 수 있음

root@host:~/sb_code# vi .dockerignore


root@m20:~/sb_code# docker build -t vmim:2 .
- 이미지 빌드 후 컨테이너 실행해서 정말 안 들어갔는지
root@host:~/sb_code# docker run -itp 8989:8085 --name app sbimage:2 bash

방법 1이든, 방법 2든 어쨌든 우리에게 필요한 파일은 앱파일(springbootApp.jar) 임.
nodejs 웹애플리케이션을 배포

git clone https://github.com/earth-space/Node.js-small-project-example
root@host:~# mv Node.js-small-project-example/ node

- 사용하는 포트(=접속할 포트) : 3000이고,
- :27017 이 mongodb 포트 번호임
1. 몽고디비 컨테이너를 띄울 예정
root@host:~# docker run -dp 27017:27017 --name mongo mongo:latest

root@host:~# docker exec -it mongo mongosh
- 몽고디비는 mongosh라는 쉘을 쓰므로 접속이 되는지 여부만 체크.
- 잘 동작중인걸 확인

- 나중에 앱을 연동을 시키면 아마 node라는 db가 생성될 것

root@m20:~/node# apt update -y && apt install -y nodejs npm
-> nodejs와 npm(node package manager ) 개발 환경 구성
root@m20:~/node# npm install express
- 의존성 패키지 설치
-> 의존성 패키지란?
-> 어떤 소프트웨어나 애플리케이션이 실행되기 위해 필요한 외부 라이브러리나 패키지를 말함. 즉, 자기 자신만으로는 동작하지 않거나, 기능을 구현하기 위해 다른 라이브러리나 모듈에 의존하는 경우 그 라이브러리들이 의존성이 됨
-> 위에 express 패키지는 애플리케이션이 웹 서버를 만들 수 있도록 도와주는 기능을 제공하며, 애플리케이션의 의존성이 됨.

- 의존성 패키지 목록
root@host:~/node# npm install
- 패키지 설치
root@m20:~/node# node app.js
- app.js에서 동작



- 수정할 소스코드 파일을 찾아야 함.
root@host:~/node# vi views/home.ejs
- 소스코드가 있는 주소로 번경

root@m20:~/node# vi app.js
- app.js 파일의 mongodb주소도 수정


- chat이 잘 작동하는지 확인

- 채팅서버가 mogodb를 사용하므로 잘 동작하면 몽고디비와 연동도 잘 됐음을 확인 가능함.
오류 /해결 방안


실습) nodejs앱을 컨테이너화 해보세요.
-p 3000-3001:3000-3001
# publish 포트를 범위로 지정.
-p 3000:3000 -p 3001:3001
# publish 포트를 두 번 명시
views/home.ejs 에서 컨테이너주소를 적어도 찾아갈 수 있게 만들 수 있는 분은 만들어서 ㅂㅊㅁ 강사님한테 알려주세요.
vi app.js

root@m20:~/node# docker run -d --name mongo2 mongo:latest
# 외부로 publish 하지 않고 띄우자.
root@host:~/node# vi views/home.ejs

- 내부끼리 통신을 할 때는 내부주소로 찾아가는 게 좋긴 하지만, 이 앱 자체가 그렇게 만들어져 있지 않기 때문에, 어쩔 수 없이 앱 내부에서 통신을 할 때도 외부 주소를 명시해야 쓸 수밖에 없음

root@host:~/node# vi .dockerignore
-> 설치된 패키지를 넣는 게 아니라, 소스코드 package *.json파일의 설치목록을 통해 컨테이너 내부에 패키지를 설치할 것 이기 때문에 node_modules를 제외시켜 주자

- 컨테이너이미지를 찾기 위해 node.js의 버전을 확인
- node 레포에서 10.19 태그로 검색


vi Dockerfile
FROM node:10.19-slim
WORKDIR /app
COPY package*.json .
# 일단은 설치할 패키지목록만 복사
RUN npm install
# 패키지 설치
COPY . .
# 소스코드 복사
CMD ["node","app.js"]

- Dockerfile에서 굳이 패키지 목록을 미리 복사해서 설치하고 난 다음에 소스코드를 복사하는 이유
-> 도커파일을 잘 만들면 빌드했을 때 유용하다?
-> 레이어를 잘 나누면 시간을 세이브할 수 있음

root@m20:~/node# docker build -t node:1 .
root@host:~/node# docker run -dp 3000-3001:3000-3001 --link mongo --name node2 node:1
오류 /해결 방안

- 이런 오류가 생겼을 때 해결 방안은 디스크 용량 부족 이슈다!
- 그래서 용량을 확장시켜 주면 됨
- 용량 확장 방법은 밑에 블로그 확인 부탁 dream
디스크 용량 확장/ mysql 컨테이너 생성/--link 옵션/ 사설저장소(private registry)
우분투에서 디스크 용량 확장더보기root@host:~# pvcreate /dev/sdb1root@host:~# vgextend ubuntu-vg /dev/sdb1root@host:~# lvextend -l +100%FREE -n /dev/mapper/ubuntu--vg-ubuntu--lvroot@host:~# resize2fs /dev/mapper/ubuntu--vg-ubuntu--lv - 늘
yunz-story.tistory.com
파이썬 플라스크 앱 배포
git clone https://github.com/oolralra/smart

실습) 이 앱을 컨테이너 화하고 사설저장소에 push 해서 테스트해 보세요!!
파이썬 버전 3.9
pip install -r requirements.txt
# 패키지 설치.
gunicorn -b 0.0.0.0:8080 main:app
# 앱을 실행하는 명령어. 모든 대역에 오픈.( -b 0.0.0.0:8080 )
풀이)
1. 이미지 선택
2. requirements.txt 복사
3. pip install
4. 소스코드 복사
5. 실행

root@host:~/smart# vi Dockerfile
root@host:~/smart# cat Dockerfile
FROM python:3.9.21-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn","-b","0.0.0.0:8080","main:app"]
# 0.0.0.0 = 0.0.0.0/0

root@host:~/smart# docker build -t smart:2 .
root@host:~/smart# docker run -dp 8089:8080 --name myflask smart:2

오류 /해결 방안
vi Dokerfile을 했을 때 아래와 같은 오류창이 뜬다면?
E325: ATTENTION Found a swap file by the name ".Dockerfile.swp" owned by: root dated: Fri Mar 21 05:05:08 2025 [cannot be read] While opening file "Dockerfile" dated: Fri Mar 21 05:07:59 2025 NEWER than swap file! (1) Another program may be editing the same file. If this is the case, be careful not to end up with two different instances of the same file when making changes. Quit, or continue with caution. (2) An edit session for this file crashed. If this is the case, use ":recover" or "vim -r Dockerfile" to recover the changes (see ":help recovery"). If you did this already, delete the swap file ".Dockerfile.swp" to avoid this message.
root@m20:~/smart# rm .Dockerfile.swp
이거 입력해 주면 됨
멀티스테이지 빌드

root@host:~# mkdir multi
root@host:~# cp -r sb_code multi
root@host:~# cd multu/sb_code
root@m20:~/multi/sb_code# vi Docekrfile
FROM maven:3.6.3-openjdk-8-slim AS builder
WORKDIR /app
COPY . .
# 호스트의 Dockerfile의 위치에 있는 모든 파일이
# 컨테이너 내부의 /app에 복사가 됨.
RUN mvn clean package
# target 폴더에 springbootApp.jar 생성
# 여기부터 다음 스테이지
FROM openjdk:8-alpine
WORKDIR /app
COPY --from=builder /app/target/springbootApp.jar app.jar
CMD ["java","-jar","app.jar"]

root@host:~/multi/sb_code# docker build -t msb:1 .
root@host:~/multi/sb_code# docker run -dp 8085:8085 --name mtest msb:1

실습) 첫 번째 스테이지를 ubuntu:latest 로 하여, 호스트에 존재하는 간단한 source-code.txt 파일을 넣은 후, 이 파일의 이름을 index.html바꿔서 nginx:alpine를 기반으로 하는 다음 스테이지에 넣어서 배포해 보세요.
root@host:~/multi/sb_code# cd ..
root@host:~/multi# mkdir mginx
root@host:~/multi# cd mginx/
root@host:~/multi/mginx# echo multi-test > source-code.txt
root@host:~/multi/mginx# vi Dockerfile
FROM ubuntu:latest AS build
# AS 뒤에 오는 컨테이너의 이름은 내가 맘대로 정하면 된다.
WORKDIR /app
COPY source-code.txt source-code.txt
RUN mv source-code.txt index.html
FROM nginx:alpine
COPY --from=build /app /usr/share/nginx/html

root@m20:~/multi/mginx# docker build -t mginx:1 .
root@host:~/multi/mginx# docker run -dp 7979:80 --name mginx mginx:1

# 잘 된다.
VUEJS로 만든 프론트엔드 멀티스테이지 빌드
nodejs 기반으로 만들어진 프론트엔드
- vue
- 리액트
- svelte
소스코드 -> npm run build -> 정적인 파일 생성 html, css 같은 파일들을 말함
소스코드 = nodejs 개발 환경이 필요
정적인 파일 = nginx나 httpd 같은 웹서버에서 배포 가능
root@host:~/multi/mginx# cd ..
root@host:~/multi# git clone https://github.com/oolralra/vue-fastapi.git
root@host:~/multi# cd vue-fastapi
1. 프론트엔드
root@host:~/multi/vue-fastapi/frontend# vi Dockerfile

root@host:~/multi/vue-fastapi/frontend# docker build -t vue:1 .
root@host:~/multi/vue-fastapi/frontend# docker run -dp 5656:80 --name web vue:1

fastapi: 벡엔드에 있는 데이터를 가져와서 그걸 뿌려줘
nginx가 와서 뿌려줌

2. 백엔드
root@host:~/multi/vue-fastapi/frontend# cd ..
root@host:~/multi/vue-fastapi# cd backend/
root@host:~/multi/vue-fastapi/backend# vi Dockerfile

root@host:~/multi/vue-fastapi/backend# docker build -t back:1 .
root@host:~/multi/vue-fastapi/backend# docker run -dp 8000:8000 --name backend back:1

# 간단한 데이터가 들어가 있다.
다시 프론트엔드로 돌아가서 소스코드들을 보자
root@host:~/multi/vue-fastapi/backend# cd ..
root@host:~/multi/vue-fastapi# cd frontend/
root@host:~/multi/vue-fastapi/frontend# vi default.conf
# 리버스 프록시 파일 내용.

root@host:~/multi/vue-fastapi/frontend# vi src/components/Products.vue


# Dockerfile의 22번째줄에 주석해제하고 잘못된 부분을 수정.
# /app/default.conf가 두 번 들어가 있었음.
root@host:~/multi/vue-fastapi/frontend# docker build -t front:1 .
root@host:~/multi/vue-fastapi/frontend# docker run -dp 80:80 --name web --link backend front:1
오류/ 해결 방안
ss -tnlp
- nginx 때문에 80번 포트 실행이 잘 안 되는 걸 확인할 수 있음
- 그래서 다른 걸 실행시켜 주기 위해서 다른 80번 포트를 닫아주고 다른 포트를 열어 주면 됨
systemctl stop nginx


실습) 백엔드는 그대로 두고, 프론트엔드를 node:16 단일스테이지로 띄워서 백엔드와 연동해 보세요! 프론트엔드앱이 사용하는 포트는 8080입니다.
node에서 vue앱을 동작시키기 위한 명령은 npm run serve입니다.
방법 1) 리버스프록시를 안 쓰는 방법
vi src/components/Products.vue
에서 브라우저가 찾아갈 수 있는 주소를 적어준다.

방법2)
리버스프록시를 구성해 준다. = 안 하셔도 됩니다
하는 방법 = vue.config.js에서 만들어주면 됩니다.
const { defineConfig } = require('@vue/cli-service');
module.exports = defineConfig({
transpileDependencies: true,
devServer: {
proxy: {
'/api': {
target: 'http://backend:8000', // 백엔드 컨테이너로 요청 전달
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
}
}
});

# 리버스프록시가 되어있으면 프론트엔드를 통해 백엔드를 찾아갈 수 있지만, 리버스프록시가 안되어있으면 브라우저가 직접 백엔드를 찾아가야 한다.(방법 1 - 직접 찾아가는 것)
'AWS Cloud School 8기 > 도커(docker)' 카테고리의 다른 글
디스크 용량 확장/ mysql 컨테이너 생성/--link 옵션/ 사설저장소(private registry) (1) | 2025.04.02 |
---|---|
Docker Swarm (1) | 2025.04.01 |
docker compose/ 자동 재시작 스크립트/ 2번 기본 vim 편집기 (0) | 2025.03.30 |
도커이미지(Docker Image)/ FROM/ WORKDIR/ COPY/ RUN/ CMD/ EXPOSE/ ENV/ Dockerfile (4) | 2025.03.19 |
컨테이너 가상화 (6) | 2025.03.18 |