์๋ ํ์ธ์ ์ ๋ Bootcamp๋ฅผ ๋ํ ๋ด ์ฐ๊ตฌ์๋ค์ ์ํ ์์ ๋คํธ์ํฌ๋ก ๋ง๋ค๋ ค๊ณ ํฉ๋๋ค. ๊ทธ๋ฌ๋ ๋ช ๊ฐ์ง ์ ์ฝ์ผ๋ก ์ธํด ํ์ฌ caddy๋ฅผ ๋ฐฐํฌ์ฉ ๋ฆฌ๋ฒ์ค ํ๋ก์๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. ๋์ nginx๋ฅผ ์ฌ์ฉํฉ๋๋ค. ๊ฐ๋ฅํ๋ค๋ฉด ํ๋ก๋์ ํ๊ฒฝ์ ๋ํด ์ง์ ํด์ผ ํ๋ ๋งค๊ฐ๋ณ์์ ๋ํ ์ง์นจ์ ์ ๊ณตํ ์ ์์ต๋๋ค. env.example ํ์ผ์ ๋ณด์์ง๋ง ํ๋ก์ ํธ๊ฐ ์ฒ์์ด๋ผ ๋ชจ๋ ๊ฒ์ด ์ด๋ป๊ฒ ์ฐ๊ฒฐ๋๋์ง ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ๋ค์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค.
manage.py runworker: error: the following arguments are required: channels
๋์์ ์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค.
์๋
ํ์ธ์,
์บ๋๋ฅผ ์ฌ์ฉํ์ง ์์ต๋๋ค. ๋ด ๋ชจ๋ django ํ๋ก์ ํธ์ gunicorn์ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
๋ชจ๋ ์๊ตฌ ์ฌํญ์ ์ค์น ํ์ต๋๊น?
์ฑ๋>=2.1.1 # https://github.com/django/channels
์ฑ๋-๋ ๋์ค>=2.2.1 # https://github.com/django/channels_redis
์ฝ์์ ํตํด ํ์ธํ ์ ์์ต๋๋ค
$ python -c "import channels"
$ echo $?
0์ ์กด์ฌํจ์ ์๋ฏธํฉ๋๋ค
1์ ๋ชจ๋์ด ์์คํ
์ ์กด์ฌํ์ง ์์์ ์๋ฏธํฉ๋๋ค.
์ฑ๋์ด ์ค์น๋ฉ๋๋ค. ์ง๊ธ ๋ ๋ค๋ฅธ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์ฌ๊ธฐ ๋ด ๋์ปค ํ์ผ๊ณผ .env๊ฐ ์์ต๋๋ค. ์์ ์ ์๋น์ค์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ๊ทธ๊ฒ์ด ๋ฌด์์ํ๋์ง ํ์คํ์ง ์์ต๋๋ค. ๋น์ ์ ๋์์ ์ง์ฌ์ผ๋ก ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋น์ ์ ํ๋ก์ ํธ๋ ๋งค์ฐ ํฅ๋ฏธ๋กญ๊ณ ์ด๊ฒ์ด ์์ฐ๋๋ค๋ฉด ์ฐ๋ฆฌ ๋ํ์ ๋ง์ ์ฌ๋๋ค์ ๋์ธ ์ ์์ต๋๋ค.
๋ค์์ ์ค๋ฅ ๋ก๊ทธ์ ๋๋ค.
worker_1 | /usr/local/lib/python3.6/site-packages/daphne/server.py:13: UserWarning: Something has already installed a non-asyncio Twisted reactor. Attempting to uninstall it; you can fix this warning by importing daphne.server early in your codebase or finding the package that imports Twisted and importing it later on.
worker_1 | UserWarning,
django_1 | DEBUG 2019-10-17 21:28:37,751 base 1 140450066271560 Configuring Raven for host: https://sentry.io
worker_1 | DEBUG 2019-10-17 21:28:35,663 base 1 140638836505928 Configuring Raven for host: https://sentry.io
worker_1 | Running worker for channels ['channels', 'notifications']
worker_1 | DEBUG 2019-10-17 21:28:36,297 base 1 140638836505928 Sending message of length 5534 to https://sentry.io/api/1782977/store/
worker_1 | Traceback (most recent call last):
worker_1 | File "manage.py", line 30, in <module>
worker_1 | execute_from_command_line(sys.argv)
worker_1 | File "/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py", line 381, in execute_from_command_line
worker_1 | utility.execute()
worker_1 | File "/usr/local/lib/python3.6/site-packages/django/core/management/__init__.py", line 375, in execute
worker_1 | self.fetch_command(subcommand).run_from_argv(self.argv)
worker_1 | File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 323, in run_from_argv
worker_1 | self.execute(*args, **cmd_options)
worker_1 | File "/usr/local/lib/python3.6/site-packages/django/core/management/base.py", line 364, in execute
worker_1 | output = self.handle(*args, **options)
worker_1 | File "/usr/local/lib/python3.6/site-packages/channels/management/commands/runworker.py", line 46, in handle
worker_1 | worker.run()
worker_1 | File "/usr/local/lib/python3.6/site-packages/asgiref/server.py", line 60, in run
worker_1 | event_loop.run_until_complete(self.handle())
worker_1 | File "/usr/local/lib/python3.6/asyncio/base_events.py", line 484, in run_until_complete
worker_1 | return future.result()
worker_1 | File "/usr/local/lib/python3.6/site-packages/channels/worker.py", line 30, in handle
worker_1 | [listener.result() for listener in listeners]
worker_1 | File "/usr/local/lib/python3.6/site-packages/channels/worker.py", line 30, in <listcomp>
worker_1 | [listener.result() for listener in listeners]
worker_1 | File "/usr/local/lib/python3.6/site-packages/channels/worker.py", line 37, in listener
worker_1 | message = await self.channel_layer.receive(channel)
worker_1 | File "/usr/local/lib/python3.6/site-packages/channels_redis/core.py", line 461, in receive
worker_1 | return (await self.receive_single(channel))[1]
ํ๊ฒฝ์ ๋ณํ
REDIS_URL=redis://127.0.0.1:6379
์์ ์ ์๋น์ค๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ ์ฃผ์๊ฒ ์ต๋๊น? ๊ทธ๋ฆฌ๊ณ ์ ํ์ํฉ๋๊น? ์ด ํ๋ก์ ํธ๋ฅผ ์ฒ์ ์ ํ์ฌ ํด๋น ์ ๋ณด๋ฅผ ์ด๋์์ ์ฐพ์์ผ ํ ์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค.
์ด, ๋ง์ด. ์ด๊ฒ์ ๋ช ๋ถ ์์ ์๋ฃ๋์ง ์์ต๋๋ค ...
๋จผ์ ์๋ฒ ํ๊ฒฝ์ ๋ชจ๋ ์๊ตฌ ์ฌํญ์ ์ค์นํ๋์ง ํ์ธํ์ญ์์ค.
pip install -U -r requirements/production.txt
๋์งธ, ํ๋ก์ ํธ๊ฐ ๋ก์ปฌ์์ ์งํ ์ค์ ๋๊น?
๋ชจ๋ ํ์ผ์ด ์์ผ๋ฉด ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ ๊ทธ๊ฒ์ ๊ตฌ์ฑํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ง ์์ต๋๋ค. ๋ด ๊ตฌ์ฑ ๋ฐ ๊ณต์ ๋ฅผ ํ์ธํ ์ ์์ง๋ง ๋ถํธ์บ ํ์ ๋ํด ํ ์คํธ ๋ฐ ์น์ธ๋์ง ์์์ต๋๋ค. ์ถ๊ฐ ์ค์ ์ด ํ์ํ ์ ์์ต๋๋ค.
docker compose๋ฅผ ์ฌ์ฉํ์ฌ ์๋น์ค๋ฅผ ์์ํ๊ณ ์์ต๋๋ค. ๋ก์ปฌ ๋ฐฐํฌ๋ ์ ์๋ํ์ง๋ง production.yml์ ์์ ํ ๋ค๋ฆ ๋๋ค. ๋๋ redis, daphne, postgres๋ฅผ ํฌํจํฉ๋๋ค. ์ด๋๊ฐ์ ํธ๋ฆฌํ docker-compose ํ์ผ์ด ์์ผ๋ฉด ๊ณต์ ํ์ญ์์ค. ๊ฐ์ฌ ํด์
iOS์ฉ Outlook ๋ค์ด๋ก๋ https://aka.ms/o0ukef
๋ณด๋ธ ์ฌ๋: samazaphikel [email protected]
๋ณด๋ธ ๋ ์ง: 2019๋
10์ 17์ผ ๋ชฉ์์ผ ์คํ 5:03:30
๋ฐ๋ ์ฌ๋: vitorfs/bootcamp [email protected]
์ฐธ์กฐ: Tri Minh Pham [email protected] ; ์ ์ ์ ์ @noreply.github.com
์ ๋ชฉ: Re: [vitorfs/bootcamp] ํ๋ก๋์
์ค์ ์ ๋์์ด ๋ฉ๋๋ค. (#193)
์ด, ๋ง์ด. ์ด๊ฒ์ ๋ช ๋ถ ์์ ์๋ฃ๋์ง ์์ต๋๋ค ...
๋จผ์ ์๋ฒ ํ๊ฒฝ์ ๋ชจ๋ ์๊ตฌ ์ฌํญ์ ์ค์นํ๋์ง ํ์ธํ์ญ์์ค.
pip install -U -r ์๊ตฌ ์ฌํญ/production.txt
๋์งธ, ํ๋ก์ ํธ๊ฐ ๋ก์ปฌ์์ ์งํ ์ค์ ๋๊น?
๋ชจ๋ ํ์ผ์ด ์์ผ๋ฉด ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋๋ ๊ทธ๊ฒ์ ๊ตฌ์ฑํ๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ง ์์ต๋๋ค. ๋ด ๊ตฌ์ฑ ๋ฐ ๊ณต์ ๋ฅผ ํ์ธํ ์ ์์ง๋ง ๋ถํธ์บ ํ์ ๋ํด ํ ์คํธ ๋ฐ ์น์ธ๋์ง ์์์ต๋๋ค. ์ถ๊ฐ ์ค์ ์ด ํ์ํ ์ ์์ต๋๋ค.
โ
์ค๋ ๋๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์ ์ด ๋ฉ์์ง๋ฅผ ๋ฐ๋ ๊ฒ์
๋๋ค.
GitHub์์ ๊ทธ๊ฒ์ ์ง์ ์ด ์ด๋ฉ์ผ์ ํ์ ๋ณผ https://github.com/vitorfs/bootcamp/issues/193?email_source=notifications&email_token=ADEK4AB5JEUP5LQ4APTJ6ITQPDOLFA5CNFSM4JB4YOCKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEBRVI2A#issuecomment-543380584 , ๋๋ ํํด https://github.com/notifications/unsubscribe- ์ธ์ฆ/ADEK4ADBCG24WLWIT3IM6OLQPDOLFANCNFSM4JB4YOCA .
์ ๊ฒฝ์ฐ์๋ Ubuntu ์๋ฒ ์์คํ ์์ python 3.7.1์ ์ฌ์ฉํ๋ ๋ฉ์ ์
์ ํ์ ์ค์ Python ๋ฒ์
sudo update alternatives --install /usr/bin/python/ python /usr/bin/python3.7.1
์ด ๋ช ๋ น์ ์ฌ์ฉํ๋ฉด python 3.7.1์ด ์ฒซ ๋ฒ์งธ ์ฐ์ ์์์ ๋๋ค.
๋จผ์ ๋จธ์ ์ ํ๊ฒฝ์ ์ค์นํฉ๋๋ค.
sudo -H pip3 install virtualenv
cd /home/pages
์ฌ๋ฐ๋ฅธ ํด๋๋ก ๋ณ๊ฒฝ
mkdir bootcamp
ํ๋ก์ ํธ ํด๋ ์์ฑ
cd bootcamp/
ํ๊ฒฝ ์์ฑ
virtualenv bootcampenv
ํ๊ฒฝ ํ์ฑํ
source bootcampenv/bin/activate
์ค์นํ๋ค
pip3 install gunicorn
ํ์ด์ง ๋๋ ํ ๋ฆฌ๋ก ๋์๊ฐ๊ธฐ
cd ..
๋ถํธ์บ ํ ํ๋ก์ ํธ๋ฅผ ์ํ ํด๋ ์์ฑ
django-admin startproject bootcampprojectdir
cd bootcampprojectdir
๊ทธ๋ฆฌ๊ณ ์๊ตฌ ์ฌํญ์ ์ค์น
pip install -U -r requirements/production.txt
๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฑ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ง์ด๊ทธ๋ ์ด์ ์ ์์ํ๊ณ static์ ์์งํฉ๋๋ค.
ํฌํธ 8000์ ํ์ฉํ๋๋ก ๋ฐฉํ๋ฒฝ ์
๋ฐ์ดํธ
sudo ufw allow 8000
gunicorn wsgi ์์ฑ
gunicorn --bind 0.0.0.0:8000 settings.wsgi
์์คํ
์์ผ ์์ฑ
sudo nano /etc/systemd/system/gunicorn.socket
[๋จ์]
์ค๋ช =gunicorn.sock[์์ผ]
ListenStream=/run/gunicorn.sock[์ค์น]
WantedBy=sockets.target
์๋น์ค๋ฅผ ๋ง๋ค๋ค
sudo nano /etc/systemd/system/gunicorn.service
[๋จ์]
์ค๋ช =gunicorn ๋ฐ๋ชฌ
ํ์=gunicorn.socket
์ดํ=๋คํธ์ํฌ.ํ๊ฒ[์๋น์ค]
์ฌ์ฉ์=ํ์ด์ง
๊ทธ๋ฃน=www-data
WorkingDirectory=/home/pages/bootcampprojectdir/bootcampenv/bin/gunicorn
--์ก์ธ์ค-๋ก๊ทธ ํ์ผ-
--๋ ธ๋์ 3
--bind ์ ๋์ค:run/gunicorn.sock
settings.wsgi.application[์ค์น]
WantedBy=๋ค์ค ์ฌ์ฉ์.๋์
๋ชจ๋ ๊ฒ์ ํ์ฑํ
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
ํ์ธํด ๋ด
file /run/gunicorn.sock
์ค๋ฅ๊ฐ ์์ผ๋ฉด ๊ด์ฐฎ์ต๋๋ค.
์ํ๋ฅผ ํ์ธํ์ธ์
sudo systemctl status gunicorn.socket
์ ๊ฒ ์๋น์ค
curl --unix-socket /run/gunicorn.sock localhost
htnl ์ฝ๋๊ฐ ํ์๋์ง ์์ผ๋ฉด gunicorn.service๊ฐ ์๋ ๊ฒ
์๋น์ค๊ฐ ์คํ ์ค์ธ์ง ํ์ธ
sudo systemctl status gunicorn
๋ชจ๋ ๊ฒ์ด ๊ด์ฐฎ์ ๋ ๋ค์ ๋จ๊ณ NGinx๋ gunicorn์ผ๋ก ์ ๋ฌ๋ฉ๋๋ค.
nginx ์ค์น
sudo apt install nginx
nginx์์ ์ฌ์ดํธ ๋ง๋ค๊ธฐ
์๋น์ค๋ฅผ ๋ง๋ค๋ค
sudo nano /etc/nginx/sites-available/bootcampproject
์๋ฒ {
๋ค์ด๋ด 80;
์๋ฒ ์ด๋ฆ 99.99.99.99location = /favicon.ico { access_log off; log_not_found off; } location /static/ { root /home/pages/bootcampprojectdir; }
์์น / {
proxy_params ํฌํจ;
proxy_pass http://unix :/run/gunicorn.sock;
}
}
์ด ํ์ผ์ ์ฌ์ดํธ ์ฌ์ฉ ๊ฐ๋ฅ์ ์ ์ฅํ๊ณ ๋ณต์ฌํ์ญ์์ค.
sudo ln -s /etc/nginx/sites-available/bootcampproject /etc/nginx/sites/enabled
nginx ์ค์ ํ์ธ
sudo nginx -t
์ค๋ฅ๊ฐ ์์ผ๋ฉด nginx๋ฅผ ๋ค์ ์์ํ์ญ์์ค.
sudo systemctl restart nginx
nginx ๋ฐฉํ๋ฒฝ ํฌํธ๋ฅผ ์ถ๊ฐํ๋ ๋จผ์ ํ ์คํธ์์ ํฌํธ 8000์ ์ญ์ ํ์ญ์์ค.
sudo ufw delete allow 8000
nginx ์ถ๊ฐ
sudo ufw allow 'Nginx Full'
์๋
ํ์ธ์ @phamminhtris ํ๋ก์ ํธ๋ฅผ ์ฌ์ฉํ๊ณ docker-compose
์ ๋ํด ์๋นํ ์์ค์ ์ง์์ด ํ์ํฉ๋๋ค. ๋๋ ์ ๋ฌธ๊ฐ์๋ ๊ฑฐ๋ฆฌ๊ฐ ๋ฉ๊ณ ๊ทธ๊ฒ์ด ๊ฐ๋ฐ์ฉ์ผ๋ก๋ง ์ฌ์ฉํ๋ ์ด์ ์
๋๋ค. ํ์ง๋ง ์๋ง๋ ์ฌ๊ธฐ์์ ์ ์ฉํ ๊ฒ์ ์ฐพ์ ์
๋ค๋ฅธ ๋ฐฉ๋ฒ์ ํ๋ก์ ํธ๋ฅผ ์๋ ๊ทธ๋๋ก ๊ตฌํํ๋ ๊ฒ์
๋๋ค. "๋ ์ฌ์ด"(๋๋ ์ต์ํ ๋ฐฐํฌ๋ฅผ ์ํ ๋ ๋ง์ ๋ฆฌ์์ค์ ๊ฐ์ด๋๋ฅผ ์ฐพ์ ์ ์์), ํ์ํ ๋ณ์์ ํจ๊ป .env
ํ์ผ์ ๋ก๋ํ๋ ๊ฒ์ ๊ธฐ์ตํ์ญ์์ค. ํฌํจ๋ ์์ ๋ฒ์ ์ ์ฌ์ฉํ์ฌ ์ ์ธ ๋ฐฉ๋ฒ์ ์ดํดํ ์ ์์ต๋๋ค.
๊ทธ๋ฅ gunicorn์ ์ ์ผํ ์๋ฒ๋ก ์ฌ์ฉํ๋ ๊ฒ์ผ๋ก ์ถฉ๋ถํฉ๋๊น? ์น ์์ผ ํธ๋ํฝ์ ์ฒ๋ฆฌํ๊ธฐ ์ํด daphne๊ณผ ๊ฐ์ ASGI ์ ํ๋ฆฌ์ผ์ด์ ์๋ฒ๊ฐ ํ์ํ ๊ธฐ๋ฅ ์ค ์ผ๋ถ๋ฅผ ๋ณด์์ต๋๋ค. ๋ด๊ฐ ํ๋ ธ๋ค๋ฉด ์ ๋ฅผ ์์ ํ์ญ์์ค. ์น์ ํ ๋์์ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ์ ๋ง ๊ฐ์ฌํฉ๋๋ค.
Nginx๋ ์ธํฐ๋ท์ ์์ฒญ์ด ๊ฐ์ฅ ๋จผ์ ๋์ฐฉํ๋ ๊ณณ์ ๋๋ค. ๋งค์ฐ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌํ ์ ์์ผ๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก ์น ์ ํ๋ฆฌ์ผ์ด์ ์ ์ค์ ๋ก ๋๋ฌํด์ผ ํ๋ ์์ฒญ๋ง ํต๊ณผํ๋๋ก ๊ตฌ์ฑ๋ฉ๋๋ค.
Gunicorn์ Nginx์์ ๋ฐ์ ์์ฒญ์ ์น ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ฒ๋ฆฌํ ์ ์๋ ํ์์ผ๋ก ๋ณํํ๊ณ ํ์ํ ๋ ์ฝ๋๊ฐ ์คํ๋๋๋ก ํฉ๋๋ค.
๊ฐ์๊ฐ ํ ์ ์๋ ์ผ์ ๋ค๋ฅธ ๋๊ตฐ๊ฐ๊ฐ ํ ์ ์์ต๋๋ค.
Nginx๋ ์น ์๋ฒ ๋ฐ ์ญ๋ฐฉํฅ ํ๋ก์์
๋๋ค. ์น ์๋ฒ๊ฐ ์ํํด์ผ ํ๋ ๋ชจ๋ ์์
์ ๋ํด ๊ณ ๋๋ก ์ต์ ํ๋์ด ์์ต๋๋ค.
๋๋ฉ์ธ ์ด๋ฆ ๋ผ์ฐํ
์ ์ฒ๋ฆฌํฉ๋๋ค(์์ฒญ์ด ์ด๋๋ก ๊ฐ์ผ ํ๋์ง ๋๋ ์ค๋ฅ ์๋ต์ด ์ฌ๋ฐ๋ฅธ์ง ๊ฒฐ์ ).
์ ์ ํ์ผ ์ ๊ณต
ํ ๋ฒ์ ๋ค์ด์ค๋ ๋ง์ ์์ฒญ ์ฒ๋ฆฌ
๋๋ฆฐ ํด๋ผ์ด์ธํธ ์ฒ๋ฆฌ
๋์ ์ด์ด์ผ ํ๋ ์์ฒญ์ Gunicorn์ ์ ๋ฌ
SSL ์ข
๋ฃ(https๋ ์ฌ๊ธฐ์์ ๋ฐ์)
Python ์ฝ๋์ ๋น๊ตํ์ฌ ์ปดํจํ
๋ฆฌ์์ค(CPU ๋ฐ ๋ฉ๋ชจ๋ฆฌ) ์ ์ฝ
๊ทธ๋ฆฌ๊ณ ํจ์ฌ ๋, ๊ทธ๋ ๊ฒ ํ๋๋ก ๊ตฌ์ฑํ๋ฉด(๋ก๋ ๋ฐธ๋ฐ์ฑ, ์บ์ฑ, โฆ)
๊ตฌ๋์ฝ
Nginx๊ฐ ๊ฒฐ์ ํ๋ฉด ํน์ ์์ฒญ์ Gunicorn์ผ๋ก ์ ๋ฌํด์ผ ํฉ๋๋ค(๊ตฌ์ฑํ ๊ท์น์ผ๋ก ์ธํด).
Gunicorn์ ๊ณ ๋๋ก ์ต์ ํ๋์ด ์์ผ๋ฉฐ ํธ๋ฆฌํ ๊ธฐ๋ฅ์ด ๋ง์ด ์์ต๋๋ค.
์์
์ ํ๋ก์ธ์ค/์ค๋ ๋ ํ ์คํ(์ฝ๋ ์คํ!)
Nginx์์ ๋ค์ด์ค๋ ์์ฒญ์ WSGI์ ํธํ๋๋๋ก ๋ณํ
์ฑ์ WSGI ์๋ต์ ์ ์ ํ http ์๋ต์ผ๋ก ๋ณํ
์ค์ ๋ก ์์ฒญ์ด ๋ค์ด์ฌ ๋ Python ์ฝ๋๋ฅผ ํธ์ถํฉ๋๋ค.
Gunicorn์ ๋ค์ํ ์น ์๋ฒ์ ํต์ ํ ์ ์์ต๋๋ค.
Gunicorn์ ์ ํจํ ๋ง์ WSGI ์๋ฒ ์ค ํ๋์ผ ๋ฟ์
๋๋ค. ๋น์ ์ ์ฑ์ ๋น์ ์ด ์ด๋ค ๊ฒ์ ์ฌ์ฉํ๋์ง ์๊ดํ์ง ์์ผ๋ฉฐ Nginx๋ ์๊ดํ์ง ์์ต๋๋ค.
์์ ๋ด์ฉ์ ์ดํดํฉ๋๋ค. ๊ทธ๋ฌ๋ ์ด ํ๋ก์ ํธ๋ ํ๋กํ ์ฝ ์ธก๋ฉด์์ ๋งค์ฐ ํน๋ณํฉ๋๋ค. ์น ์์ผ์ ํตํด ์๋ฆผ์ ์ ๊ณตํ๋ฉฐ ์ฑ์ ๊ตฌ๋ํ๋ ค๋ฉด ์ผ๋ฐ gunicorn ๋ฐ nginx ์ด์์ด ํ์ํ๋ค๊ณ ์ดํดํฉ๋๋ค. ๋ก์ปฌ ๋์ปค ์์ฑ์ ์คํํ ๋ /notifications๊ฐ ์๋ํ์ง ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ ๊ฐ ๋ง์ ๊ฒ์ ์๊ตฌํ๊ณ ์๋ค๋ ๊ฒ์ ์๊ณ ์์ง๋ง @samazaphikel์ ๋์์ฃผ์ ์๊ฐ๊ณผ ๋ ธ๋ ฅ์ ์ ๋ง ๊ฐ์ฌ๋๋ฆฝ๋๋ค. ๋ฒ ์ด ์ฐ๋ถํฌ๋ง ๋ก์ปฌ ๊ตฌ์ฑ(docker-compose, docker ์์)์ ์๋ํ๊ณ ์๋ํ๋์ง ํ์ธํฉ๋๋ค. ๊ฐ์ฌํฉ๋๋ค ์ฌ๋ฌ๋ถ
๋งค์ฐ ์ ์ฉํ ๊ฐ์ด๋. ํ์.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ ๊ฒฝ์ฐ์๋ Ubuntu ์๋ฒ ์์คํ ์์ python 3.7.1์ ์ฌ์ฉํ๋ ๋ฉ์ ์
์ ํ์ ์ค์ Python ๋ฒ์
sudo update alternatives --install /usr/bin/python/ python /usr/bin/python3.7.1
์ด ๋ช ๋ น์ ์ฌ์ฉํ๋ฉด python 3.7.1์ด ์ฒซ ๋ฒ์งธ ์ฐ์ ์์์ ๋๋ค.
๋จผ์ ๋จธ์ ์ ํ๊ฒฝ์ ์ค์นํฉ๋๋ค.
sudo -H pip3 install virtualenv
cd /home/pages
์ฌ๋ฐ๋ฅธ ํด๋๋ก ๋ณ๊ฒฝmkdir bootcamp
ํ๋ก์ ํธ ํด๋ ์์ฑcd bootcamp/
ํ๊ฒฝ ์์ฑ
virtualenv bootcampenv
ํ๊ฒฝ ํ์ฑํ
source bootcampenv/bin/activate
์ค์นํ๋ค
pip3 install gunicorn
ํ์ด์ง ๋๋ ํ ๋ฆฌ๋ก ๋์๊ฐ๊ธฐ
cd ..
๋ถํธ์บ ํ ํ๋ก์ ํธ๋ฅผ ์ํ ํด๋ ์์ฑ
django-admin startproject bootcampprojectdir
cd bootcampprojectdir
๊ทธ๋ฆฌ๊ณ ์๊ตฌ ์ฌํญ์ ์ค์น
pip install -U -r requirements/production.txt
๋ค๋ฅธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฑ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ๋ง์ด๊ทธ๋ ์ด์ ์ ์์ํ๊ณ static์ ์์งํฉ๋๋ค.
ํฌํธ 8000์ ํ์ฉํ๋๋ก ๋ฐฉํ๋ฒฝ ์ ๋ฐ์ดํธ
sudo ufw allow 8000
gunicorn wsgi ์์ฑ
gunicorn --bind 0.0.0.0:8000 settings.wsgi
์์คํ ์์ผ ์์ฑ
sudo nano /etc/systemd/system/gunicorn.socket
์๋น์ค๋ฅผ ๋ง๋ค๋ค
sudo nano /etc/systemd/system/gunicorn.service
๋ชจ๋ ๊ฒ์ ํ์ฑํ
sudo systemctl start gunicorn.socket
sudo systemctl enable gunicorn.socket
ํ์ธํด ๋ด
file /run/gunicorn.sock
์ค๋ฅ๊ฐ ์์ผ๋ฉด ๊ด์ฐฎ์ต๋๋ค.
์ํ๋ฅผ ํ์ธํ์ธ์
sudo systemctl status gunicorn.socket
์ ๊ฒ ์๋น์ค
curl --unix-socket /run/gunicorn.sock localhost
htnl ์ฝ๋๊ฐ ํ์๋์ง ์์ผ๋ฉด gunicorn.service๊ฐ ์๋ ๊ฒ
์๋น์ค๊ฐ ์คํ ์ค์ธ์ง ํ์ธ
sudo systemctl status gunicorn
๋ชจ๋ ๊ฒ์ด ๊ด์ฐฎ์ ๋ ๋ค์ ๋จ๊ณ NGinx๋ gunicorn์ผ๋ก ์ ๋ฌ๋ฉ๋๋ค.
nginx ์ค์น
sudo apt install nginx
nginx์์ ์ฌ์ดํธ ๋ง๋ค๊ธฐ
์๋น์ค๋ฅผ ๋ง๋ค๋ค
sudo nano /etc/nginx/sites-available/bootcampproject
์ด ํ์ผ์ ์ฌ์ดํธ ์ฌ์ฉ ๊ฐ๋ฅ์ ์ ์ฅํ๊ณ ๋ณต์ฌํ์ญ์์ค.
sudo ln -s /etc/nginx/sites-available/bootcampproject /etc/nginx/sites/enabled
nginx ์ค์ ํ์ธ
sudo nginx -t
์ค๋ฅ๊ฐ ์์ผ๋ฉด nginx๋ฅผ ๋ค์ ์์ํ์ญ์์ค.
sudo systemctl restart nginx
nginx ๋ฐฉํ๋ฒฝ ํฌํธ๋ฅผ ์ถ๊ฐํ๋ ๋จผ์ ํ ์คํธ์์ ํฌํธ 8000์ ์ญ์ ํ์ญ์์ค.
sudo ufw delete allow 8000
nginx ์ถ๊ฐ
sudo ufw allow 'Nginx Full'