## 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 ```