NixOS 체험기 - Caddy 설정하기


요약

기존에 nginx에서 설정하던 웹 서버 설정을 NixOS로 이전해봤다.

배경

기존에 조그마한 서비스 몇개를 docker로 구동하고 nginx에서 reverse proxy로 연결해서 서비스하고 있었는데, 이런 서비스들을 이번에 NixOS로 이전해 봤다.

Docker compose 서비스 - 굳이 nix로?

먼저 docker에서 구동하는 서비스들을 nix로 옮겨야 하는데, 굳이 잘 돌아가는 서비스를 nix로 옮길 필요가 있나 싶다. 이미 docker에서 컨테이너로 서비스를 잘 묶어뒀는데 그걸 다시 풀어헤쳐서 nix로 재조립… 하면야 물론 좀 더 작은 이미지를 만들 순 있지만 번거롭다 이거지.

여튼 그냥 docker-compose.yml을 그대로 nix에서 구동할 수 있도록 systemd 설정만 해 줬다.

systemd.services."survived" = {
  enable = true; // 서버 켜질때 같이 돌아가게
  wantedBy = [ "multi-user.target" ]; // 거의 항상 돌아가게
  after = [ "network.target" ]; // 시스템 부팅 중에 인터넷이 이후에 돌아가게
  path = [ pkgs.docker ]; // docker 보이는 환경에서 돌려줘
  serviceConfig = {
    // docker compose 명령이 종료돼도 상관없어
    RemainAfterExit = "yes"; 
    // 서비스 시작은 docker compose up -d
    ExecStart = "${pkgs.docker}/bin/docker compose -f ${srcs.survived}/docker-compose.yml up -d --force-recreate";
    // 서비스 종료할 컨테이너도 삭제해줘 (그래야 다음 실행때 컨테이너 생성 가능)
    ExecStop = "${pkgs.docker}/bin/docker compose -f ${srcs.survived}/docker-compose.yml rm -s";
  };
};

웹 서버 reverse proxy 설정하기

원래는 그냥 Caddy에서 reverse proxy 한줄이면 될 줄 알았는데, Nginx의 CORS 설정을 옮겨야 해서 좀 설정이 길어졌다. 하여튼 이런 모양이다.

"gql.blmarket.net".extraConfig = ''
  @cors_preflight method OPTIONS

  header {
   	Access-Control-Allow-Origin "*"
   	Access-Control-Allow-Methods "GET,POST,OPTIONS"
   	Access-Control-Allow-Headers "Origin,Content-Type,Accept,Authorization"
   	Access-Control-Allow-Credentials "true"
  }

  handle @cors_preflight {
   	header {
   		Access-Control-Max-Age "3600"
   	}
   	respond "" 204
  }

  @auth {
    not method OPTIONS
  }

  basicauth @auth {
    gql $blahblahSuperAwesome/Password:1283172367123 
  }

  reverse_proxy localhost:8181
'';

CORS에 대해 구체적으로 설명하는건 너무 길어지니 패스하고, CORS를 제대로 지원하려면 먼저 OPTIONS 요청(Preflight)에 대해 401 응답을 해선 안되기 때문에 basicauth에서 OPTIONS를 빼고 적용하도록 해 주고, 또 응답도 204 응답을 전용 헤더와 함께 전달하도록 해 주면 된다. 그 외의 요청의 경우 basicauth를 적용하고 적당한 암호를 제공하준 녀석에게만 reverse proxy로 요청을 전달해 준다.

결론

몇년 묵힌 서비스 이전하려니 힘들다