> For the complete documentation index, see [llms.txt](https://undefined-291.gitbook.io/tooliv-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://undefined-291.gitbook.io/tooliv-docs/guides/deployment.md).

# Deployment

{% hint style="info" %}
**Good to know:**&#x20;

본 가이드 문서는 Enterprise Edition 설치를 위해 제공됩니다.

가이드를 따라 설치하기 위 사전 준비 항목이 있습니다.

* Ubuntu 서버 (20.04)
* 서버 도메인  ex) example.com

Ubuntu 20.04 기준으로 작성되었으니,

원활한 설치를 위해 같은 버전으로 서버를 준비하는 것을 권장합니다.
{% endhint %}

* [Instruction](#deployment-instructions)
* [Prerequisites](#prerequisites)
* [Install Certbot](#install-certbot)
* [Clone Git](#clone-git)
* [Execute Shell script](#execute-shell-script)
* [Configuration Gradle](#configuration-gradle)&#x20;
* [Install Redis](#install-redis)
* [Install OpenVidu](#install-openvidu)
* [Install MySQL and Create Database](#install-mysql-and-create-database)
* [Build And Run Project](#build-project)

## Instruction <a href="#deployment-instructions" id="deployment-instructions"></a>

* EC2 혹은 Lightsail 등으로 이용 가능한 Ubuntu 서버가 필요합니다.

  * 원활한 설치를 위해 서버 기본 상태에서 시작하는 것을 권장합니다.

* TOOLIV Community Edition 서버 사양은 다음과 같습니다.

  최소한 아래 명시 사양 이상의 서버를 사용해서 설치할 것을 권장합니다.

  * Memory 16GB
  * 4 vCPUs (4 코어)
  * Storage(EBS Volume) 10GB 이상

## Prerequisites

원활한 설치와 설정을 위해 root 권한으로 진행합니다.

```shell
sudo su
```

ubuntu 에서 설치 가능한 패키지 리스트를 업데이트합니다.&#x20;

```shell
apt update
```

TOOLIV 배포에 필요한 여러 패키지를 설치합니다.

* **vim 에디터 설치**
  * 파일을 수정하기 위해 vim을 설치합니다.

```
apt install -y vim
```

* **git 설치**
  * TOOLIV Github를 클론 받기 위해 설치합니다.

```
apt install git
```

* **nodejs 설치**
  * client 프로젝트 빌드를 위해 nodejs 및 npm을 설치합니다.

```
curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
apt-get install -y nodejs
```

* **NGINX 설치**
  * 리버스 프록시 NGINX 서버를 설치합니다.

```
apt install -y nginx
```

NGINX 설정 파일을 letsencrypt - certbot 에서 자동 설정할 수 있도록 구동시킵니다.

```shell
service nginx start
```

TOOLIV은 **`React client`**, **`Spring Boot Server`**, **`OpenVidu`**, **`redis`** 및 **`NGINX`**&#xB97C; 사용하므로

아래 항목들에 대한 **`인바운드 규칙`**&#xC744; 설정해줍니다.&#x20;

|    **TCP**    |    **UDP**    |
| :-----------: | :-----------: |
|       22      |               |
|       80      |               |
|      443      |               |
|      3000     |               |
|      3478     |      3478     |
|      8443     |               |
| 40000 - 57000 | 40000 - 57000 |
| 57001 - 65535 | 57001 - 65535 |

## Install Certbot

{% hint style="info" %}
`본 가이드는`` `**`Ubuntu 20.04.4`** 기준으로 작성된 예시입니다. &#x20;

Certbot 설치 관련하여 자세한 내용을 확인하고 싶다면,

[certbot.eff.org](https://certbot.eff.org/) 혹은 [Certbot 참고문서](https://eff-certbot.readthedocs.io/en/stable/install.html#certbot-auto) 확인해주세요.
{% endhint %}

Certbot 설치를 위해 snap을 이용하여 core를 설치합니다. core는 snap 최신 버전을 유지하기 위해 설치합니다.&#x20;

```shell
snap install core
snap refresh core
```

만약 기존에 Certbot이 설치되어 있다면 Certbot을 삭제합니다.

```shell
apt remove certbot
```

snap을 이용하여 Certbot을 설치합니다.

```shell
snap install --classic certbot
```

Certbot 명령을 로컬에서 실행할 수 있도록 연결시켜줍니다.

```
ln -s /snap/bin/certbot /usr/bin/certbot
```

아래 명령어를 실행하여 Certbot을 이용해 SSL 인증서를 받아온 후, Certbot이 NGINX를 설정합니다.

```shell
certbot --nginx
```

서버 환경에 맞도록 NGINX를 설정합니다.

```shell
vim ${path}/etc/nginx/sites-available/default
```

아래 내용은 참고할 만한 예시입니다. ( etc/nginx/sites-available/default - 443 server 블록 ) &#x20;

포트 번호는 그대로 이용하는 것을 권장합니다.&#x20;

```shell
location / {
    proxy_pass http://도메인:클라이언트 컨테이너 포트(ex: 3000);
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}    
	
location /api/ {
    proxy_pass https://도메인:서버 컨테이너 포트(ex: 8443);
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /chatting/ {
    proxy_pass https://도메인:서버 컨테이너 포트(ex: 8443);
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

location /openvidu/ {
    proxy_pass https://도메인:오픈비두 HTTPS 포트(ex: 4443);
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

```

발급받은 SSL을 서버에 적용하기 위해 `tooliv.p12` 파일을 export 합니다.&#x20;

```shell
openssl pkcs12 -export -in ${path}/etc/letsencrypt/live/{도메인}/cert.pem -inkey ${path}/etc/letsencrypt/live/{도메인}/privkey.pem -out tooliv.p12 -CAfile ${path}/etc/letsencrypt/live/{도메인}/chain.pem -caname root
```

추가로 비밀번호 입력하는 창이 나면 tooliv.p12 키에 대한 비밀번호를 입력합니다.

{% hint style="info" %}
비밀번호는 [Build And Run Project](#build-and-run-project) 과정에서 필요한 정보로, 메모해두시기 바랍니다.
{% endhint %}

## Clone Github repository

[Github Tooliv repogitory](https://github.com/TOOLIV/tooliv)에서 오픈소스 코드를 clone 받아옵니다. ( home/ubuntu 경로에서 실행 )&#x20;

```shell
git clone https://github.com/TOOLIV/Tooliv.git
```

**`server`** 프로젝트 폴더 내에 있는 **`tooliv.p12`** 파일을 삭제합니다.&#x20;

```shell
rm -rf ${path}/home/ubuntu/Tooliv/server/src/main/resources/keystore/tooliv.p12
```

생성한 **`tooliv.p12`** 파일을 프로젝트 내 폴더로 복사합니다.

```shell
cp ${path}/home/ubuntu/tooliv.p12 ${path}/home/ubuntu/Tooliv/server/src/main/resources/keystore
```

## Execute Shell script

TOOLIV 배포에 필요한 패키지를 자동으로 설치하고, 필요한 Docker 볼륨과 네트워크를

편리하게 생성하기 위해 shell script 파일을 **`home/ubuntu`** 경로로 가져옵니다.

```
cp ${path}/home/ubuntu/Tooliv/tooliv-install.sh ${path}/home/ubuntu
```

`tooliv-install.sh` 파일에 실행 권한을 부여합니다.

```
chmod 755 ${path}/home/ubuntu/tooliv-install.sh
```

`tooliv-install.sh` 파일을 실행하여 패키지 설치 및 환경설정을 자동으로 실행합니다.

```shell
${path}/home/ubuntu/tooliv-install.sh
```

* **설치 항목**

  * OpenJDK 8
  * Gradle 7.4
  * Docker
  * Docker-compose

* **실행 내용**
  * docker | tooliv-network 생성
  * docker | tooliv-volume 생성
  * docker | tooliv-db-volume 생성

## Configure Gradle&#x20;

Gradle의 bin 디렉토리를 포함하도록 PATH 환경변수를 설정합니다.&#x20;

`gradle.sh` 파일을 생성합니다.

```shell
vim ${path}/etc/profile.d/gradle.sh
```

`gradle.sh` 내부에 아래 내용을 입력합니다.&#x20;

```shell
export GRADLE_HOME=/opt/gradle/latest
export PATH=${GRADLE_HOME}/bin:${PATH}
```

생성한 `gradle.sh` 파일에 실행 권한을 부여합니다.

```shell
chmod +x ${path}/etc/profile.d/gradle.sh
```

명령어를 입력하여 환경변수를 로딩합니다.&#x20;

```shell
. ${path}/etc/profile.d/gradle.sh
```

## Install Redis

{% hint style="info" %}
TOOLIV 채팅 기능은 빠른 데이터 조회를 위해 Redis를 이용합니다.&#x20;
{% endhint %}

아래 명령어를 통해`redis-container`를 구동시킵니다.&#x20;

( 예시 명령어 그대로 입력해서 포트 번호를 동일하게 실행하는 것을 권장합니다. )&#x20;

```shell
docker run --network tooliv-network -d --name redis-container -p 6380:6380 -dit --restart unless-stopped redis
```

`redis-container` host 정보를 확인하기 위해 `tooliv-network` 정보를 조회합니다.

```shell
docker inspect tooliv-network  
```

<div align="center"><img src="/files/RUwWEsgeKwIPN5plWD1j" alt="redis-container host 확인 예시"></div>

{% hint style="info" %}
host 정보는 [Build And Run Project](#build-and-run-project) 과정에서 필요한 정보로, 메모해두시기 바랍니다.
{% endhint %}

## Install OpenVidu

{% hint style="info" %}
TOOLIV 화상회 기능은 OpenVidu 오픈소스 프로젝트를 이용합니다.
{% endhint %}

OpenVidu 설치 위해 `/opt` 폴더로 이동합니다. &#x20;

```shell
cd ${path}/opt
```

아래 명령어를 실행하면 OpenVidu가 다운로드되고 설치 스크립트가 동작합니다.

`openvidu` 폴더에 필요한 모든 파일이 다운로드됩니다.&#x20;

```shell
curl https://s3-eu-west-1.amazonaws.com/aws.openvidu.io/install_openvidu_latest.sh | bash
```

`openvidu` 폴더로 이동합니다.

```shell
cd openvidu
```

OpenVidu 내부적으로도 NGINX를 사용하고 있기 때문에 충돌을 방지하기 위해서 NGINX 실행을 멈춥니다.

```shell
service nginx stop
```

OpenVidu 초기 설정을 위해 환경변수를 다음과 같이 수정합니다.&#x20;

```shell
vim .env
```

* 환경변수 속성
  * **`DOMAIN_OR_PUBLIC_IP`** : 도메인네임 또는 Public IP를 작성합니다.&#x20;
  * **`OPENVIDU_SECRET`** : OpenVidu 서버에 연결하기 위해 사용됩니다. (<mark style="color:red;">**`TOOLIV`**</mark> 작성)
  * **`CERTIFICATE_TYPE`** : letsencrypt로 설정하여 유효한 인증서를 자동 생성합니다.
  * **`LETSENCRYPT_EMAIL`** : 이메일을 입력합니다.&#x20;

```shell
# Domain name. If you do not have one, the public IP of the machine.
# For example: 198.51.100.1, or openvidu.example.com
DOMAIN_OR_PUBLIC_IP={도메인}
OPENVIDU_SECRET=TOOLIV
CERTIFICATE_TYPE=letsencrypt
LETSENCRYPT_EMAIL={이메일}
HTTP_PORT=80 
HTTPS_PORT=443
```

![OpenVidu 초기 설정 화면](/files/UojEg9g02JKvGcRxSauh)

속성 값을를 모두 입력하였으면 vim 창을 저장  종료합니다. (esc + : wq!) &#x20;

OpenVidu를 start하여 초기 설정을 완료합니다.

```
./openvidu start
```

**실제 TOOLIV 서비스에서 사용할 PORT 번호**를 OpenVidu 환경 변수에 다시 매핑합니다.

```shell
vim .env
```

**`HTTP_PORT`**, **`HTTPS_PORT`** 2가지 속성 값을 변경합니다.

( 가능한 동일한 설치 환경을 구성하기 위해 예시대로 작성하는 것을 권장합니다. )

```shell
# Domain name. If you do not have one, the public IP of the machine.
# For example: 198.51.100.1, or openvidu.example.com
DOMAIN_OR_PUBLIC_IP={도메인}
OPENVIDU_SECRET=TOOLIV
CERTIFICATE_TYPE=letsencrypt
LETSENCRYPT_EMAIL={이메일}
HTTP_PORT=4442
HTTPS_PORT=4443
```

![실제 사용할 PORT 번호를 다시 설정해 준 화면](/files/VeYGkmSXAl6pZ4ci8oEH)

변경을 완료했으면 OpenVidu 설정을 마치고 다시 구동시킵니다.

```
./openvidu restart 
```

이제 OpenVidu 설치 및 설정이 끝났습니다.

OpenVidu 작업을 위해 종료했던 NGINX를 다시 구동시키고, 홈 디렉토리로 이동합니다.

```shell
service nginx start
cd ${path}/home/ubuntu
```

## Install MySQL and Create Database

TOOLIV Server를 이용하기 위해서는 MySQL 데이터베이스가 필요합니다. 사용자의 환설정에 맞게 5.7 버전을 설정하고 컨테이너로 구동시킵니다.&#x20;

아래 예시는 `toolv-db-volume` 을 사용하여 `tooliv-db` 라는 이름으로 컨테이너를 구동시키고 `tooliv_db` 스키마를 생성하는 예시 명령어입니다.&#x20;

```shell
docker run --network tooliv-network -v tooliv-db-volume:/var/lib/mysql --name tooliv-db -e MYSQL_ROOT_PASSWORD={패스워드} -e TZ=Asia/Seoul -d mysql:5.7
docker exec -it tooliv-db bash
mysql -u root -p
패스워드 입력 
create database if not exists tooliv_db collate utf8mb4_general_ci;
```

{% hint style="info" %}
컨테이너 이름, root 계정 패스워드 및 스키마 이름은 사용자가 직접 설정하면 됩니다.&#x20;

**추후 환경설정 시 필요한 정보로, 메모해두시기 바랍니다.**
{% endhint %}

## Build And Run Project

clone 받은 client 프로젝트를 Docker Image 빌드합니다.&#x20;

* Docker Image : tooliv-client:lts

```shell
cd ${path}/home/ubuntu/Tooliv/client
docker build -t tooliv-client:lts .
```

[Install Certbot](#install-certbot) 과정 중 NGINX에서 설정한 대로 client 컨테이너를 해당 포트 번호로 실행합니다.

가이드대로 진행을 했다면 `포트 번호 3000`을 그대로 실행하면 됩니다.&#x20;

```
docker run --network tooliv-network --name tooliv-client -p 3000:3000 -d tooliv-client:lts 
```

clone 받은 server 프로젝트를 Docker Image 빌드합니다.

* Docker Image : tooliv-server:lts

```shell
cd ../server
gradle wrapper clean build -x test
docker build -t tooliv-server:lts .
```

위에서 빌드한 Docker Image를 이용하여 client server 컨테이너를 구동시킵니다.

사진 및 파일을 저장하는 AWS S3 Bucket은 별도의 설정을 하지 않는 경우, Tolliv Bucket을 사용하게 됩니다. 파일을 기업에서 별도로 관리하고 싶은 경우에는 자체 AWS S3 Bucket을 생성하고 `access_key`, `secret_key`, `bucket_name`, `aws_region` 정보를 기입하여 사용할 수 있습니다.

* 환경변수 속성

  * **`db_container_name`** : tooliv-db (별도로 설했다면 해당 database 컨테이너명)&#x20;
  * **`db_schema_name`** : tooliv\_db (별도로 설정했다면 해당 database명)
  * **`database_username`** : root (다 계정을 추가했다면 root 혹은 해당 username)
  * **`database_password`** : 패스워드
  * **`aws_accesskey`** : S3 Bucket 생성 시 발급된 access key
  * **`aws_secret_key`** : S3 Bucket 생성 시 발급된 secret key
  * **`bucket_name`** : S3 Bucket 명
  * **`aws_region`** : S3 Bucket region (예시: ap-northeast-2)
  * **`ssl_key_password`** : letsencrypt certbot 을 이용하여 생성한 SSL 비밀번호
  * **`redis-container_host`** : [Install Redis](#install-redis) 과정에 확인한 redis-container host IP
  * **`redis-container_port`** : 6379 (별도로 설정했다면 해당 port)

{% tabs %}
{% tab title="자체 S3 Bucket을 사용할 경우" %}

```shell
docker container run --network tooliv-network --name tooliv-server 
-e JAVA_TOOL_OPTIONS="-Dspring.profiles.active=prod"
-e "SPRING.DATASOURCE.URL=jdbc:mysql://{db_container_name}/{db_schema_name}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Seoul&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true" 
-e "SPRING.DATASOURCE.HIKARI.USERNAME={database_username}" 
-e "SPRING.DATASOURCE.HIKARI.PASSWORD={database_password}" 
-e "CLOUD.AWS.CREDENTIALS.ACCESSKEY={aws_access_key}"
-e "CLOUD.AWS.CREDENTIALS.SECRETKEY={aws_secret_key}"
-e "CLOUD.AWS.S3.BUCKET={bucket_name}"
-e "CLOUD.AWS.region.static={aws_region}"
-e "SERVER.SSL.KSY-STORE-PASSWORD={ssl_key_password}"
-e "SPRING.REDIS.HOST={redis-container_host}"
-e "SPRING.REDIS.PORT={redis-container_port}"
-p 8443:8443 -d tooliv-server:lts
```

{% endtab %}

{% tab title="TOOLIV 제공 S3 Bucket을 사용할 경우" %}

```shell
docker container run --network tooliv-network --name tooliv-server 
-e JAVA_TOOL_OPTIONS="-Dspring.profiles.active=prod"
-e "SPRING.DATASOURCE.URL=jdbc:mysql://{db_container_name}/{db_schema_name}?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Seoul&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true" 
-e "SPRING.DATASOURCE.HIKARI.USERNAME={database_username}" 
-e "SPRING.DATASOURCE.HIKARI.PASSWORD={database_password}"
-e "SERVER.SSL.KSY-STORE-PASSWORD={ssl_key_password}"
-e "SPRING.REDIS.HOST={redis-container_host}"
-e "SPRING.REDIS.PORT={redis-container_port}"
-p 8443:8443 -d tooliv-server:lts
```

{% endtab %}
{% endtabs %}

## Ready To Use

정상적으로 설치를 완료했으면 관리자 계정으로 접속해서 TOOLIV을 이용할 수 있습니다.

관리자 계정은 최초 1회 자동으로 생성해드리고 있으니, 접속 후 비밀번호를 변경하고 이용 부탁드립니다.

{% hint style="info" %}
관리자 계정 :  <admin@tooliv.io>

비밀번호      :  a12345678!@
{% endhint %}
