Posted
Filed under 개발/Linux
* 다음 웹페이지를 보고 따라해보면서 마지막까지 트러블 없이 완료. 나에게 맞게 명령을 수정하면서 수행했던 내용을 기록하는 의미에서 포스팅한다.
How to setup Taiga project management platform on Raspberry Pi 3 with Raspbian Stretch Lite
https://www.techcoil.com/blog/how-to-setup-taiga-project-management-platform-on-raspberry-pi-3-with-raspbian-stretch-lite/


[기본설정 준비]
* 필요패키지 설치
$ sudo apt-get install build-essential binutils-doc autoconf flex bison libjpeg-dev libfreetype6-dev zlib1g-dev libzmq3-dev libgdbm-dev libncurses5-dev automake libtool libffi-dev curl git tmux gettext rabbitmq-server redis-server nginx supervisor postgresql postgresql-contrib postgresql-doc postgresql-server-dev-9.6 python-dev libxml2-dev libxslt-dev libssl-dev libffi-dev libopenjp2-7-dev virtualenv


* 시스템유저 taiga 작성 후 로그인
$ sudo adduser taiga
$ sudo adduser taiga sudo
$ sudo su taiga
$ cd ~


* PostgreSQL 설정을 위한 리눅스 로케일 확인
$ locale -a


* PostgreSQL 유저및 DB생성
$ sudo -u postgres createuser taiga
$ sudo -u postgres createdb taiga -O taiga --encoding='utf-8' --locale=en_GB.utf8 --template=template0


* RabbitMQ 유저및 가상호스트 생성
$ sudo rabbitmqctl add_user taiga PASSWORD_FOR_EVENTS
$ sudo rabbitmqctl add_vhost taiga
$ sudo rabbitmqctl set_permissions -p taiga taiga ".*" ".*" ".*"


* 로그폴더 생성
$ mkdir -p ~/logs


[타이가 백엔드 셋업]

* 타이가 최신 백엔드 다운로드
$ cd ~
$ git clone https://github.com/taigaio/taiga-back.git taiga-back
$ cd taiga-back
$ git checkout stable


* 타이가 백엔드에서 사용할 Python3 용 가상환경 생성
$ cd ~
$ virtualenv -p python3 taiga-back_env


* Python3용 타이가 백엔드 의존 패키지 설치
$ cd ~
$ source taiga-back_env/bin/activate
$ cd taiga-back
$ pip install -r requirements.txt


* 디렉토리는 이동하지 말고 동일 디렉토리에서 백엔드 데이터베이스 초기화
$ python manage.py migrate --noinput
$ python manage.py loaddata initial_user
$ python manage.py loaddata initial_project_templates
$ python manage.py compilemessages
$ python manage.py collectstatic --noinput

이 조작으로 admin/123123 이라는 계정이 생성된다


* 초기설정파일 작성. 예를 들어 라즈베리파이의 IP는 192.168.0.25라 한다.
$ sudo nano ~/taiga-back/settings/local.py

[code]
from .common import *
 
MEDIA_URL = "http://192.168.0.25/media/"
STATIC_URL = "http://192.168.0.25/static/"
SITES["front"]["scheme"] = "http"
SITES["front"]["domain"] = "192.168.0.25"
 
SECRET_KEY = "theveryultratopsecretkey"
 
DEBUG = False
PUBLIC_REGISTER_ENABLED = False
 
DEFAULT_FROM_EMAIL = "no-reply@192.168.0.25"
SERVER_EMAIL = DEFAULT_FROM_EMAIL
 
#CELERY_ENABLED = True
 
EVENTS_PUSH_BACKEND = "taiga.events.backends.rabbitmq.EventsPushBackend"
EVENTS_PUSH_BACKEND_OPTIONS = {"url": "amqp://taiga:PASSWORD_FOR_EVENTS@localhost:5672/taiga"}
 
# Uncomment and populate with proper connection parameters
# for enable email sending. EMAIL_HOST_USER should end by @domain.tld
#EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
#EMAIL_USE_TLS = False
#EMAIL_HOST = "localhost"
#EMAIL_HOST_USER = ""
#EMAIL_HOST_PASSWORD = ""
#EMAIL_PORT = 25
 
# Uncomment and populate with proper connection parameters
# for enable github login/singin.
#GITHUB_API_CLIENT_ID = "yourgithubclientid"
#GITHUB_API_CLIENT_SECRET = "yourgithubclientsecret"
[/code]

* 백엔드 인스톨 검증
$ source ~/taiga-back_env/bin/activate
$ python ~/taiga-back/manage.py runserver

그러면 taiga 계정에서 서버가 시작되므로 putty등으로 추가적인 SSH 세션을 열어서 파이에 접속한다
$ ssh pi@192.168.0.25

그 후 추가 SSH 세션에서 다음 명령으로 서버가 응답하는지 확인한다. http://localhost:8000/api/v1/으로 시작하는 JSON 리스트를 받으면 성공이다.
$ curl -0 http://localhost:8000/api/v1/

서버응답을 확인했으면 SSH 세션을 닫고 컨트롤+C로 타이가 백엔드를 중지시킨다.


[타이가 프론트엔드 셋업]

* 타이가 프론트엔드 다운로드
$ cd ~
$ git clone https://github.com/taigaio/taiga-front-dist.git taiga-front-dist
$ cd taiga-front-dist
$ git checkout stable

설정파일을 작성한뒤 다음과 같이 수정한다.
$ cp ~/taiga-front-dist/dist/conf.example.json ~/taiga-front-dist/dist/conf.json
$ sudo nano ~/taiga-front-dist/dist/conf.json

[code]
{
    "api": "http://192.168.0.25/api/v1/",
    "eventsUrl": "ws://192.168.0.25/events",
    "eventsMaxMissedHeartbeats": 5,
    "eventsHeartbeatIntervalTime": 60000,
    "eventsReconnectTryInterval": 10000,
    "debug": true,
    "debugInfo": false,
    "defaultLanguage": "en",
    "themes": ["taiga"],
    "defaultTheme": "taiga",
    "publicRegisterEnabled": false,
    "feedbackEnabled": true,
    "supportUrl": "https://tree.taiga.io/support",
    "privacyPolicyUrl": null,
    "termsOfServiceUrl": null,
    "maxUploadFileSize": null,
    "contribPlugins": [],
    "tribeHost": null,
    "importers": [],
    "gravatar": true
    "rtlLanguages": ["fa"]
}
[/code]


[타이가 이벤트 세팅]
Taiga-events는 웹소켓 서버로, 타이가 프론트엔드가 백로그, 태스크보드, 칸반, 이슈리스팅의 변경을 리얼타임으로 보여줄 수 있게 한다. 이 서버는 RabbitMQ를 메시지 브로커로 이용한다.

* 타이가 이벤트 다운로드
$ cd ~
$ git clone https://github.com/taigaio/taiga-events.git taiga-events
$ cd taiga-events


* nodejs 인스톨
$ curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
$ sudo apt-get install -y nodejs


* npm이 같이 안깔릴 경우
$ sudo apt-get install npm
$ sudo npm install -g npm@latest


* 자바스크립트 의존모듈 인스톨
$ npm install
$ sudo npm install -g coffee-script


* 타이가 이벤트 환경설정파일 작성
$ cp config.example.json config.json
$ sudo nano config.json

[code]
{
    "url": "amqp://taiga:PASSWORD_FOR_EVENTS@localhost:5672/taiga",
    "secret": "theveryultratopsecretkey",
    "webSocketServer": {
        "port": 8888
    }
}
[/code]

"secret"의 키 내용은 ~/taiga-back/settings/local.py 에 작성한 "SECRET_KEY"와 동일해야 한다.


[슈퍼바이저에게 타이가 백엔드와 타이가 이벤트를 실행하도록 설정]
Supervisor라는 프로세스 컨트롤 시스템이 타이가 백엔드와 타이가 이벤트를 계속 실행하도록 설정한다.

* 슈퍼바이저가 타이가 백엔드를 실행하도록 구성
다음과 같은 내용의 배시파일을 작성한다.
$ nano ~/run_taiga_backend.sh

[code]
#!/bin/bash
 
source taiga-back_env/bin/activate
gunicorn -w 3 -t 60 --pythonpath=./taiga-back -b 127.0.0.1:8001 taiga-back.taiga.wsgi
deactivate
[/code]

유저 taiga가 실행할 수 있도록 퍼미션 변경
$ sudo chmod u+x ~/run_taiga_backend.sh

다음과 같은 내용의 슈퍼바이저 환경설정파일을 작성.
$ sudo nano /etc/supervisor/conf.d/taiga-back.conf

[code]
[program:taiga-back]
directory=/home/taiga
command=/bin/bash -E -c ./run_taiga_backend.sh
autostart=true
autorestart=true
stopsignal=INT
stopasgroup=true
killasgroup=true
stdout_logfile=/home/taiga/logs/taiga-back.stdout.log
stderr_logfile=/home/taiga/logs/taiga-back.stderr.log
user=taiga
[/code]

* 슈퍼바이저가 타이가이벤트를 실행하도록 설정
다음과 같은 내용의 설정파일을 작성한다.
$ sudo nano /etc/supervisor/conf.d/taiga-events.conf

[code]
[program:taiga-events]
directory=/home/taiga/taiga-events
command=/usr/bin/coffee index.coffee         
autostart=true
autorestart=true
stopsignal=INT
stopasgroup=true
killasgroup=true
stdout_logfile=/home/taiga/logs/taiga-events.stdout.log
stderr_logfile=/home/taiga/logs/taiga-events.stderr.log
user=taiga
[/code]

* 슈퍼바이저를 재시작
sudo systemctl restart supervisor.service


[Nginx가 타이가 프론트엔드, 백엔드, 이벤트를 관할하도록 설정]

다음과 같은 내용의 Nginx 가상호스트 설정파일을 작성
$ sudo nano /etc/nginx/sites-available/taiga.conf

[code]
server {
    listen 80 default_server;
    server_name _;
 
    large_client_header_buffers 4 32k;
    client_max_body_size 50M;
    charset utf-8;
 
    access_log /home/taiga/logs/nginx.access.log;
    error_log /home/taiga/logs/nginx.error.log;
 
    # Frontend
    location / {
        root /home/taiga/taiga-front-dist/dist/;
        try_files $uri $uri/ /index.html;
    }
 
    # Backend
    location /api {
        include proxy_params;
        proxy_set_header X-Scheme $scheme;
        proxy_pass http://127.0.0.1:8001/api;
        proxy_redirect off;
    }
 
    # Django admin access (/admin/)
    location /admin {
        include proxy_params;
        proxy_set_header X-Scheme $scheme;
        proxy_pass http://127.0.0.1:8001$request_uri;
        proxy_redirect off;
    }
 
    # Static files
    location /static {
        alias /home/taiga/taiga-back/static;
    }
 
    # Media files
    location /media {
        alias /home/taiga/taiga-back/media;
    }
 
    # Taiga-events
    location /events {
        proxy_pass http://127.0.0.1:8888/events;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }
}
[/code]


* sites-enabled 디렉토리에 가상호스트 설정파일의 심볼릭링크를 생성한다
$ sudo ln -s /etc/nginx/sites-available/taiga.conf /etc/nginx/sites-enabled/taiga.conf

* Nginx 서버 재시작
$ sudo systemctl restart nginx.service


[타이가를 외부에서 접속하기]
현재 상태에서 타이가는 192.168.0.25 IP로 내부내트워크에서 밖에 접속할 수 없다. yourdomain.com 이라는 도메인을 구입해서 사용하고 있고 taiga.yourdomain.com 이라는 주소로 타이가를 연결해서 사용해 보기로 한다.

* 타이가의 Nginx용 설정파일을 가상호스트용으로 바꾸고 다음과 같이 내용을 수정한다.
$ sudo mv /etc/nginx/sites-available/taiga.conf /etc/nginx/sites-available/taiga.yourdomain.com.conf

[code]
server {
    listen 80;
    server_name taiga.yourdomain.com;
 
    large_client_header_buffers 4 32k;
    client_max_body_size 50M;
    charset utf-8;
 
    access_log /home/taiga/logs/nginx.access.log;
    error_log /home/taiga/logs/nginx.error.log;
 
    # For ACME challenge
    location ~ /.well-known {
        root /home/taiga;
        allow all;
    }
 
    # Frontend
    location / {
        root /home/taiga/taiga-front-dist/dist/;
        try_files $uri $uri/ /index.html;
    }
 
    # Backend
    location /api {
        include proxy_params;
        proxy_set_header X-Scheme $scheme;
        proxy_pass http://127.0.0.1:8001/api;
        proxy_redirect off;
    }
 
    # Django admin access (/admin/)
    location /admin {
        include proxy_params;
        proxy_set_header X-Scheme $scheme;
        proxy_pass http://127.0.0.1:8001$request_uri;
        proxy_redirect off;
    }
 
    # Static files
    location /static {
        alias /home/taiga/taiga-back/static;
    }
 
    # Media files
    location /media {
        alias /home/taiga/taiga-back/media;
    }
 
    # Taiga-events
    location /events {
        proxy_pass http://127.0.0.1:8888/events;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }
}
[/code]


* 기존의 심볼릭링크를 삭제하고 새로운 파일에 대한 심볼릭링크를 작성한다
$ sudo rm /etc/nginx/sites-enabled/taiga.conf
$ sudo ln -s /etc/nginx/sites-available/taiga.yourdomain.com.conf /etc/nginx/sites-enabled/taiga.yourdomain.com.conf


* Nginx 서버를 재시작하면 이제 타이가는 http://taiga.yourdomain.com으로 접속할 수 있고, SSL 인증에 대한 ACME challenge를 통과할 수 있게 된다.
$ sudo systemctl restart nginx.service


[Lets's Encrypt의 인증서를 이용하여 HTTPS 프로토콜로 변경]
* SSL 인증서를 취득
$ sudo apt-get install letsencrypt
$ sudo certbot certonly --webroot --webroot-path=/home/taiga
-d taiga.yourdomain.com


* Diffie-Hellman group 생성
Nginx가 클라이언트와 암호화키를 주고받을 수 있도록 Diffie-Hellman group을 생성
$ sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048


* Nginx 설정파일을 다음과 같이 변경한다
$ sudo nano /etc/nginx/sites-enabled/taiga.yourdomain.com.conf

[code]
server {
    listen 80;
    server_name  taiga.yourdomain.com;
    return 301 https://$host$request_uri;
}
  
# For ssl
server {
    ssl on;
    ssl_certificate /etc/letsencrypt/live/taiga.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/taiga.yourdomain.com/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_dhparam /etc/ssl/certs/dhparam.pem;
    ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_stapling on;
    ssl_stapling_verify on;
    add_header Strict-Transport-Security max-age=15768000;
      
    default_type  application/octet-stream;
      
    listen 443;
    server_name  taiga.yourdomain.com;
  
    access_log /home/taiga/logs/nginx.access.log;
    error_log /home/taiga/logs/nginx.error.log;
 
    # For ACME challenge
    location ~ /.well-known {
        root /home/taiga;
        allow all;
    }
 
    # Frontend
    location / {
        root /home/taiga/taiga-front-dist/dist/;
        try_files $uri $uri/ /index.html;
    }
 
    # Backend
    location /api {
        include proxy_params;
        proxy_set_header X-Scheme $scheme;
        proxy_pass http://127.0.0.1:8001/api;
        proxy_redirect off;
    }
 
    # Django admin access (/admin/)
    location /admin {
        include proxy_params;
        proxy_set_header X-Scheme $scheme;
        proxy_pass http://127.0.0.1:8001$request_uri;
        proxy_redirect off;
    }
 
    # Static files
    location /static {
        alias /home/taiga/taiga-back/static;
    }
 
    # Media files
    location /media {
        alias /home/taiga/taiga-back/media;
    }
 
    # Taiga-events
    location /events {
        proxy_pass http://127.0.0.1:8888/events;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_connect_timeout 7d;
        proxy_send_timeout 7d;
        proxy_read_timeout 7d;
    }
}
[/code]


* Nginx를 재시작한다
$ sudo systemctl restart nginx.service


[새로운 URL 세팅에 대해 타이가 프론트엔드와 백엔드의 설정변경]

* 백엔드의 설정을 다음과 같이 변경한다
$ sudo nano ~/taiga-back/settings/local.py

[code]
from .common import *
 
MEDIA_URL = "https://taiga.yourdomain.com/media/"
STATIC_URL = "https://taiga.yourdomain.com/static/"
SITES["front"]["scheme"] = "https"
SITES["front"]["domain"] = "taiga.yourdomain.com"
 
SECRET_KEY = "theveryultratopsecretkey"
 
DEBUG = False
PUBLIC_REGISTER_ENABLED = False
 
DEFAULT_FROM_EMAIL = "no-reply@example.com"
SERVER_EMAIL = DEFAULT_FROM_EMAIL
 
#CELERY_ENABLED = True
 
EVENTS_PUSH_BACKEND = "taiga.events.backends.rabbitmq.EventsPushBackend"
EVENTS_PUSH_BACKEND_OPTIONS = {"url": "amqp://taiga:PASSWORD_FOR_EVENTS@localhost:5672/taiga"}
 
# Uncomment and populate with proper connection parameters
# for enable email sending. EMAIL_HOST_USER should end by @domain.tld
#EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
#EMAIL_USE_TLS = False
#EMAIL_HOST = "localhost"
#EMAIL_HOST_USER = ""
#EMAIL_HOST_PASSWORD = ""
#EMAIL_PORT = 25
 
# Uncomment and populate with proper connection parameters
# for enable github login/singin.
#GITHUB_API_CLIENT_ID = "yourgithubclientid"
#GITHUB_API_CLIENT_SECRET = "yourgithubclientsecret"
[/code]


* 프론트엔드의 설정을 다음과 같이 변경한다
$ sudo nano ~/taiga-front-dist/dist/conf.json

[code]
{
    "api": "https://taiga.yourdomain.com/api/v1/",
    "eventsUrl": "wss://taiga.yourdomain.com/events",
    "eventsMaxMissedHeartbeats": 5,
    "eventsHeartbeatIntervalTime": 60000,
    "eventsReconnectTryInterval": 10000,
    "debug": true,
    "debugInfo": false,
    "defaultLanguage": "en",
    "themes": ["taiga"],
    "defaultTheme": "taiga",
    "publicRegisterEnabled": false,
    "feedbackEnabled": true,
    "supportUrl": "https://tree.taiga.io/support",
    "privacyPolicyUrl": null,
    "termsOfServiceUrl": null,
    "maxUploadFileSize": null,
    "contribPlugins": [],
    "tribeHost": null,
    "importers": [],
    "gravatar": true
}
[/code]


* 슈퍼바이저를 재시작하면 https로 접속되는것을 확인할 수 있다.
$ sudo systemctl restart supervisor.service


[타이가에서 email 통지를 보낼수 있도록 설정]

* Postfix를 설치한다
$ sudo apt-get install -y postfix


* Postfix 설치시 팝업에 대해서는 다음과 같이 입력한다
Genaral type of mail configuration: Internet Site
System mail name: taiga.yourdomain.com


* 타이가 백엔드 설정을 다음과 같이 변경한다
$ sudo nano ~/taiga-back/settings/local.py

[code]
from .common import *
 
MEDIA_URL = "https://taiga.yourdomain.com/media/"
STATIC_URL = "https://taiga.yourdomain.com/static/"
SITES["front"]["scheme"] = "https"
SITES["front"]["domain"] = "taiga.yourdomain.com"
 
SECRET_KEY = "theveryultratopsecretkey"
 
DEBUG = False
PUBLIC_REGISTER_ENABLED = False
 
DEFAULT_FROM_EMAIL = "no-reply@taiga.yourdomain.com"
SERVER_EMAIL = DEFAULT_FROM_EMAIL
 
#CELERY_ENABLED = True
 
EVENTS_PUSH_BACKEND = "taiga.events.backends.rabbitmq.EventsPushBackend"
EVENTS_PUSH_BACKEND_OPTIONS = {"url": "amqp://taiga:PASSWORD_FOR_EVENTS@localhost:5672/taiga"}
 
# Uncomment and populate with proper connection parameters
# for enable email sending. EMAIL_HOST_USER should end by @domain.tld
EMAIL_BACKEND = "django.core.mail.backends.smtp.EmailBackend"
EMAIL_USE_TLS = False
EMAIL_HOST = "localhost"
EMAIL_HOST_USER = ""
EMAIL_HOST_PASSWORD = ""
EMAIL_PORT = 25
 
# Uncomment and populate with proper connection parameters
# for enable github login/singin.
#GITHUB_API_CLIENT_ID = "yourgithubclientid"
[/code]


* 슈퍼바이저를 재시작한다
$ sudo systemctl restart supervisor.service


[업데이트]
* taiga 유저로그인
$ sudo su taiga

* 프론트엔드 업데이트
$ cd ~/taiga-front-dist
$ git checkout stable
$ git pull

* 백엔드 업데이트
$ cd ~/taiga-back
$ git checkout stable
$ git pull

* 백엔드 파이썬패키지 업데이트
$ cd ~
$ source taiga-back_env/bin/activate
$ cd taiga-back
$ pip install -r requirements.txt

* 디렉토리는 이동하지 말고 동일 디렉토리에서 백엔드 데이터베이스 리셋
$ python manage.py migrate --noinput
$ python manage.py compilemessages
$ python manage.py collectstatic --noinput

* 프로세스 매니저 리셋
$ sudo systemctl restart supervisor.service
$ sudo systemctl restart nginx.service
2020/01/13 19:41 2020/01/13 19:41