참고자료
Developing inside a Container using Visual Studio Code Remote Development
Developing inside a Container using Visual Studio Code Remote Development
code.visualstudio.com
03. Nginx 기초 사용법 정리 1 (conf, directives)
nginx의 매우 기본적인 부분에 대해서 정리한다. 이 전에 문서를 보고 번역 & 정리해 놓은 자료를 다시 한 번 정리한다. 'nginx를 사용할 줄 안다' 함은 결국 'conf 파일을 설정/이해할 줄 안다'로 귀결
aimaster.tistory.com
velog
velog.io
enable cross-origin resource sharing
Contribute The content on this site stays fresh thanks to help from users like you! If you have suggestions or would like to contribute, fork us on GitHub.
enable-cors.org
Docker Compose 를 이용해 Spring Boot + MySQL 서비스 구축 (기초)
이 글은 개인적으로 공부를 목적으로 여러 블로그, 문서를 참조하며 작성하여 부정확하거나 내용이 부실할 수 있는점 양해드리며 잘못된 부분이 있다면 댓글로 알려주시면 감사하겠습니다 :)
do-study.tistory.com
velog
velog.io
과정
cors 설정을 하고, Cookie는 정상적으로 전송이 잘 되었다.
다른 Host에서 session을 사용할 때, 보안 이슈로 풀리는 상황이 발생하였다.
내가 떠오른 선택지는 2가지 이다.
- JWT로 인증방식을 바꾼다.
- 동일한 Host로 묶는다.
JWT로 가는게 장기적으로는 맞는 선택이라고 생각하지만,
지금 시간이 없어서 동일한 Host로 해결하는 방식으로 결정했다.
동일 Host에 정적 프론트 파일과, WAS(spring)를 올려야 한다라는 생각이 드니 떠오르는게 있다.
Nginx를 이용하여 현재 문제를 해결 해 보도록 하자.
docker-image를 사용할 것이므로, 일단 세팅부터 하러 간다.
Container 주도 개발
필자는 개발을 주로 docker에서 한다.
local 환경이 어질러지는 것도 싫고, 배포시에 골치아플까봐 처음부터 docker에서 하는 편이다.
flutter로 web개발을 할 때도,
bind-mount & vscode : dev-container extension을 이용하여 주로 개발한다.
Local 환경에는 코드파일만 두고, 환경의 책임은 Container한테 다 때려박는걸 좋아하기 때문이다.
docker run -itd \
--name dev_front \
-p 8082:8080 \
--mount type=bind,source="$(pwd)",target=/app \
beat_front
위의 명령어로 실행해서, WS를 위한 포트를 개방한다.
그리고 mount를 통해 local의 코드를 공유하는 container를 실행한다.
그리고 vs-code의 extension을 통해, 동작하는 container에 연결하여 작업을 한다.
Container 여러개로 작업을 하다보면
해당 프로젝트를 간략하게 그리면 다음과 같은 그림이 된다.
의존성이 있음을 알 수 있다.
Nginx가 돌려면 -> Spring이 돌고 있어야 한다
Spring이 돌려면 -> MySQL이 돌고 있어야 한다.
Docker-container간의 의존성 문제와, 통신 관리를
Docker-compose를 통해 쉽게 해결할 수 있다.
version: '3'
services:
web:
container_name: nginx
image: nginx
ports:
- "80:80"
volumes:
- ./nginx/conf.d:/etc/nginx/conf.d
depends_on:
- application
networks:
- inner_network
database:
container_name: mysql
image: mysql:8.0
environment:
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_ROOT_HOST: ${MYSQL_ROOT_HOST}
TZ: Asia/Seoul
restart: unless-stopped
ports:
- "3306:3306"
volumes:
- /mysql/conf.d:/etc/mysql/conf.d
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
command:
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
networks:
- inner_network
application:
container_name: spring
restart: on-failure
build:
context: ./
dockerfile: Dockerfile
depends_on:
- database
environment:
SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/beat?useSSL=false&allowPublicKeyRetrieval=true
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: 1234
ports:
- "8080:8080"
networks:
- inner_network
networks:
inner_network:
서비스 들을 구성한다.
난 3개의 서비스를 사용한다. Nginx, Spring, MySQL
그리고 각 서비스는 image를 가지고, 추가적인 설정을 가진다.
추가적인 설정에서 networks, ports, depends_on을 설정하여 목적을 달성할 수 있다.
depends_on 옵션으로 의존 순서대로 container를 자동으로 생성해주어
순서를 신경 써가며 일일히 Container를 실행시킬 필요가 없다.
Nginx로 같은 host에서 운영하기
같은 host에서만 Session이 유지 되는걸 확인해서, Nginx를 도입하기로 했었다.
그림을 그려보면 다음과 같이 될 것이다.
이제 Nginx의 Setting을 간단하게 해보면 다음과 같다.
server {
listen 80;
access_log off;
root /opt/build/web;
location / {
try_files $uri $uri/ =404;
}
location /api {
add_header 'Access-Control-Allow-Origin' 'https://time-traveler.site' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT' always;
add_header 'Access-Control-Allow-Headers' 'Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://application:8080;
proxy_set_header Host application:8080;
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;
}
location /oauth {
add_header 'Access-Control-Allow-Origin' 'https://time-traveler.site' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE, PUT' always;
add_header 'Access-Control-Allow-Headers' 'Origin,Accept,X-Requested-With,Content-Type,Access-Control-Request-Method,Access-Control-Request-Headers,Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain charset=UTF-8';
add_header 'Content-Length' 0;
return 204;
}
proxy_pass http://application:8080;
proxy_set_header Host application:8080;
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;
}
}
/의 요청이 들어오면 정적 파일로 보내버리고,
다른 요청들은 Spring으로 보내버리도록 설정 했다.
Nginx를 통해 다시 실행 해 보면?
로그인을 하고 내 정보를 조회하는 Api가 정상동작 한다. Session을 지켜냈다..!
피드백
이전에는 다 JWT쓰니까~ 하면서 사용을 했다.
이번에는 Spring-security에서 제공하는 Session을 활용해서 편하게 해볼까 라는 생각에 시작 했었는데.
직접 겪어보니, host와 같은 설정들에 대해서 유연함이 좋기 때문이라는 것을 많이 느꼈다.
기술은 그냥 가져다 쓰는다고 끝이 아니라,
왜 탄생 했으며, 어떤 architect를 가지는 지도 공유를 해야한다는 것을 다시 배웠다.
'프로젝트 > Beatn-beat [비튼 - 비트]' 카테고리의 다른 글
14. EC2 + Route53 배포 (0) | 2024.02.17 |
---|---|
13. S3 bucket에 Image 위임하기 (0) | 2024.02.15 |
11. 인증과의 전쟁 (0) | 2024.02.12 |
10. Spring-boot와 OAuth2.0 (0) | 2024.02.11 |
9. Flutter web CI/CD 적용 (0) | 2024.02.08 |