으어어... 오타와의 싸움
챗지피티에게 진작에 물어봤어야 했다.
오늘의 교훈: 오타를 조심하고 챗지피티의 답변을 열심히 읽자.
docker-compose를 사용하여 nginx에서 api 서버를 포워딩해주려 한다.
도메인 주소로 http 요청이 들어오면 nginx가 리버스 프록시 역할을 하여
/api가 붙은 요청은 api 서버로, /로 오는 요청은 프론트엔드 서버로 포워딩해준다.
토이 프로젝트라서 하나의 호스트에서 백엔드, 프론트엔드, DB까지 실행시킬 예정이라 nginx를 로드밸런서로 사용하여 request별 포워딩을 진행한다.
이 경우 으악 여기 써야 하는데
아직 프론트엔드 서버는 준비가 안돼서 api 서버만 먼저 작업한다. docker-compose를 사용하여 nginx 이미지와 내가 빌드한 spring 이미지를 사용할 것이다.
프로젝트 루트에 docker-compose.yaml을 만든다.
version: '1'
services:
nginx:
image: nginx:1.21.5-alpine
ports:
- 80:80
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf # 여기서 오타나서 굉장히 삽질함ㅠ
- ./error.log:/var/log/nginx/error.log
container_name: service-proxy
depends_on:
- api
api:
image: [빌드한 api 서버 이미지명]
ports:
- 8080:8080
container_name: service-api
먼저 services 하단에 사용하게 될 2개의 서비스를 등록한다. : nginx와 api
image에는 사용할 이미지 이름을 적으면 된다. api의 경우 Dockerfile을 사용해서 이미지를 직접 빌드한 걸 사용하고 있다.
nginx의 경우 로컬에서 혹은 직접 작성한 nginx.conf를 docker에 반영시키기 위해 volumes를 사용하였다. docker-compose.yaml과 동일한 위치에 nginx.conf를 생성한 후 nginx 컨테이너 안에서 nginx.conf와 맵핑시켰다. 그 아래 로그도 마찬가지.
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-upstream;
upstream service-api {
server api:8080;
}
server {
listen 80;
server_name localhost; # 로컬에서 띄우느라 일단 localhost로 설정. 추후에 도메인 주소로 변경한다.
location /api {
proxy_pass http://service-api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
다른 설정들은 복붙해왔고 직접 설정해주어야 하는 부분은 http 안에 upstream과 server 이다. 여기도 써야함
실행시키는 방법은 매우 간단하다. docker-compose.yaml이 있는 폴더에서 아래 명령어를 실행하면 된다.
docker-compose up
종료하고 싶으면
docker-compose down
하면 된다. 종료하고 컨테이너를 지워주기까지 한다. 매우 편함
원래 계속
2023/04/28 16:05:26 [error] 33#33: *1 open() "/usr/share/nginx/html/api" failed (2: No such file or directory), client: 192.168.32.1, server: localhost, request: "GET /api HTTP/1.1", host: "localhost"
2023/04/28 16:05:27 [error] 33#33: *1 open() "/usr/share/nginx/html/api/time" failed (2: No such file or directory), client: 192.168.32.1, server: localhost, request: "GET /api/time HTTP/1.1", host: "localhost"
2023/04/28 16:05:27 [error] 33#33: *1 open() "/usr/share/nginx/html/api/time" failed (2: No such file or directory), client: 192.168.32.1, server: localhost, request: "GET /api/time HTTP/1.1", host: "localhost"
이런 오류가 발생했었다. (추가2 적용 전)
nginx container에 들어가서 api 서버와 통신이 되는지 시도했다.
Docker Desktop이 깔려있어서 간단하게 접근했는데 만약 터미널에서 nginx container로 접근하고 싶다면
docker exec -it service-proxy /bin/sh # 원래는 docker exec -it [컨테이너 이름] bash하면 되는데 오류남;
하면 된다.
이제 컨테이너에서 api 서버와 통신이 되는지 확인한다.
curl http://api:8080/api
이미 여기서 안되고 있었다. 원인은 빌드를 안하고 이미지를 만들어서 수정사항 변경이 안됐던것... 빌드를 잘하자
수정했더니 nginx -> api로의 접근은 됐지만 여전히 같은 오류가 발생했다.
nginx container에 다시 접속해서
맵핑시켰던 /etc/nginx/nginx.conf 파일을 확인했다. 그랬더니 내가 작성한 nginx.conf가 반영이 안되어 있었다.
docker-compose.yaml을 다시 보니 오타가 있었다ㅠㅠ(/etc/ngix/nginx.conf로 되어있었따...)
수정했더니 정상작동한다.
참고 글의 댓글을 참고했다.
원래는 api 서버로 직접 접근이 가능했다.
nginx를 통해서만 접근하도록 수정했다.
api:
image: [
expose: # ports -> export로 변경한다.
- 8080:8080
container_name: service-api
이제 직접 접근은 불가하다.