Установка exchanger-api

Установка Rest-API на собственные сервера доступна только при покупке полной лицензии ПО BoxExchanger

Prepare dependencies

apt update
apt upgrade -y
apt install -y nano sudo curl wget

1. Install Docker and Docker Compose

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

2. Create runner user and add it to sudoers

sudo adduser --disabled-password --gecos "" runner
sudo usermod -aG sudo runner

3. Create docker group and add user to it

sudo usermod -aG docker runner

4. Switch to a 'runner' user

sudo su runner
newgrp docker

5. Create docker network

docker network create --subnet 10.1.0.0/24 exchanger-net
docker network create --subnet 10.255.255.0/24 control-net

6. Docker login

  • Create a Personal Access Token in GitLab

  • Make sure to tick the read_registry permission 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/api_server
mkdir -p /home/runner/api_server/config
mkdir -p /home/runner/api_server/public
mkdir -p /home/runner/api_server/pluginsExternal
cd /home/runner/api_server

8. Create your configurations (.env)

nano /home/runner/api_server/.env
PROJECT_NAME=""
API_URL="https:///service/"
REDIS_URI="redis://exchanger-api-redis:6379/0"
UPLOADER_URL="http://exchanger-uploader-service:3013/"
VCS_NAMESPACE=""

8.1 Create your docs configuration (.env.docs.config.js)

nano /home/runner/api_server/.env.docs.config.js
const e = {
    PROJECT_NAME:"",
    BASE_URL:"https://",
    API_PATH:"/service/api/v1",
    API_URL:"https:///service/api/v1/",
};
export {e as config};

8.2 Create your lifecycle manager secret (.env.lm)

nano /home/runner/api_server/.env.lm
DOCKER_LIFECYCLE_MANAGER_URL=http://exchanger-lifecycle-manager:8000/
DOCKER_LIFECYCLE_MANAGER_KEY=932a4dd476573c9b7d39d932d1b2bc04f01b0b028d7e2475567eb849ea3002db

9. Create nginx configuration for api

Create /home/runner/api_server/nginx_api.conf file with following contents

nano /home/runner/api_server/nginx_api.conf
map $http_upgrade $connection_upgrade {
    default upgrade;
    ""      close;
}

log_format cf_custom '$remote_addr - $remote_user [$time_local] "$request" '
                     '$status $body_bytes_sent "$http_referer" '
                     '"$http_user_agent" "$http_x_forwarded_for" '
                     '"$http_cf_ray" "$http_cf_connecting_ip"';
server {
    listen 3000;
    server_tokens off;
    server_name default;

    location /service/ {
        proxy_pass http://exchanger-api-http:3010/;
        proxy_http_version 1.1;
        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_redirect off;
    }
    location /service/api-docs/ {
        add_header Cache-Control "public, max-age=900";
        proxy_pass http://exchanger-docs:8080/;
        proxy_http_version 1.1;
        proxy_set_header Host $http_host;
        proxy_redirect off;
    }
    location /service/fs {
        add_header Cache-Control "public, max-age=900";
        alias /public;
    }
    location /ws/ {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://exchanger-api-websocket: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;
    }

    access_log /dev/stdout cf_custom;
    error_log /dev/stderr error;
    sendfile off;
    client_max_body_size 100m;
}

10. Create your docker-compose.yml

nano /home/runner/api_server/docker-compose.yml
x-logging:
  &default-logging
  driver: "json-file"
  options:
    max-file: "1"
    max-size: "500m"

services:

  exchanger-api-http:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-api:${API_BRANCH:-master}
    container_name: exchanger-api-http
    entrypoint: bash ./entry.sh API
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-uploader-service
      - exchanger-api-mongodb
      - redis
    env_file:
      - .env.mongo.user
      - .env.lm
      - .env
    volumes:
      - ./config:/app/config
      - ./public:/app/public
      - ./pluginsExternal:/app/pluginsExternal
      - type: tmpfs
        target: /home/node/.pm2/
        tmpfs:
          size: "10000000"
          mode: 0777
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.101
      control-net:
        ipv4_address: 10.255.255.25
  exchanger-lifecycle-manager:
    image: rg.boxexchanger.net/boxexchanger-utils/exchanger-lifecycle-manager:main@sha256:5315489b02d27f319467f3161b64f69d76f4ba8aaf951dd921e92b2613671502
    container_name: exchanger-lifecycle-manager
    restart: unless-stopped
    read_only: true
    env_file:
      - .env.lm
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      control-net:
        ipv4_address: 10.255.255.24

  exchanger-api-websocket:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-api:${API_BRANCH:-master}
    container_name: exchanger-api-websocket
    entrypoint: bash ./entry.sh WEBSOCKET
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-api-http
    env_file:
      - .env.mongo.user
      - .env
    volumes:
      - ./config:/app/config:ro
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.107
  exchanger-api-parser-rate:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-api:${API_BRANCH:-master}
    container_name: exchanger-api-parser-rate
    entrypoint: bash ./entry.sh PARSER_RATE
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-api-http
    env_file:
      - .env.mongo.user
      - .env
    volumes:
      - ./config:/app/config:ro
      - ./public:/app/public
      - ./pluginsExternal:/app/pluginsExternal:ro
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.108
  exchanger-api-cron:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-api:${API_BRANCH:-master}
    container_name: exchanger-api-cron
    entrypoint: bash ./entry.sh CRON
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-api-http
    env_file:
      - .env.mongo.user
      - .env
    volumes:
      - ./config:/app/config
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.109
  exchanger-api-payout:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-api:${API_BRANCH:-master}
    container_name: exchanger-api-payout
    entrypoint: bash ./entry.sh PAYOUT
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-api-http
    env_file:
      - .env.mongo.user
      - .env
    volumes:
      - ./config:/app/config:ro
      - ./public:/app/public
      - ./pluginsExternal:/app/pluginsExternal:ro
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.110
  exchanger-api-aml:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-api:${API_BRANCH:-master}
    container_name: exchanger-api-aml
    entrypoint: bash ./entry.sh AML
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-api-http
    env_file:
      - .env.mongo.user
      - .env
    volumes:
      - ./config:/app/config:ro
      - ./public:/app/public
      - ./pluginsExternal:/app/pluginsExternal:ro
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.111
  exchanger-api-module:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-api:${API_BRANCH:-master}
    container_name: exchanger-api-module
    entrypoint: bash ./entry.sh MODULE
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-api-http
    env_file:
      - .env.mongo.user
      - .env
    volumes:
      - ./config:/app/config:ro
      - ./public:/app/public
      - ./pluginsExternal:/app/pluginsExternal:ro
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.112
  exchanger-api-notification:
    image: rg.boxexchanger.net/${VCS_NAMESPACE}/exchanger-api:${API_BRANCH:-master}
    container_name: exchanger-api-notification
    entrypoint: bash ./entry.sh NOTIFICATION
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-api-http
    env_file:
      - .env.mongo.user
      - .env
    volumes:
      - ./config:/app/config:ro
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.113

  exchanger-uploader-service:
    image: rg.boxexchanger.net/boxexchanger-utils/exchanger-uploader-service:master
    container_name: exchanger-uploader-service
    restart: unless-stopped
    read_only: true
    volumes:
      - ./public:/public
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.104
  exchanger-email-service:
    image: rg.boxexchanger.net/boxexchanger-utils/exchanger-email-service:master
    container_name: exchanger-email-service
    restart: unless-stopped
    read_only: true
    volumes:
      - ./config:/app/config:ro
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.106

  exchanger-docs:
      image: rg.boxexchanger.net/boxexchanger-utils/restapi-docs-ui:master
      container_name: exchanger-docs
      restart: unless-stopped
      read_only: true
      volumes:
        - ./.env.docs.config.js:/usr/share/nginx/html/dist/_nuxt/_CONFIG.js:ro
        - type: tmpfs
          target: /tmp/
          tmpfs:
            size: "1000000"
      logging: *default-logging
      networks:
        exchanger-net:
          ipv4_address: 10.1.0.105
  exchanger-api-mongodb:
    image: mongo:6
    container_name: exchanger-api-mongodb
    restart: unless-stopped
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.102
    volumes:
      - mongo_db:/data/db
      - /backups:/backups
      - ./init_db.js:/docker-entrypoint-initdb.d/init.js
    logging: *default-logging
    ports:
      - 127.0.0.1:27017:27017
    env_file:
      - .env.mongo.root

  redis:
    image: redis:7
    container_name: exchanger-api-redis
    restart: unless-stopped
    read_only: true
    volumes:
      - redis_data:/data
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.103

  nginx-api:
    image: nginxinc/nginx-unprivileged:1.27-alpine
    container_name: nginx-api
    restart: unless-stopped
    read_only: true
    depends_on:
      - exchanger-api-http
    volumes:
      - ./nginx/:/etc/nginx/conf.d:ro
      - ./public:/public:ro
      - type: tmpfs
        target: /docker-entrypoint.d/
        tmpfs:
          size: "100000"
      - type: tmpfs
        target: /tmp/
        tmpfs:
          size: "10000000"
    ports:
      - "3000:3000"
    logging: *default-logging
    networks:
      exchanger-net:
        ipv4_address: 10.1.0.100
volumes:
  mongo_db:
  redis_data:

networks:
  exchanger-net:
    external: true
  control-net:
    external: true

11. Execute credential mongo generation script

cd /home/runner/api_server
wget "https://git.boxexchanger.net/-/snippets/2/raw/main/init_db.js"
wget "https://git.boxexchanger.net/-/snippets/2/raw/main/generate_credentials.sh"
chmod +x generate_credentials.sh
./generate_credentials.sh

12. Initialize MongoDB

docker compose up -d exchanger-api-mongodb

13. Start API server

docker compose up -d

14. Get and remove initial admin credentials:

docker exec exchanger-api cat access.txt
  • remove access.txt

    docker exec exchanger-api rm access.txt

Last updated

Was this helpful?