
<<환경 및 전제 조건>>
backend : Spring Boot(3.5.x) + Spring Data JPA + JDK21
database: MySQL(8.x)
databaseName: cardb
frontend: React(VITE) + nginx(reverse proxy)
[소스코드 준비하기]
...생략
springBoot {
mainClass = 'com.carbackend.CarbackendApplication'
}
bootJar {
archiveFileName = 'app.jar'
}
...생략
spring:
application:
name: carbackend
datasource:
url: jdbc:mysql://localhost:3306/cardb
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
show-sql: true
hibernate:
ddl-auto: create
properties:
hibernate:
dialect: org.hibernate.dialect.MySQL8Dialect
FROM openjdk:21-jdk-slim
COPY build/libs/app.jar app.jar
ENTRYPOINT ["java", "-jar", "/app.jar"]
EXPOSE 8080
VITE_API_URL=/api
# Build stage
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Production stage
FROM nginx:stable-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
worker_processes 1;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri /index.html;
}
location /api/ {
proxy_pass http://backend:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
rewrite ^/api/(.*)$ /$1 break;
}
}
}
/ (루트)나 그 하위 경로일 때 웹서버가 정적 파일을 제공하도록 적용/usr/share/nginx/html 디렉토리를 문서 루트(웹 루트)로 지정/index.html 요청이 들어오면 /usr/share/nginx/html/index.html 파일이 반환/index.html을 대신 반환/api/로 시작하는 URI에만 매칭 (/api 일 경우 /apiSomething 같은 경로도 포함됨)/api/ 경로에 해당하는 요청을 도커 네트워크 내 backend라는 호스트의 8080 포트로 전달(리버스 프록시)/api/ 경로 뒤의 URI 부분을 잘라내어 백엔드로 전달하는 규칙[리눅스 서버 구축]
sudo dnf install -y dnf-utils device-mapper-persistent-data lvm2
sudo dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
sudo usermod -aG docker $USER
dnf-utils : dnf 패키지 관리에 필요한 다양한 유틸리티 패키지 모음-y : 사용자 확인 없이 자동으로 설치 진행device-mapper-persistent-data와 lvm2 : Docker 저장소 사용과 관련된 디스크 및 볼륨 관리 패키지로, Docker 설치와 운용에 필요dnf config-manager를 사용해 Docker 공식 저장소를 repo에 추가(이 저장소를 통해 Docker CE(Community Edition) 패키지를 설치)docker-ce : Docker 엔진(서버) 패키지 설치docker-ce-cli : Docker 명령어 클라이언트 도구 설치containerd.io : Docker 컨테이너 런타임(컨테이너 실행 환경) 패키지systemctl enable : 시스템 부팅 시 자동으로 시작할 서비스 등록$USER)를 docker 그룹에 추가 (-a는 추가, -G는 그룹) → sudo 없이 도커 명령어를 실행sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version
curl 명령어로 Docker Compose의 최신 리눅스 x86_64 바이너리를 GitHub에서 다운로드-L 옵션은 URL이 리다이렉션 될 경우 따라가도록 하는 옵션/usr/local/bin/docker-compose 위치에 저장합니다.sudo dnf install -y git
sudo dnf install -y java-21-openjdk-devel
readlink -f $(which java)
~/
ㄴcompose
ㄴdocker-compose.yml
version: "3.8"
services:
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "80:80"
depends_on:
- backend
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE=prod
SPRING_DATASOURCE_URL: jdbc:mysql://db:3306/cardb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 1234
SPRING_PROFILES_ACTIVE: prod
depends_on:
- db
db:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: 1234
MYSQL_DATABASE: cardb
ports:
- "3306:3306"
volumes:
- mysql-data:/var/lib/mysql
volumes:
mysql-data:
~/compose# git clone <repo url> backend
cd backend
chmod +x ./gradlew
./gradlew clean build
~/compose# git clone <repo url> frontend
docker-compose down
docker-compose up -d --build
docker ps [-a]
docker logs <containerID>
docker exec -it <containerId> <CMD>
[접속 및 테스트]
ip addr
해당 서버의 ip주소 확인 후 http://[hostIP]로 접속