Установка exchanger-web
Prepare dependencies
apt install -y nano sudo curl wget
apt update
apt upgrade -y1. Install Docker and Docker Compose
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh2. Create runner user and add it to sudoers
sudo adduser --disabled-password --gecos "" runner
sudo usermod -aG sudo runner3. Create docker group and add user to it
sudo usermod -aG docker runner4. Switch to a 'runner' user
sudo su runnernewgrp docker5. Create docker network
docker network create --subnet 10.1.0.0/24 exchanger-net6. Docker login
- Create a Personal Access Token in GitLab 
- Make sure to tick the - read_registrypermission scope
- Create a reminder to update the PAT after expiration date, as once it expires you lose access for updates. https://git.boxexchanger.net/-/profile/personal_access_tokens 
- Login to docker read_registry - docker login rg.boxexchanger.net # Username: your_gitlab_username # Password: your_gitlab_pat
7. Create required folders
mkdir -p /home/runner/web_server
mkdir -p /home/runner/web_server/config
mkdir -p /home/runner/web_server/public
mkdir -p /home/runner/web_server/nginx
cd /home/runner/web_server8. Place basic nginx config server_names_hash_bucket_size.conf
server_names_hash_bucket_size.confnano /home/runner/web_server/nginx/server_names_hash_bucket_size.confwith content:
server_names_hash_bucket_size 64;9. Place basic nginx config nginx_default.conf
nginx_default.confnano /home/runner/web_server/nginx/nginx_default.conf with content:
server {
    listen 80 default_server;
    server_name _;
    return 500;
}10. Place Nginx nginx_admin.conf config
nginx_admin.conf confignano /home/runner/web_server/nginx/nginx_admin.confmap $http_upgrade $connection_upgrade {
    default upgrade;
    ""      close;
}
server {
    listen 80;
    server_name admin.domain.name;
    location / {
        proxy_pass http://exchanger-admin-web:80;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    
    location /service/ {
        proxy_pass http://nginx-api:3000/service/;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    location /ws/ {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://nginx-api:3000/ws/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_redirect    off;
    }
    
    access_log off;
    error_log  /var/log/nginx-admin-error.log error;
    sendfile off;
    client_max_body_size 100m;
}11.  Place Nginx nginx_web.conf config
nginx_web.conf confignano /home/runner/web_server/nginx/nginx_web.confmap $http_upgrade $connection_upgrade {
    default upgrade;
    ""      close;
}
server {
    listen 80;
    server_name domain.name;
    return 301 https://www.domain.name$request_uri;
}
server {
    listen 80;
    server_name www.domain.name;
    location / {
        proxy_pass http://exchanger-client-web:80;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    location /service/ {
        proxy_pass http://nginx-api:3000/service/;
        proxy_http_version 1.1;
        add_header CF-IPCountry $http_cf_ipcountry always;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    location /ref/ {
        proxy_pass http://nginx-api:3000/service/ref/;
        proxy_http_version 1.1;
        add_header CF-IPCountry $http_cf_ipcountry always;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    location /ws/ {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://nginx-api:3000/ws/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_redirect    off;
    }
        
    access_log off;
    error_log  /var/log/nginx-error.log error;
    sendfile off;
    client_max_body_size 100m;
}12. Create config file (.env)
nano /home/runner/web_server/.envVCS_NAMESPACE=bx4/project-name12.  Create your docker-compose.yml
nano /home/runner/web_server/docker-compose.ymlversion: '3'
services:
  nginx-web:
    image: nginxinc/nginx-unprivileged:1.27-alpine
    read_only: true
    container_name: nginx-web
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.250
    volumes:
      - ./nginx/:/etc/nginx/conf.d:ro
      - type: tmpfs
        target: /docker-entrypoint.d/
        tmpfs:
          size: "100000"
      - type: tmpfs
        target: /tmp/
        tmpfs:
          size: "10000000"
  exchanger-admin-web:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-admin-web:${ADMIN_BRANCH:-master}
    container_name: exchanger-admin-web
    restart: unless-stopped
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.5
  exchanger-client-web:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-client-web:${CLIENT_BRANCH:-box}
    container_name: exchanger-client-web
    restart: unless-stopped
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.4
networks:
    exchanger-net:
        external: true13.  Start WEB server
docker compose up -dServer Side Render:
- Attention! This mod is not recommended for use; it creates a load on the server to build the project for each client, which greatly increases the delay in loading the site 
To enable SSR mode add variable SSR = 1 in your account https://licence.boxexchanger.net/licenses/ then run pipeline for build project and fetch build on your server.
1. Подготовка окружения
После установки сервера к нему необходимо подключиться по SSH и настроить окружение
Установить пакеты сервера (nano git curl)
apt update
apt upgrade -y
apt-get install -y curl git nano wget sudoУстановить  Nginx: 
apt-get install -y nginxУстановить NodeJS:
Установка NodeJs2. Скачать ПО на сервер
Создаем SSH-ключ
Документация с github.com Создание нового ключа SSH
Учебник по Linux
ssh-keygen -t rsa -b 4096> Enter x3
eval "$(ssh-agent -s)"ssh-add ~/.ssh/id_rsaПолучить свой ключ:
cat ~/.ssh/id_rsa.pubСкопируйте результат и установите данный ключ в своей учётной записи git.boxexchanger.net
Доступ к исходному кодуКлонируем репозитории
cd /var/www/git clone [email protected]:bx4/NAME_SPACE/exchanger-client-web.gitgit clone [email protected]:bx4/NAME_SPACE/exchanger-admin-web.git3. Сборка админ панели
cd /var/www/exchanger-admin-web/npm inpm run configureСконфигурируйте конфигурацию:
nano .envADMIN_BASE_URL="https://admin.domain.name"
EXCHANGE_URL="https://www.domain.name"
PROXY_REST_API="http://localhost:3010/"Сборка проекта:
npm run generate4. Сборка веб-панели
cd /var/www/exchanger-client-web/npm inpm run configureСконфигурируйте конфигурацию: (при возникновении затруднений обратитесь в техподдержку [email protected])
nano config/app.jsonСборка проекта:
npm run generate5. Применяем Nginx конфигурацию
nano /etc/nginx/sites-enabled/domain.com.confmap $http_upgrade $connection_upgrade {
    default upgrade;
    ""      close;
}
server {
    listen 80;
    server_name domain.com;    return 301 https://www.domain.com$request_uri;
}
server {
    listen 80;
    server_name www.domain.com;
    root "/var/www/exchanger-client-web";
    gzip on;
    gzip_comp_level 9;
    gzip_disable "msie6";
    gzip_types application/javascript text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    index index.html;
    charset utf-8;
    add_header "X-Frame-Options" "SAMEORIGIN";
    add_header "X-XSS-Protection" "1; mode=block";
    add_header "X-Content-Type-Options" "nosniff";
    location / {
        root /var/www/exchanger-client-web/dist/client;
        rewrite ^([^.]*[^/])$ $1/ permanent;
        try_files $uri $uri/ /200.html;
        # expires 7d;
    }
    access_log off;
    error_log  /var/www/exchanger-client-web/nginx-error.log error;
    sendfile off;
    client_max_body_size 100m;
    location /service/ {
        proxy_pass http://127.0.0.1:3010/;
        proxy_http_version 1.1;
        add_header CF-IPCountry $http_cf_ipcountry always;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    location /ref/ {
        proxy_pass http://nginx-api:3010/ref/;
        proxy_http_version 1.1;
        add_header CF-IPCountry $http_cf_ipcountry always;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    location /service/fs {
        alias /var/www/exchanger-api/public;
    }
    location /tg/ {
        proxy_pass http://127.0.0.1:3003/;
        proxy_http_version 1.1;
        add_header CF-IPCountry $http_cf_ipcountry always;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    #location /service/fs {
    #    alias /var/www/exchanger-api/public;
    #}
    location /ws/ {
        proxy_http_version 1.1;
        add_header CF-IPCountry $http_cf_ipcountry always;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://127.0.0.1:3011/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $host;
        proxy_set_header X-Forwarded-Server $host;
        proxy_redirect    off;
    }
}
server {
    listen 80;
    server_name admin.domain.com;
    root "/var/www/exchanger-admin-web";
    gzip on;
    gzip_comp_level 9;
    gzip_disable "msie6";
    gzip_types application/javascript text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
    index index.html index.htm index.php;
    charset utf-8;
    add_header "X-Frame-Options" "DENY";
    add_header "X-XSS-Protection" "1; mode=block";
    add_header "X-Content-Type-Options" "nosniff";
    location / {
        root /var/www/exchanger-admin-web/dist/admin;
        try_files $uri $uri/ /index.html;
    }
    access_log off;
    error_log  /var/www/exchanger-admin-web/nginx-error.log error;
    sendfile off;
    client_max_body_size 100m;
    location /service/ {
        proxy_pass http://127.0.0.1:3010/;
        proxy_http_version 1.1;
        add_header CF-IPCountry $http_cf_ipcountry always;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_redirect off;
    }
    location /service/fs {
        alias /var/www/exchanger-api/public;
    }
}Тестируем nginx конфигурацию:
nginx -t Применяем изменения:
service nginx restartLast updated
Was this helpful?
