{
    "componentChunkName": "component---src-templates-blog-post-js",
    "path": "/18-10-06-flask-gunicorn/",
    "result": {"data":{"site":{"siteMetadata":{"title":"irrationnelle","author":"irrationnelle","siteUrl":"https://dev.rase.blog","comment":{"disqusShortName":"","utterances":"irrationnelle/devlog"},"sponsor":{"buyMeACoffeeId":""}}},"markdownRemark":{"id":"4974e2bf-613f-597f-9336-24e6936152f9","excerpt":"AWS Lightsail AWS Lightsail 과거에는 digitalocean이나 vultr 같은 곳을 저렴한 비용으로 사용했지만, 한국에 리전까지 있고 월 $3.5 로 AWS 의 인프라를 경험할 수 있다는 점에서 Lightsail 을 사용하지 않을 이유가 없다. 막상 사용해보면 기존의 AWS 콘솔을 사용하지 않고 Lightsail 전용 대시보드가 나오기 때문에 AWS…","html":"<h1 id=\"aws-lightsail\" style=\"position:relative;\"><a href=\"#aws-lightsail\" aria-label=\"aws lightsail permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>AWS Lightsail</h1>\n<p><a href=\"https://lightsail.aws.amazon.com\">AWS Lightsail</a></p>\n<p>과거에는 <a href=\"https://www.digitalocean.com/\">digitalocean</a>이나 <a href=\"https://www.vultr.com\">vultr</a> 같은 곳을 저렴한 비용으로 사용했지만, 한국에 리전까지 있고 월 $3.5 로 AWS 의 인프라를 경험할 수 있다는 점에서 Lightsail 을 사용하지 않을 이유가 없다. 막상 사용해보면 기존의 AWS 콘솔을 사용하지 않고 Lightsail 전용 대시보드가 나오기 때문에 AWS 인프라를 사용한다는 장점은 퇴색한 듯 싶지만, 어쨌든 전용 대시보드도 직관적이고 복잡한 설정 없이 딱 필요한 설정만 있어 오히려 더 낫다는 느낌이다. AWS Lambda + AWS Gateway API 같은 UI 에 비하면 정말 편하고 좋다는 느낌.</p>\n<p>현 포스팅을 위한 lightsail 환경은 다음과 같다</p>\n<ul>\n<li>os: Amazon Linux (AMI) 2018.03</li>\n<li>spec: 512MB RAM, 1 vCPU, 20GB SSD</li>\n<li>region: ap-northeast-2a</li>\n<li>stack: 없음. 순정 운영체제</li>\n</ul>\n<p>운영체제가 우분투가 아닌데다 특별히 스택 적용도 되지 않은 운영체제를 사용했기 때문에 작업을 진행하기 위해 먼저 설치해주어야 하는 것이 제법 된다. 과거에는 최신 Fedora 를 사용했고 요즘은 우분투를 쓰기 때문에 <code class=\"language-text\">yum</code>을 사용해야 한다거나 데몬 재시작 등 시스템 제어 관련 명령어를 찾는데 좀 헤멘 감이 있는데, 과거 AWS Lambda 를 사용하면서 모듈이나 라이브러리 의존성이 매우 짜증났기 때문에(Docker 로도 결국 해결을 못했다) 특별한 이유가 없으면 AMI 를 사용하기로 했다.</p>\n<h1 id=\"lightsail-ssh-접속\" style=\"position:relative;\"><a href=\"#lightsail-ssh-%EC%A0%91%EC%86%8D\" aria-label=\"lightsail ssh 접속 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Lightsail ssh 접속</h1>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">ssh</span> -i <span class=\"token string\">'pem파일경로'</span> <span class=\"token string\">'유저이름'</span>@<span class=\"token string\">'고정아이피'</span></code></pre></div>\n<p>윈도우 사용자는 <strong>putty</strong> 를 사용하거나 <strong>WSL</strong> 을 사용해서 리눅스 터미널을 열어 ssh 를 사용하면 될 듯 싶다.</p>\n<p>항상 터미널 명령어를 보며 나도 헤메지만, 저기서 <code class=\"language-text\">'pem파일경로'</code>에서 볼 수 있는 따옴표(<code class=\"language-text\">'</code>)들은 적어줄 필요가 없다.</p>\n<p>유저이름은 AMI 라면 <code class=\"language-text\">ec2-user</code>이고 우분투라면 <code class=\"language-text\">ubuntu</code>일 것이다.</p>\n<p>유저이름없이 고정아이피로만 접속을 시도하면 접속이 안되기 때문에 주의 요망</p>\n<h1 id=\"python3-설치\" style=\"position:relative;\"><a href=\"#python3-%EC%84%A4%EC%B9%98\" aria-label=\"python3 설치 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Python3 설치</h1>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">sudo</span> yum update\n$ <span class=\"token function\">sudo</span> yum <span class=\"token function\">install</span> python36 python36-devel python36-pip python36-setuptools python36-virtualenv</code></pre></div>\n<h1 id=\"venv-실행\" style=\"position:relative;\"><a href=\"#venv-%EC%8B%A4%ED%96%89\" aria-label=\"venv 실행 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>venv 실행</h1>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">mkdir</span> python3\n$ <span class=\"token builtin class-name\">cd</span> python3\n$ python3 -m venv venv\n$ <span class=\"token builtin class-name\">.</span> venv/bin/activate</code></pre></div>\n<p>python2 이하 버전은 <code class=\"language-text\">virtualenv</code>를 따로 설치해서 <code class=\"language-text\">virtualenv venv</code> 로 만들어준다.\n<code class=\"language-text\">venv</code> 는 python 을 사용하기 위한 일종의 가상 환경인데, python 프로젝트마다 각각 다른 버전의 라이브러리 설치를 가능하게 해준다. <code class=\"language-text\">nodejs</code>의 <code class=\"language-text\">nvm</code>과 비슷하지만 조금은 다른 그런 것.</p>\n<p><code class=\"language-text\">$ python3 -m venv venv</code> 라고 하면 혼동이 올 수 있는데</p>\n<p><code class=\"language-text\">$ python3 -m venv hello-project</code> 등으로 이름을 지어줄 수도 있다.</p>\n<p><code class=\"language-text\">venv</code> 모듈 호출 뒤에 원하는 이름을 작성하면 된다.</p>\n<h1 id=\"flask-gunicorn-설치\" style=\"position:relative;\"><a href=\"#flask-gunicorn-%EC%84%A4%EC%B9%98\" aria-label=\"flask gunicorn 설치 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>flask, gunicorn 설치</h1>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ pip3 <span class=\"token function\">install</span> flask gunicorn</code></pre></div>\n<p>앞서도 말했지만 해당 라이브러리는 <code class=\"language-text\">. venv/bin/activate</code>로 활성화된 <code class=\"language-text\">venv</code>에 설치하는 것이다. 따라서 다음에도 해당 <code class=\"language-text\">venv</code> 를 활성화해주지 않으면 나중에 호출할 때 해당 라이브러리는 존재하지 않는 것으로 응답한다.</p>\n<h1 id=\"flask-코드-작성\" style=\"position:relative;\"><a href=\"#flask-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1\" aria-label=\"flask 코드 작성 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>flask 코드 작성</h1>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">vim</span> hello.py</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> flask <span class=\"token keyword\">import</span> Flask\n<span class=\"token comment\"># flask 공식 예제는 app 이라는 변수명으로 초기화 하는데 이 경우 WSGI 연동시 할일이 더 생긴다.</span>\n<span class=\"token comment\"># 그러니 application 이라는 변수명으로 초기화 해주자.</span>\napplication <span class=\"token operator\">=</span> Flask<span class=\"token punctuation\">(</span>__name__<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># 라우팅을 위한 데코레이터</span>\n<span class=\"token decorator annotation punctuation\">@application<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/user/&lt;username>'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">show_user_profile</span><span class=\"token punctuation\">(</span>username<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">'Your user name is %s'</span> <span class=\"token operator\">%</span> username\n\n<span class=\"token decorator annotation punctuation\">@application<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/post/&lt;int:post_id>'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">show_post</span><span class=\"token punctuation\">(</span>post_id<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">'Post Id is %d'</span> <span class=\"token operator\">%</span> post_id\n\n<span class=\"token decorator annotation punctuation\">@application<span class=\"token punctuation\">.</span>route</span><span class=\"token punctuation\">(</span><span class=\"token string\">'/path/&lt;path:subpath>'</span><span class=\"token punctuation\">)</span>\n<span class=\"token keyword\">def</span> <span class=\"token function\">show_subpath</span><span class=\"token punctuation\">(</span>subpath<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token string\">'Subpath is %s, but what is subpath?'</span> <span class=\"token operator\">%</span> subpath\n\n<span class=\"token keyword\">if</span> __name__ <span class=\"token operator\">==</span> <span class=\"token string\">\"__main__\"</span><span class=\"token punctuation\">:</span>\n    application<span class=\"token punctuation\">.</span>run<span class=\"token punctuation\">(</span>host<span class=\"token operator\">=</span><span class=\"token string\">'0.0.0.0'</span><span class=\"token punctuation\">,</span> port<span class=\"token operator\">=</span><span class=\"token string\">'5000'</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>참고로 이 포스트의 코드들은 <a href=\"http://flask.pocoo.org/docs/1.0/quickstart/#a-minimal-application\">flask 공식 사이트</a>에서 적당히 코드를 가져온 다음,</p>\n<p><a href=\"https://pyliaorachel.github.io/blog/tech/system/2017/07/07/flask-app-with-gunicorn-on-nginx-server-upon-aws-ec2-linux.html\">Flask App with Gunicorn on Nginx Server upon AWS EC2 Linux</a> 라는 글의 예제를 참조했다.</p>\n<p>return 문의 문장은 내 맘대로 알아보기 쉽게 수정했다.</p>\n<p>작성한 코드를 실행시켜보자.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ python3 hello.py\n * Serving Flask app <span class=\"token string\">\"hello\"</span> <span class=\"token punctuation\">(</span>lazy loading<span class=\"token punctuation\">)</span>\n * Environment: production\n   WARNING: Do not use the development server <span class=\"token keyword\">in</span> a production environment.\n   Use a production WSGI server instead.\n * Debug mode: off\n * Running on http://0.0.0.0:5000/ <span class=\"token punctuation\">(</span>Press CTRL+C to quit<span class=\"token punctuation\">)</span></code></pre></div>\n<p>나는 위와 같이 결과가 나왔는데, 이미 gunicorn 과 nginx 연동이 끝난 후 실행하는 것이라 결과가 다르게 나올 수도 있다.</p>\n<p>production 환경에서 지금과 같은 개발 서버를 사용하지 말라고 경고를 하며 production WSGI 서버를 사용하라고 경고가 나오는데,</p>\n<p>그 이유에 대해서는 다음 사이트를 참조하면 될 것이다.</p>\n<p><a href=\"https://www.reddit.com/r/Python/comments/8bb102/why_shouldnt_one_use_flask_bottle_django_etc/\">Why shouldn’t one use Flask, Bottle, Django, etc. directly, and always use WSGI?</a></p>\n<p>대략 로드밸런싱과 성능 및 보안 문제인 것 같다. 요샌 AWS 인프라가 이런 로드밸런싱 업무를 대행하는 듯 해서 앞으로도 유효한 방법인지는 좀 더 지켜봐야 할 것 같다.</p>\n<h1 id=\"gunicorn-으로-wsgi-연동\" style=\"position:relative;\"><a href=\"#gunicorn-%EC%9C%BC%EB%A1%9C-wsgi-%EC%97%B0%EB%8F%99\" aria-label=\"gunicorn 으로 wsgi 연동 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>gunicorn 으로 wsgi 연동</h1>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">vim</span> wsgi.py</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">from</span> hello <span class=\"token keyword\">import</span> application\n\n<span class=\"token keyword\">if</span> __name__ <span class=\"token operator\">==</span> <span class=\"token string\">\"__main__\"</span><span class=\"token punctuation\">:</span>\n    application<span class=\"token punctuation\">.</span>run<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p>그 후 <code class=\"language-text\">gunicorn</code> 으로 실행한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ gunicorn --bind <span class=\"token number\">0.0</span>.0.0:5000 wsgi</code></pre></div>\n<p>그럼 wsgi 연동 작업도 완료되었다. <code class=\"language-text\">uwsgi</code> 를 사용하면 좀 더 복잡한 과정이 있었던 거 같은데 <code class=\"language-text\">gunicorn</code>을 사용하니 정말 간단한 느낌.</p>\n<p>이 작업을 실행하지 않으면 해당 폴더에 <code class=\"language-text\">hello.sock</code> 파일이 생기지 않을 것이다. 따라서 한 번은 반드시 실행해야 한다.</p>\n<h1 id=\"서버-재시작시-자동으로-재실행하는-스크립트-작성\" style=\"position:relative;\"><a href=\"#%EC%84%9C%EB%B2%84-%EC%9E%AC%EC%8B%9C%EC%9E%91%EC%8B%9C-%EC%9E%90%EB%8F%99%EC%9C%BC%EB%A1%9C-%EC%9E%AC%EC%8B%A4%ED%96%89%ED%95%98%EB%8A%94-%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%9E%91%EC%84%B1\" aria-label=\"서버 재시작시 자동으로 재실행하는 스크립트 작성 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>서버 재시작시 자동으로 재실행하는 스크립트 작성</h1>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">sudo</span> <span class=\"token function\">vim</span> /etc/init/helloproject.conf</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">script\ndescription <span class=\"token string\">\"Gunicorn application server running myproject\"</span>\n\nstart on runlevel <span class=\"token punctuation\">[</span><span class=\"token number\">2345</span><span class=\"token punctuation\">]</span>\nstop on runlevel <span class=\"token punctuation\">[</span><span class=\"token operator\">!</span><span class=\"token number\">2345</span><span class=\"token punctuation\">]</span>\n\nrespawn\n\n<span class=\"token comment\"># python3 venv 위치로 지정한 곳을 작성.</span>\n<span class=\"token function\">env</span> <span class=\"token assign-left variable\"><span class=\"token environment constant\">PATH</span></span><span class=\"token operator\">=</span>/home/ec2-user/works/python3/venv/bin\n<span class=\"token function\">env</span> <span class=\"token assign-left variable\">PROGRAM_NAME</span><span class=\"token operator\">=</span><span class=\"token string\">\"helloproject\"</span>\n<span class=\"token function\">env</span> <span class=\"token assign-left variable\">USERNAME</span><span class=\"token operator\">=</span><span class=\"token string\">\"ec2-user\"</span>\n\nscript\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"[<span class=\"token variable\"><span class=\"token variable\">`</span><span class=\"token function\">date</span> -u +%Y-%m-%dT%T.%3NZ<span class=\"token variable\">`</span></span>] (sys) Ready to run...\"</span> <span class=\"token operator\">>></span> /var/log/<span class=\"token variable\">$PROGRAM_NAME</span>.sys.log\n\n    <span class=\"token builtin class-name\">export</span> <span class=\"token assign-left variable\"><span class=\"token environment constant\">HOME</span></span><span class=\"token operator\">=</span><span class=\"token string\">\"/home/ec2-user\"</span>\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token variable\">$$</span> <span class=\"token operator\">></span> /var/run/<span class=\"token variable\">$PROGRAM_NAME</span>.pid\n\n    <span class=\"token comment\"># wsgi 파일이 위치하고 실행시키고자 하는 .sock 파일이 위치한 곳을 작성.</span>\n    <span class=\"token builtin class-name\">cd</span> /home/ec2-user/works/python3/flask-tutorial\n    <span class=\"token builtin class-name\">exec</span> gunicorn --workers <span class=\"token number\">3</span> --bind unix:hello.sock -m 000 wsgi <span class=\"token operator\">>></span> /var/log/<span class=\"token variable\">$PROGRAM_NAME</span>.sys.log <span class=\"token operator\"><span class=\"token file-descriptor important\">2</span>></span><span class=\"token file-descriptor important\">&amp;1</span>\nend script\n\n<span class=\"token comment\"># 디버깅을 위해 시작 전 실행하는 스크립트</span>\npre-start script\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"[<span class=\"token variable\"><span class=\"token variable\">`</span><span class=\"token function\">date</span> -u +%Y-%m-%dT%T.%3NZ<span class=\"token variable\">`</span></span>] (sys) Starting\"</span> <span class=\"token operator\">>></span> /var/log/<span class=\"token variable\">$PROGRAM_NAME</span>.sys.log\nend script\n\n<span class=\"token comment\"># 디버깅을 위해 종료 전 실행하는 스크립트</span>\npre-stop script\n    <span class=\"token function\">rm</span> /var/run/<span class=\"token variable\">$PROGRAM_NAME</span>.pid/\n    <span class=\"token builtin class-name\">echo</span> <span class=\"token string\">\"[<span class=\"token variable\"><span class=\"token variable\">`</span><span class=\"token function\">date</span> -u +%Y-%m-%dT%T.%3NZ<span class=\"token variable\">`</span></span>] (sys) Stopping\"</span> <span class=\"token operator\">>></span> /var/log/<span class=\"token variable\">$PROGRAM_NAME</span>.sys.log\nend script</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">sudo</span> initctl reload-configuration\n$ <span class=\"token function\">sudo</span> initctl list\nhelloproject start/running, process <span class=\"token number\">1234</span>\n$ <span class=\"token function\">sudo</span> initctl start helloproject\ninitctl: Job is already running: helloproject <span class=\"token comment\">#이미 나는 실행 중이어서 이런 문구가 출력</span>\n$ <span class=\"token function\">sudo</span> initctl status helloproject\nhelloproject start/running, process <span class=\"token number\">1234</span></code></pre></div>\n<h1 id=\"nginx-설치-및-설정\" style=\"position:relative;\"><a href=\"#nginx-%EC%84%A4%EC%B9%98-%EB%B0%8F-%EC%84%A4%EC%A0%95\" aria-label=\"nginx 설치 및 설정 permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>nginx 설치 및 설정</h1>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">sudo</span> yum <span class=\"token function\">install</span> nginx\n$ <span class=\"token function\">sudo</span> <span class=\"token function\">vim</span> /etc/nginx/nginx.conf</code></pre></div>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">전략\n<span class=\"token punctuation\">..</span>.\nserver <span class=\"token punctuation\">{</span>\n        listen       <span class=\"token number\">80</span> default_server<span class=\"token punctuation\">;</span>\n        listen       <span class=\"token punctuation\">[</span>::<span class=\"token punctuation\">]</span>:80 default_server<span class=\"token punctuation\">;</span>\n        server_name  helloproject<span class=\"token punctuation\">;</span> <span class=\"token comment\"># 서버 이름 설정</span>\n        root         /usr/share/nginx/html<span class=\"token punctuation\">;</span>\n\n        include /etc/nginx/default.d/*.conf<span class=\"token punctuation\">;</span>\n\n        location / <span class=\"token punctuation\">{</span>\n                <span class=\"token comment\"># wsgi에서 설정한 .sock 파일이 있는 위치를 작성한다.</span>\n                proxy_pass http://unix:/home/ec2-user/works/python3/flask-tutorial/hello.sock<span class=\"token punctuation\">;</span>\n        <span class=\"token punctuation\">}</span>\n        <span class=\"token punctuation\">..</span>.중략\n<span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">..</span>.\n후략</code></pre></div>\n<p>그 후 nginx 설정을 제대로 했는지 확인하기 위해 다음 명령어를 입력한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">sudo</span> nginx -t\nnginx: the configuration <span class=\"token function\">file</span> /etc/nginx/nginx.conf syntax is ok\nnginx: configuration <span class=\"token function\">file</span> /etc/nginx/nginx.conf <span class=\"token builtin class-name\">test</span> is successful</code></pre></div>\n<p>위와 다른 결과가 나온다면 뭔가가 잘못된 것이니 설정 파일을 작성하는데 오타나 실수가 없는지 확인한다.</p>\n<p>그 후 nginx 를 재실행한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">sudo</span> <span class=\"token function\">service</span> nginx restart</code></pre></div>\n<p>그리고 lightsail 의 고정 아이피에 포트를 80 으로 설정해서 들어가면… 아무 문제 없이 잘 되었으면 좋으련만 아마 에러가 발생할 것이다.</p>\n<p>permission 문제 때문인데 이게 <code class=\"language-text\">uWSGI</code>를 사용할 때도 발생했던 문제이고 이걸 해결하는 게 조금 까다로워서 <code class=\"language-text\">gunicorn</code>을 사용했는데 상황은 비슷한듯 하다.</p>\n<p>참조했던 사이트에서는 해당 문제를 아주 상큼하게 다음과 같이 해결한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"bash\"><pre class=\"language-bash\"><code class=\"language-bash\">$ <span class=\"token function\">chmod</span> <span class=\"token number\">711</span> /home/ec2-user <span class=\"token comment\"># 사용자는 무엇이든 할 수 있고 그외 다른 접근자는 실행(execute)만 가능하도록 permission</span>\n$ <span class=\"token function\">sudo</span> <span class=\"token function\">service</span> nginx restart <span class=\"token comment\"># 혹시 모르니 nginx 재시작</span></code></pre></div>\n<p>이제 브라우저 주소창에 <code class=\"language-text\">'고정아이피':'포트번호(80)'/user/rase</code> 라고 입력해보면</p>\n<div class=\"gatsby-highlight\" data-language=\"text\"><pre class=\"language-text\"><code class=\"language-text\">Your user name is rase</code></pre></div>\n<p>라고 나올 것이다.</p>","frontmatter":{"title":"AWS Lightsail에 flask + gunicorn + nginx 조합으로 간단한 서버 만들기","date":"October 06, 2018"}}},"pageContext":{"slug":"/18-10-06-flask-gunicorn/","previous":null,"next":{"fields":{"slug":"/19-04-22-trust-asset/"},"frontmatter":{"title":"신뢰자본과 개발주도","category":"Dev","draft":false}}}},
    "staticQueryHashes": ["3128451518","3474900066"]}