Bootcamp: ํ”„๋กœ๋•์…˜ ์„ค์ •์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

์— ๋งŒ๋“  2019๋…„ 10์›” 17์ผ  ยท  12์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: vitorfs/bootcamp

์•ˆ๋…•ํ•˜์„ธ์š” ์ €๋Š” Bootcamp๋ฅผ ๋Œ€ํ•™ ๋‚ด ์—ฐ๊ตฌ์›๋“ค์„ ์œ„ํ•œ ์†Œ์…œ ๋„คํŠธ์›Œํฌ๋กœ ๋งŒ๋“ค๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ช‡ ๊ฐ€์ง€ ์ œ์•ฝ์œผ๋กœ ์ธํ•ด ํ˜„์žฌ caddy๋ฅผ ๋ฐฐํฌ์šฉ ๋ฆฌ๋ฒ„์Šค ํ”„๋ก์‹œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  nginx๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์— ๋Œ€ํ•ด ์ง€์ •ํ•ด์•ผ ํ•˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ์ง€์นจ์„ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. env.example ํŒŒ์ผ์„ ๋ณด์•˜์ง€๋งŒ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ฒ˜์Œ์ด๋ผ ๋ชจ๋“  ๊ฒƒ์ด ์–ด๋–ป๊ฒŒ ์—ฐ๊ฒฐ๋˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

manage.py runworker: error: the following arguments are required: channels

๋„์›€์„ ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Support discussion help wanted

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

์ œ ๊ฒฝ์šฐ์—๋Š” 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.99

  location = /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'

๋ชจ๋“  12 ๋Œ“๊ธ€

์•ˆ๋…•ํ•˜์„ธ์š”,
์บ๋””๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด ๋ชจ๋“  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๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์ž‘์—…์ž ์„œ๋น„์Šค์— ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ๋ฌด์—‡์„ํ•˜๋Š”์ง€ ํ™•์‹คํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์˜ ๋„์›€์— ์ง„์‹ฌ์œผ๋กœ ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค. ๋‹น์‹ ์˜ ํ”„๋กœ์ ํŠธ๋Š” ๋งค์šฐ ํฅ๋ฏธ๋กญ๊ณ  ์ด๊ฒƒ์ด ์ƒ์‚ฐ๋œ๋‹ค๋ฉด ์šฐ๋ฆฌ ๋Œ€ํ•™์˜ ๋งŽ์€ ์‚ฌ๋žŒ๋“ค์„ ๋„์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

env.txt

docker-compose.txt

๋‹ค์Œ์€ ์˜ค๋ฅ˜ ๋กœ๊ทธ์ž…๋‹ˆ๋‹ค.

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.99

  location = /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 ์—†์Œ)์„ ์‹œ๋„ํ•˜๊ณ  ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค ์—ฌ๋Ÿฌ๋ถ„

๋งค์šฐ ์œ ์šฉํ•œ ๊ฐ€์ด๋“œ. ํ์‡„.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰

๊ด€๋ จ ๋ฌธ์ œ

sebastian-code picture sebastian-code  ยท  11์ฝ”๋ฉ˜ํŠธ

norouzzadeh picture norouzzadeh  ยท  3์ฝ”๋ฉ˜ํŠธ

ssahilsahil798 picture ssahilsahil798  ยท  5์ฝ”๋ฉ˜ํŠธ

yashLadha picture yashLadha  ยท  21์ฝ”๋ฉ˜ํŠธ

mwanjajoel picture mwanjajoel  ยท  5์ฝ”๋ฉ˜ํŠธ