현제의 현재이야기

[DevOps] static 파일 처리기 본문

Infra

[DevOps] static 파일 처리기

현재의 현제 2023. 7. 30. 16:09

admin를 사용하려면 nginx에서 static을 처리해줬어야 했다. 근데 도저히 static 파일을 미리 모아두기 싫었다.

왜냐하면 static file들이 갱신될 수도 있는거고, 그럴 때마다 수동으로 collectstatic을 하면 불편하기 때문.

그래서 처음에는 nginx docker image가 만들어질 때, 같은 폴더의 static 폴더를 복사하도록 dockerfile을 만들었었다.

근데 nginx 폴더에 static 폴더가 있는건 너무 이상.. 그래서 진짜 몇 시간의 뻘짓을 하다가 드디어 성공했다.

 

그건 바로 docker의 volume 기능. 처음에 volume이 그저 host와 마운트 되어서 파일을 공유하는 기능인 줄 알았다.

하지만 volumes를 설정해서 컨테니어간 파일을 공유할 수도 있었다!

version: '3'
services:
  nginx:
    build: ./config/nginx
    ports:
      - "80:80"
    volumes:
      - static_volume:/static
    image: 11thbackend/nginx:latest
    depends_on:
      - web
    platform: linux/amd64
  web:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - static_volume:/project/data/static
    command: ["./start.sh"]
    ports:
      - "8000:8000"
    platform: linux/amd64
    image: 11thbackend/web:latest
    environment:
      - DJANGO_SETTINGS_MODULE=hackathon.settings.prod
    env_file:
      - .env
  redis:
    image: redis:7
    ports:
        - "6379:6379"
volumes:
  static_volume:

저기의 volumes를 통해서 docker volume을 설정해주고, web과 nginx의 volume을 설정해준다.

저 volumes는 호스트 디렉토리:컨테이너 디렉토리로 마운팅 하는 것과 다르게, 저장은 호스트에 되지만 파일을 도커가 관리해주는 일종의 스토리지 같은 것이었다. 그래서 저렇게 만들어진 볼륨을 서로 마운팅하면 파일을 공유할 수 있었다. 이렇게 볼륨을 붙여주고

#!/bin/bash
python manage.py collectstatic --no-input
daphne -b 0.0.0.0 -p 8000 hackathon.asgi:application

실행하기 전에 정적 파일을 모아주면? static_volume에 static 파일들이 모이고 공유할 수 있을거라고 생각했다. 그런데

1차 뻘 짓

local에서는 분명히! nginx 컨테이너의 /static 폴더에 파일이 있었음에도 불구하고 계속해서 static 파일을 불러오지 못했다.

원인은.. 계속해서 http://127.0.0.1:8000 로 들어가고 있었던 것. 도커 환경의 local로 실행하다보니깐 nginx가 돌아감에도 불구하고

계속해서 8000포트로 접속하니깐 당연히 nginx를 통하지 않고 django 내장 서버로 다이렉트로 돌아간 것이다.

 http://127.0.0.1 로 접속하니깐 해결했다. ㅋㅋ; 

upstream web {
  # 클라이언트 IP를 hash 후 특정 클라이언트는 특정 서버로 연결
  ip_hash;
  server web:8000;
}

server {
  # static 파일을 제공해야할 경우
  location /static/ {
    alias /static/;
  }

  # 프록시 설정, nginx 뒤에 WAS가 있을 경우  
  location / {
    proxy_pass http://web/;
  }

  # 포트 설정
  listen 80;
  server_name localhost api.qrtaxi.kro.kr 43.201.20.246;
}

나의 nginx 설정은 /static/으로 들어온 것은 nginx 컨테이너의 static 폴더로 접근한다는 뜻

참고로 upstream을 설정하게 된다면 sever 도메인 1, server 도메인 2 .. 을 설정해서 로드밸런싱이 가능하다고 했다.

나는 그냥 docker의 django 컨테이너 이름으로 설정해서 was는 django로 처리했다.

또한 80포트를 열어서 웹서버의 역할을 하였다. 이제야 nginx에 대해서 조금 알 것 같다..

2차 뻘짓

이제 로컬에서 도커 환경에서도 static 파일이 잘 불러와졌으니 서버로 배포할 일만 남았다.

그럼에도 불구하고 계속 nginx container에서 static 파일들이 404가 떴다.

이번에는 확인해보니깐 django 컨테이너에서는 static 파일들이 잘 모아졌으나, nginx 컨테이너에 static 폴더가 비어있었다!

그래서 볼륨이 생성되지 않았나? 해서

docker-compose volumes
docker <volume이름> inspect
docker <comtaioner 이름> inspect

등등으로 마운트가 되어있지 않나? 볼륨이 생성되지 않았나? 확인을 해보았지만 제대로 있었다. 마운트도 정상적으로 되어있었다.

그렇다면 뭐가 문제였냐?

STATIC_ROOT = os.path.join(BASE_DIR, 'data/static')

이게 문제였는데 저렇게 되면 workdir이 project였기 때문에 /project/data/static 으로 static 파일이 모이게 되었다.

volumes:
      - static_volume:/data/static
-->

volumes:
      - static_volume:/project/data/static

그래서 이렇게 경로를 수정해주니깐 제대로 볼륨에 static 파일이 모이게 되었다.

 

"/" 를 포함하면 최상위 루트를 뜻하며, data/static을 하면 현재의 workdir에서 data/static 경로를 뜻했다.

도커 볼륨은 컨테니어 전체의 디렉토리 루트가 필요하기 떄문에 /project 까지 포함했어야 했다.

참고로 경로 마지막에 붙는 "/"는 디렉토리 임을 명시해주는 것으로, 있으나 없으나 경로는 같다고 한다.

이제 이렇게 잘 불러와진다. 휴

Comments