---
# System prepended metadata

title: Untitled

---

## telegram bot backend + web form subsidium deployment


_NOTE: i was short on time, a lot of things can be improved greately, including not very flexible deployment, so there are some prerequisites/requirements that i descibe below._

## contents

  * [description](#description)
  * [prerequisites](#prerequisites)
  * [deployment](#deployment)
  * [administration](#administration)

----

### description

the deployment procedure is for linux-based machines, CentOS 7 in this example.
in short, i use docker swarm single-node cluster to deploy 3 dockerzied services - frontend(react), backend(java), db(postgres), using file that describes the deployment (docker-compose.depl.yml below).
it is assumed to be deployed to the same machine/instance that is behind https://subsidium.digital.
current deployed telegram bot handle is @subsidium_airdrop_bot.


### UPDATE - PROXY METHOD
----
* install httpd
  ```bash
  sudo yum install httpd
  ```
* add the following lines to /etc/httpd/conf/httpd.conf
  ```bash
  SSLProxyEngine on

  ProxyPass /airdrop-form https://nftbubbles.art/airdrop-form
  ProxyPassReverse /airdrop-form https://nftbubbles.art/airdrop-form
  ```
* install mod ssl
  ```bash
  sudo yum install -y mod_ssl
  ```
* create dummy certificate
  ```bash
  cd /etc/pki/tls/certs
  sudo ./make-dummy-cert localhost.crt
  ```
* comment out the following line in /etc/httpd/conf.d/ssl.conf 
  ```bash
  # SSLCertificateKeyFile in /etc/pki/tls/private/localhost.key
  ```
* restart httpd
  ```bash
  sudo systemctl restart httpd
  ```

* visit <public-ip>/airdrop-form
  * for instance http://188.166.84.136/airdrop-form  
    
----

### WITH PROXY METHOD, STEPS BELOW ARE NOT NEEDED

### prerequisites
* following installed:
  * docker [aws reference](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/docker-basics.html)
    * installation
      ```bash
      sudo yum update -y
      sudo yum install docker
      sudo service docker start
      sudo usermod -a -G docker ec2-user    
      ```
    * post-installation
      * after installation log out and log back in to be able to use docker commands without sudo 
  * httpd [aws reference](https://docs.aws.amazon.com/efs/latest/ug/wt2-apache-web-server.html)
    * installation 
      ```bash
      sudo yum -y install httpd
      sudo service httpd start  
      ```
  * following ports available:
    * 8116
    * 8117
    * 8118

### deployment 
* configure httpd    
  * create file /etc/httpd/conf.d/httd-config.conf
    ```bash
    # /etc/httpd/conf.d/httd-config.conf
    Header set Access-Control-Allow-Origin "*"

    ProxyPass /airdrop-bot-backend http://localhost:8116
    ProxyPassReverse /airdrop-bot-backend http://localhost:8116

    ProxyPass /airdrop-form http://localhost:8118
    ProxyPassReverse /airdrop-form http://localhost:8118
    ```
  * reload httpd for the config to take effect
    ```bash
     sudo service httpd reload
    ```
  * explanation  
    * /airdrop-form is the path where form can be found, it has to be this value, as this is where frontend will pull assets from (final url would be something like that - https://subsidium.digital/airdrop-form)
    * /airdrop-bot-backend is the backend url (https://subsidium.digital/airdrop-bot-backend)
* create the following file describing the deployment 
  ```bash
  sudo vi ~/docker-compose.depl.yml
  ```
  ```yaml
  version: '3.2'
  services:
    frontend:
      image: alagiz/airdrop-bot-frontend:latest
      environment:
        - NODE_ENV=development
        - BACKEND_URL=https://subsidium.digital/airdrop-bot-backend
      deploy:
        resources:
          limits:
            cpus: '0.5'
            memory: 150M
          reservations:
            cpus: '0.1'
            memory: 10M
      ports:
        - 8118:80
    backend:
      image: alagiz/airdrop-bot-backend:latest
      environment:
        - TELEGRAM_BOT_TOKEN=2041362367:AAFFVNVdR-zYPrMKR5CjA1Xj5H3RAmLEOeI
        - SECRET_AUTHORIZATION=3zghrusjdhr450g2nhkf0jkrjgenty6f5rpwz
        - POSTGRES_URL=db:5432
        - POSTGRES_DB_NAME=postgres
        - POSTGRES_USER_NAME=postgres
        - FRONTEND_URL=https://subsidium.digital/airdrop-form
      command: ["java", "-jar", "/usr/app/app.jar"]
      deploy:
        resources:
          limits:
            cpus: '0.5'
            memory: 400M
          reservations:
            cpus: '0.1'
            memory: 10M
      ports:
        - 8116:8080
    db:
      image: postgres:13.1-alpine
      environment:
        - POSTGRES_HOST_AUTH_METHOD=trust
      volumes:
        - /var/opt/airdrop-bot/postgres-data:/var/lib/postgresql/data
      deploy:
        resources:
          limits:
            cpus: '0.5'
            memory: 150M
          reservations:
            cpus: '0.1'
            memory: 10M
      ports:
        - 8117:5432
  ```
* create folder at path /var/opt/airdrop-bot/postgres-data
  ```bash
  sudo mkdir -p /var/opt/airdrop-bot/postgres-data
  ```
  * that is where postgres will persist the data
* create docker swarm cluster
  * get private ip address of the machine
    ```bash
    ip addr
    # example output 172.31.42.214
    ```
  * init swarm cluster using the ip
    ```
    docker swarm init --advertise-addr 172.31.42.214
    ```
  * deploy the services to the cluster
    ```bash
    docker stack deploy -c ~/docker-compose.depl.yml airdropStack
    ```
  * verify that services are running 
    ```bash
    # example of successful deployment
    ID             NAME                       IMAGE                                NODE                                          DESIRED STATE   CURRENT STATE            ERROR  
    sn7xsfc2e3ne   airdropStackk_backend.1    alagiz/airdrop-bot-backend:latest    ip-172-31-42-214.us-east-2.compute.internal   Running         Running 19 minutes ago          

    7dibj189jadk   airdropStackk_db.1         postgres:13.1-alpine                 ip-172-31-42-214.us-east-2.compute.internal   Running         Running 19 minutes ago          

    ofsf1fapv29c   airdropStackk_frontend.1   alagiz/airdrop-bot-frontend:latest   ip-172-31-42-214.us-east-2.compute.internal   Running         Running 19 minutes ago          
    ```
  * if needed get logs from a particular service with
    ```bash
    docker service logs <service-id>
    # for instance docker service logs sn7xsfc2e3ne
    ```
  * verify that deployment is succesfull by using the bot and accessing https://subsidium.digital/airdrop-form
  * in case there is a need to delete the deployment, run
    ```bash
    docker stack rm airdropStack
    ```

### administration 
  * i pre-whitelisted a bunch of users in the code (according to users. xslx that i sent you in telegram group chat), but you are able to whitelist or delist users using REST API. i can also close those endpoints, if it is not needed.
    * whitelisting users (from outside of host machine)
      * call backend endpoint protected by an authorization code that allows to whitelist or delist users. i recommend using Insomnia for that.
        * SECRET_AUTHORIZATION in ~/docker-compose.depl.yml is the authorization code
        * telegram user id can be found in users.xslx
        * to whitelist user with id 1193573635 send the following GET request
          * https://subsidium.digital/airdrop-bot-backend/whitelist-by-telegram-id?userTelegramId=1193573635
          * add header Authorization and use SECRET_AUTHORIZATION as the value of it (3zghrusjdhr450g2nhkf0jkrjgenty6f5rpwz currently)
    * delisting users
      * in a similar way there is an endpoint to blacklist a user - GET request:
          * https://subsidium.digital/airdrop-bot-backend/delist-by-telegram-id?userTelegramId=1193573635
          * add header Authorization and use SECRET_AUTHORIZATION as the value of it (3zghrusjdhr450g2nhkf0jkrjgenty6f5rpwz currently)
  * logging into the db container (on host machine) 
    * to get access to the data the following steps can be taken
      * get postgres container id
        ```bash
        docker ps
        ```
        ```bash
        # output
        CONTAINER ID   IMAGE                                COMMAND                  CREATED          STATUS          PORTS      NAMES
        a91ba505e757   postgres:13.1-alpine                 "docker-entrypoint.s…"   44 minutes ago   Up 44 minutes   5432/tcp   airdropStackk_db.1.7dibj189jadknkuhvsl7l5j8o
        ```
      * use this id to log into the container
        ```bash
        docker exec -it a91ba505e757 bash
        ```
      * provide credentials to psql
        ```bash
        psql postgres postgres
        ```
      * verify that tables were created
        ```sql
        \dt
        ```
        ```bash
        # output
                          List of relations
         Schema |           Name           | Type  |  Owner   
        --------+--------------------------+-------+----------
         public | application_user         | table | postgres
         public | whitelisted_telegram_ids | table | postgres
        (2 rows)
        ```
      * query the desired information
        ```sql
        select * from whitelisted_telegram_ids;
        ```
        ```bash
        # output
                          id                  | telegram_id |
        --------------------------------------+-------------+
         af09d593-1598-4e90-ab3b-65dcd7d22d3c |  1673574671 | 
         ba62520b-cb69-431f-8d83-c2f6903eb21a |   413184612 | 
         5042494a-df58-4427-a44c-1c6e1b76e1a5 |  1682937821 | 
         3e72ef63-329b-40c2-9c76-e5901d3c5efc |  1193573635 | 
        ```
        ```sql
        select telegram_id,wallet_address from application_user;
        ```
        ```bash
        # output
         telegram_id |                wallet_address                
        -------------+----------------------------------------------
           413184612 | 
          1682937821 | terra1rrhrg4j0me0g8e24sk29rn6r24ga9q99gjsazl
          1193573635 | BZSbXyrwxgfhZKiiGY3FVeWyCbATCFhkpV2snwKbaDwo
          1673574671 | terra1666
        ```
      * to export a table into csv 
        * inside the container using psql cli tool run
          ```sql
          \COPY application_user TO 'application_user_db' CSV HEADER;
          ```
        * exit the psql cli and docker container and run docker cp command to copy the file from container to host (use postgres container id that can be fetched with "docker ps")
          ```bash
          # exit psql cli tool and the container by executing "exit" command twice
          ```
          ```bash
          # copy the file from container to host
          docker cp <container_id>:/<path_to_file_inside_container> <path_to_file_on_host>
          # for instance
          sudo docker cp a91ba505e757:/application_user_db application_user_db 
          ```
        * check the file  
          ```bash
          cat application_user_db
          ```
          ```bash
          id,chat_id,generated_code,is_code_used,is_terra_wallet,telegram_id,telegram_username,wallet_address
          1335bfc9-0b00-4301-a7a7-b44774f808d4,413184612,672473,f,f,413184612,,
          30c7bc65-84ff-46e9-9a64-e25a0b5070a9,1682937821,109364,t,t,1682937821,,terra1rrhrg4j0me0g8e24sk29rn6r24ga9q99gjsazl
          dbb29358-8090-4fa2-9172-cc59c19196b5,1193573635,537609,t,f,1193573635,,BZSbXyrwxgfhZKiiGY3FVeWyCbATCFhkpV2snwKbaDwo
          ae9d8774-48a7-4da5-96b3-03cbe3a0f710,1673574671,844410,t,t,1673574671,,terra1666
          ```
