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