Skip to main content

정적 파일만 있는 사이트를 어떻게 구동시킬까?

About 2 minPythonFlaskArticle(s)blogyozm.wishket.compythonpy

정적 파일만 있는 사이트를 어떻게 구동시킬까? 관련

Python > Article(s)

Article(s)
Google Cloud > Article(s)

Article(s)

정적 파일만 있는 사이트를 어떻게 구동시킬까? | 요즘IT
개발을 하다 보면 정적(static)인 파일로만 구성된 웹 사이트를 서비스해야 할 때가 있습니다. 정적인 웹 사이트를 생성하고 서비스하는 방법은 여럿 있지만, 저는 주로 파이썬을 활용합니다. 정적 웹 사이트를 Serving하려면 어떻게 해야 할까요? 아쉽지만 개인이라면 정적 웹 사이트를 인터넷에 서빙하는 일은 생각보다 어렵습니다. 다양한 방법 가운데 어떤 방법이 가장 효과적일지는 비용이나 배포 환경 등 제반 여건에 따라 다릅니다. 이 글이 여러분의 선택에 도움이 되기를 바랍니다.

개발을 하다 보면 정적(static)인 파일로만 구성된 웹 사이트를 서비스해야 할 때가 있습니다. 정적인 웹 사이트를 생성하고 서비스하는 방법은 여럿 있지만, 저는 주로 파이썬을 활용합니다. 파이썬에는 정적 웹 사이트를 서비스하는 간단한 모듈이 있습니다. 다음 명령을 내릴 수 있습니다.

python -m http.server

이를 셸에서 실행하면 명령이 실행된 디렉터리를 Document Root로 삼아 HTTP Server가 시작됩니다. 이 웹 서버는 기본적으로 8000 포트로 기동하기 때문에 로컬 컴퓨터에서 정적 웹 사이트를 구성하는 데 도움을 받을 수 있습니다. 물론 웹 서버가 실행되는 포트와 Document Root로 삼을 디렉터리를 명령의 실행 옵션으로 따로 지정할 수도 있습니다.

그럼 이렇게 만들어진 정적 웹 사이트를 Serving하려면 어떻게 해야 할까요? 아쉽지만 개인이라면 정적 웹 사이트를 인터넷에 Serving하는 일은 생각보다 어렵습니다. 그래서 아래 몇 가지 방법을 소개하려고 합니다.


클라우드 플랫폼의 Object Storage 사용하기

클라우드 플랫폼이 제공하는 서비스 중에 파일을 보관하는 Object Storage인 GCP의 Cloud Storage, AWS의 S3, Azure의 Blob Storage 서비스가 있습니다. 해당 서비스들은 저장소 사용량에 따라 비용을 받습니다.

저장소를 이용해 사이트를 Serving하려면 버킷에 파일을 올려놓고 이를 인터넷에 공개하겠다고 설정해야 합니다. 다만 설정이 간단한 것은 아닙니다. 무엇보다 Object Storage의 버킷을 인터넷에 공개하려고 하면 이를 ‘권장하지 않는다’라는 경고 메시지가 발생합니다.


클라우드 플랫폼의 동적 웹 사이트 서비스 사용하기

정적 웹 사이트를 Serving하기 위한 다른 선택지로 동적 웹 사이트를 Serving하는 클라우드 서비스를 활용하는 방법이 있습니다. 인터넷에 검색해 보면, 파이썬 기반 Flask 프레임워크를 사용해 정적 파일만 구성하는 웹 애플리케이션을 만드는 방법을 찾아볼 수 있습니다.

그중 Flask를 사용해 웹 서버를 만들 때는 아래 명령을 활용합니다.

from flask import Flask, send_file, abort

app = Flask(__name__)

@app.route("/", defaults={"links": "index.html"})
@app.route("/<path:links>;")
def main(links):
    if links.endswith("favicon.ico"):
        return abort(404)
    return send_file(</spanf'static/{links}')

이 코드는 static 디렉터리에서 Serving하려는 폴더가 있을 때, Flask 서버로 들어오는 모든 경로를 static 아래에서 찾아 전송하라는 의미입니다.

이는 Google App Engine, AWS Beanstalk, Heroku 등 웹사이트 배포 관련 서비스 모두에서 사용할 수 있습니다. 다만 개별 서비스에서 사용하는 전용 구성 설정을 따라야 합니다.


Github, BitBucket의 Pages 기능 사용하기

GitHub, BitBucket은 버전 관리를 사용하는 VCS 시스템으로 개발자들 사이에서는 널리 사용되고 있습니다. 이러한 VCS 시스템에도 정적 웹 사이트를 서비스하는 기능이 포함되어 있습니다.

GitHub이 제공하는 GitHub Pages, BitBucket이 제공하는 BitBucket Pages 기능이 대표적입니다. 이들이 제공하는 Pages 기능은 무상으로 쓸 수 있으며 최근 정적 웹 사이트 Serving에서 주목받고 있는 Jekyll 등을 쉽게 사용할 수 있습니다.

다만 GitHub의 경우, 저장소의 가시성이 “공개”로 되어 있어야만 Pages 기능을 사용할 수 있다는 단점이 있습니다. 다시 말해 GitHub 저장소가 아무에게나 열려 있어야 한다는 뜻입니다. 게다가 이를 다루려면 git 명령어를 잘 사용할 줄 알아야 합니다.


그래서, 어떤 방법을 사용하면 좋을까?

앞서 여러 방법을 소개했지만, 저는 정적 웹 사이트를 Serving할 때 Google App Engine 사용을 권장합니다. 기본적으로 디스크 용량 1GB를 제공하고 트래픽 등 부분에서도 일정 용량은 매일 무료로 쓸 수 있기 때문입니다.

여러분이 App Engine에서 벗어나지 않을 것이라면, 우선 다음과 같은 디렉터리 구성이 필요합니다.

  • .static_root
    • .www
    • .app.yaml

.app.yaml은 App Engine이 참조하는 파일입니다. app.yaml 파일은 다음과 같이 구성합니다.

runtime: python312

handlers:
- url: /
  static_files: www/index.html
  upload: www/index.html

- url: /(.*)
  static_files: www/\1
  upload: www/(.*)

.app.yaml에는 브라우저가 경로를 요청하면 어떻게 대응할 것인지 지정하는 handlers 설정이 포함되어 있습니다. 앞의 코드는 / URL에 대해서는 www/index.html 파일을 서빙하고, 그 외 모든 요청은 www 디렉터리에서 찾아 보내라고 구성되어 있습니다.

.app.yaml 구성을 마쳤으면 static_root 디렉터리에서 gcloud 명령을 사용하여 이를 App Engine에 업로드하면 됩니다.

gcloud app deploy

만약 여러분이 GCP를 꾸준히 사용한다면, App Engine에서 제공하는 방법만으로도 이를 유용하게 쓸 수 있을 것입니다. 그러나 App Engine을 벗어나 AWS, Heroku로 이동하거나 gzip으로 압축된 정적 콘텐츠가 있다면 이 구성 방법을 사용하기 어렵습니다. 서비스 제공자마다 구성 파일을 달리해야 하는 데다가 gzip 압축은 서비스하지 않기 때문입니다.

static3과 App Engine을 함께 사용하기

이런 한계를 극복하기 위해 static3를 활용할 수 있습니다. static3은 파이썬 코드로 작성된 정적 웹 콘텐츠를 쉽게 서비스하기 위한 라이브러리입니다. 기존에는 파이썬 2로 작성된 static이란 라이브러리가 있었는데, 지금은 유지보수되지 않고 있습니다.

이를 사용하려면 다음과 같은 디렉터리 구성이 필요합니다.

  • .static_root
    • .app.yaml
    • .
    • .requirements.txt
    • .main.py

우리는 여기에서 static3를 사용할 것이므로 requirements.txt에 다음 내용을 입력합니다.

static3

그다음 app.yaml은 다음과 같이 구성합니다.

runtime: python312

마지막으로 main.py는 다음과 같이 구성합니다.

from static import Cling
app = Cling("web")

정적 웹 사이트를 구성하기 위한 준비가 완료되었습니다. 이제 App Engine에 이를 업로드합니다. static_root에서 다음 명령을 입력하면 됩니다.

gcloud app deploy

static3은 기본적으로 브라우저가 / 를 요청하면 web 디렉터리의 index.html을 서비스합니다. 그 외 모든 경우에는 web 디렉터리에서 브라우저로부터 요청받은 경로를 찾아 서비스합니다.

static3은 gzip 압축된 파일도 서비스할 수 있습니다. 따라서 용량이 큰 html 파일은 gzip으로 압축해두면 static3이 알아서 브라우저에 해당 파일을 찾아 보내 줍니다. 앞의 예시대로라면 index.html.gz와 같은 형태가 됩니다.

다른 플랫폼에서도 static3를 사용할 수 있을까?

static3가 제공하는 cling은 기본적으로 WSGI 호환 Wrapper로서 동작합니다. 따라서 동적 웹 사이트를 서비스하는 다양한 플랫폼에서 사용할 수 있습니다.

만약 여러분이 [AWS Beanstalk나 Azure App Service][1]를 사용한다면 main.py 이름을 다음과 같이 바꾸기만 하면 됩니다.

  • AWS Beanstalk: application.py
  • Azure App Service: app.py

다만 app.yaml 등 파일은 클라우드 서비스마다 존재하는 파일이 다를 수 있습니다.


마치며

지금까지 정적 웹 사이트를 서비스하는 다양한 방법을 살펴봤습니다. 여러분은 정적 웹 사이트를 Serving하는 방법이 생각보다 다양하다는 점을 알게 되었을 것입니다.

물론 이들 다양한 방법 가운데 어떤 방법이 가장 효과적일지는 비용이나 배포 환경 등 제반 여건에 따라 다릅니다. 이 글이 여러분의 선택에 도움이 되기를 바랍니다.


이찬희 (MarkiiimarK)
Never Stop Learning.

  1. Azure의 경우, 정적 웹 사이트 호스팅을 위해 Azure Static Web Apps라는 서비스가 따로 존재합니다. ↩︎