포아봇 구축
포아봇을 구축하기 위한 과정입니다.
서버 생성페이지로 이동
Section titled “서버 생성페이지로 이동”
- “Products” 를 클릭합니다
- “Compute” 를 클릭합니다
- “Deploy” 를 클릭합니다
- “Deploy New Server” 를 클릭합니다

- “Shared CPU” 를 선택합니다
- “Asia” 를 선택합니다
- “Seoul” 혹은 “Osaka” 를 선택합니다
- “Cloud Compute” 를 선택합니다
- “vc2-1c-1gb” 를 선택합니다
- “Automatic Backups” 를 “disabled” 합니다
- “$5” 인지 확인합니다
- “Configure Software” 를 선택합니다
운영체제 선택
Section titled “운영체제 선택”
- “Ubuntu 24.04 LTS” 를 선택합니다
추가 설정 및 구축
Section titled “추가 설정 및 구축”
-
“Public IPv4” 를 선택합니다
-
“Cloud-Init User-data” 를 선택합니다
-
”User Data” 에 아래 포아봇 설치 스크립트를 붙여 넣습니다
포아봇 설치 스크립트 #cloud-configapt:preserve_sources_list: trueconf: |Dpkg::Options {"--force-confdef";"--force-confold";}APT::Get::Assume-Yes "true";APT::Get::force-yes "true";Debian::Frontend "noninteractive";package_update: truepackage_upgrade: truelocale: ko_KR.UTF-8timezone: Asia/Seoulpackages:- net-tools- unzip- chrony- ca-certificates- curl- podman- cockpit- cockpit-podman- gettext- libpam-google-authenticatorwrite_files:- path: /root/poabot.envcontent: |# RequiredPASSWORD=""DISCORD_WEBHOOK_URL=""# OptionalUPBIT_KEY=""UPBIT_SECRET=""BITHUMB_KEY=""BITHUMB_SECRET=""BINANCE_KEY=""BINANCE_SECRET=""BYBIT_KEY=""BYBIT_SECRET=""OKX_KEY=""OKX_SECRET=""OKX_PASSPHRASE=""BITGET_KEY=""BITGET_SECRET=""BITGET_PASSPHRASE=""KIS1_KEY=""KIS1_SECRET=""KIS1_ACCOUNT_NUMBER=""KIS1_ACCOUNT_CODE=""KIS2_KEY=""KIS2_SECRET=""KIS2_ACCOUNT_NUMBER=""KIS2_ACCOUNT_CODE=""KIS3_KEY=""KIS3_SECRET=""KIS3_ACCOUNT_NUMBER=""KIS3_ACCOUNT_CODE=""KIS4_KEY=""KIS4_SECRET=""KIS4_ACCOUNT_NUMBER=""KIS4_ACCOUNT_CODE=""WHITELIST=[""]TIMEZONE="Asia/Seoul"- path: /etc/systemd/system/pm2-root.servicecontent: |[Unit]Description=PM2 process managerDocumentation=https://pm2.keymetrics.io/After=network.target[Service]Type=forkingUser=rootLimitNOFILE=infinityLimitNPROC=infinityLimitCORE=infinityEnvironment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/binEnvironment=PM2_HOME=/root/.pm2PIDFile=/root/.pm2/pm2.pidRestart=on-failureExecStart=/usr/bin/pm2 resurrectExecReload=/usr/bin/pm2 reload allExecStop=/usr/bin/pm2 kill[Install]WantedBy=multi-user.target- path: /etc/chrony/chrony.confcontent: |confdir /etc/chrony/conf.dserver time.bora.net iburstserver time.kornet.net iburstserver kr.pool.ntp.org iburstserver 0.asia.pool.ntp.org iburstserver 1.asia.pool.ntp.org iburstserver 2.asia.pool.ntp.org iburstserver 3.asia.pool.ntp.org iburstpool ntp.ubuntu.com iburst maxsources 4pool 0.ubuntu.pool.ntp.org iburst maxsources 1pool 1.ubuntu.pool.ntp.org iburst maxsources 1pool 2.ubuntu.pool.ntp.org iburst maxsources 2sourcedir /run/chrony-dhcpsourcedir /etc/chrony/sources.dkeyfile /etc/chrony/chrony.keysdriftfile /var/lib/chrony/chrony.driftntsdumpdir /var/lib/chronymaxupdateskew 100.0leapsectz right/UTCmakestep 1.0 3rtcsynclogdir /var/log/chrony- path: /etc/containers/registries.confcontent: |unqualified-search-registries = ["docker.io"]- path: /usr/local/bin/setup-google-authpermissions: "0755"content: |#!/bin/bashif [ ! -f $HOME/.google_authenticator ]; thengoogle-authenticator -t -d -f -r 3 -R 30 -w 3echo "Two-factor authentication is now set up."echo "Setup is complete. Scan the above QR code with the Google Authenticator app."echo "Also, please keep the recovery code in a safe place."if [[ $EUID -ne 0 ]]; thenecho "Error: This script must be run with root privileges. (e.g. sudo $0)"exit 1fiPAM_FILE="/etc/pam.d/cockpit"AUTH_LINE_APPEND="auth required pam_google_authenticator.so nullok"AUTH_LINE_CREATE="auth required pam_google_authenticator.so"CHECK_PATTERN="^[[:space:]]*auth.*pam_google_authenticator.so"echo "Check $PAM_FILE file..."if [ -f "$PAM_FILE" ]; thenecho "$PAM_FILE file exists."if grep -qE "$CHECK_PATTERN" "$PAM_FILE"; thenecho "Google Authenticator is already set up in '$PAM_FILE' file. No changes will be made."elseecho "Google Authenticator is not set up in '$PAM_FILE' file. Append '$AUTH_LINE_APPEND' to the end of the file."if [ -n "$(tail -c1 "$PAM_FILE")" ]; thenecho "" >> "$PAM_FILE"fiecho "$AUTH_LINE_APPEND" >> "$PAM_FILE"echo "'$AUTH_LINE_APPEND' is added."fielseecho "$PAM_FILE file does not exist. Create a new file."echo "$AUTH_LINE_CREATE" > "$PAM_FILE"echo "'$AUTH_LINE_CREATE' is added to $PAM_FILE file."fisystemctl restart cockpit.socketelseecho "Google Authenticator is already set up."echo "If you want to reconfigure, remove $HOME/.google_authenticator file first."fi- path: /usr/local/bin/start-poabotpermissions: "0755"content: |#!/bin/bashfunction show_status() {echo "$1"}show_status "poabot ready"podman stop -i poabot 2>/dev/nullshow_status "poabot stopped"COMMAND="mkdir -p $HOME/logs && chmod -R 777 $HOME/logs && podman run --replace -d -p 8000:8000 -v $HOME/logs:/app/logs --env-file $HOME/poabot.env --restart unless-stopped --name poabot poabot"if eval $COMMAND; thenshow_status "poabot started"elseshow_status "poabot start failed"exit 1fi- path: /usr/local/bin/stop-poabotpermissions: "0755"content: |#!/bin/bashpodman stop -i poabot 2>/dev/nullshow_status "poabot stopped"- path: /etc/systemd/system/caddy.servicecontent: |[Unit]Description=CaddyDocumentation=https://caddyserver.com/docs/After=network.target network-online.targetRequires=network-online.target[Service]Type=notifyUser=caddyGroup=caddyExecStart=/usr/bin/caddy run --environ --config /etc/caddy/CaddyfileExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --forceTimeoutStopSec=5sLimitNOFILE=1048576PrivateTmp=trueProtectSystem=fullAmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE[Install]WantedBy=multi-user.target- path: /etc/caddy/Caddyfilecontent: |:80 {@manager {path /managerpath /manager/*}@poa_whitelist {remote_ip 52.89.214.238 34.212.75.30 54.218.53.128 52.32.178.7 127.0.0.1}redir /manager /manager/route {handle @manager {reverse_proxy localhost:9090}handle @poa_whitelist {reverse_proxy 127.0.0.1:8000}handle {respond 403}}}runcmd:- export DEBIAN_FRONTEND=noninteractive- |if command -v ufw > /dev/null; thenif [ "false" = "true" ]; thenufw allow sshelseufw delete allow 22/tcpufw delete allow sshfiufw allow 123/udpufw allow httpsufw allow httpufw allow 9090/tcpufw --force enableufw reloadelif command -v firewall-cmd > /dev/null; thenif [ "false" = "true" ]; thenfirewall-cmd --permanent --add-service=sshelsefirewall-cmd --permanent --remove-service=sshfifirewall-cmd --permanent --add-port=123/udpfirewall-cmd --permanent --add-service=httpsfirewall-cmd --permanent --add-service=httpfirewall-cmd --permanent --add-port=9090/tcpfirewall-cmd --reloadfi# caddy- n=0; while [ $n -lt 5 ] && ! wget "https://github.com/caddyserver/caddy/releases/download/v2.8.4/caddy_2.8.4_linux_amd64.tar.gz"; do echo "Command failed. Retrying in 5 seconds..."; sleep 5; n=$((n+1)); done- tar -xf caddy_*_linux_amd64.tar.gz- mv caddy /usr/bin/- groupadd --system caddy- useradd --system --gid caddy --create-home --home-dir /var/lib/caddy --shell /usr/sbin/nologin --comment "Caddy web server" caddy- chmod +x /usr/bin/caddy- rm -rf caddy_*_linux_amd64.tar.gz# NODEJS- echo "==removing existing nodejs=="- sudo apt-get remove nodejs nodejs-doc libnode* npm -y || echo "Node.js not found, continuing..."- sudo apt-get autoremove -y- echo "==installing node 20=="- curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -- sudo apt-get update -y --allow-insecure-repositories- sudo apt-get install nodejs -y --allow-unauthenticated- sudo apt-get install npm -y --allow-unauthenticated- node -v- npm -v# cockpit- echo "==cockpit-navigator=="- |if command -v apt > /dev/null; thenwget https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.10/cockpit-navigator_0.5.10-1focal_all.debapt install -y ./cockpit-navigator_0.5.10-1focal_all.debelif command -v yum > /dev/null; thenyum install -y https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.10/cockpit-navigator-0.5.10-1.el7.noarch.rpmelif command -v dnf > /dev/null; thendnf install -y https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.10/cockpit-navigator-0.5.10-1.el8.noarch.rpmfi- |if [ -f /etc/cockpit/disallowed-users ] && grep -qxF 'root' /etc/cockpit/disallowed-users; thensed -i '/^root$/d' /etc/cockpit/disallowed-usersfi- IP=$(hostname -I | awk '{print $1}')- mkdir -p /etc/cockpit- |cat > /etc/cockpit/cockpit.conf <<EOF[WebService]Origins = http://$IP wss://$IPProtocolHeader = X-Forwarded-ProtoUrlRoot = /managerEOF# poabot-manager- echo "==poabot-manager=="- cd /root- |LATEST_TAG=$(curl -s "https://api.github.com/repos/jangdokang/poabot-manager/releases/latest" | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)echo "Latest poabot-manager version: $LATEST_TAG"curl -sSL "https://github.com/jangdokang/poabot-manager/releases/download/$LATEST_TAG/poabot-manager-${LATEST_TAG#v}.tar.xz" -o "poabot-manager-${LATEST_TAG#v}.tar.xz"tar -xf "poabot-manager-${LATEST_TAG#v}.tar.xz"ls -laif [ -d cockpit-poabot ]; then cd cockpit-poabot; elif [ -d poabot-manager ]; then cd poabot-manager; else echo "Directory not found"; exit 1; fiif [ -f Makefile ]; then make && make install; else echo "Makefile not found - skipping make install"; fi# poabot- |POABOT_LATEST_TAG=$(curl -s "https://hub.docker.com/v2/repositories/jangdokang/poabot/tags" | grep -o '"name":"[^"]*' | grep -v latest | head -1 | cut -d'"' -f4)echo "poabot - $POABOT_LATEST_TAG"podman pull jangdokang/poabot:$POABOT_LATEST_TAGpodman tag jangdokang/poabot:$POABOT_LATEST_TAG jangdokang/poabot:latest# systemctl- echo "==systemctl=="- systemctl daemon-reload- systemctl enable cockpit.socket- systemctl restart cockpit.socket- systemctl enable chrony- systemctl restart chrony- systemctl enable caddy- systemctl restart caddy -
“Deploy” 를 클릭합니다