diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..a9745259 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +README.md +.* +*.log +*.jpg +deploy +config +node_modules +sec +log + +!config/default.json +!deploy/entrypoint.sh \ No newline at end of file diff --git a/.github/actions/deploy/action.yml b/.github/actions/deploy/action.yml new file mode 100644 index 00000000..24c3d457 --- /dev/null +++ b/.github/actions/deploy/action.yml @@ -0,0 +1,45 @@ +name: Deploy containers via docker-compose +inputs: + ssh_user: + description: deploy target user + required: true + ssh_identity: + description: string for known_hosts file + required: true + ssh_key: + description: string for id_ed25519 file + required: true + ssh_host: + description: deploy target host + required: true + ssh_port: + description: deploy target port + required: true + +runs: + using: composite + steps: + - + name: Put server's SSH key + uses: ./.github/actions/ssh-keys + with: + action: put + identity: ${{ inputs.ssh_identity }} + key: ${{ inputs.ssh_key }} + - + name: Deploy + shell: bash + run: | + ssh -T ${{ inputs.ssh_user }}@${{ inputs.ssh_host }} -p ${{ inputs.ssh_port }} ' + docker run --rm \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v /home/ansible/.docker/config.json:/config.json \ + containrrr/watchtower \ + --run-once \ + hackem-bot + ' + - + name: Destroy server's SSH key + uses: ./.github/actions/ssh-keys + with: + action: destroy diff --git a/.github/actions/ssh-keys/action.yml b/.github/actions/ssh-keys/action.yml new file mode 100644 index 00000000..e7c51de5 --- /dev/null +++ b/.github/actions/ssh-keys/action.yml @@ -0,0 +1,28 @@ +name: Manage SSH keys +inputs: + identity: + description: string for known_hosts file + required: false + key: + description: string for id_ed25519 file + required: false + action: + required: true + description: put or destroy + default: put +runs: + using: composite + steps: + - + if: ${{ inputs.action == 'put' }} + shell: bash + run: | + mkdir -v ~/.ssh + chmod -v 700 ~/.ssh + echo "${{ inputs.identity }}" > ~/.ssh/known_hosts + echo "${{ inputs.key }}" > ~/.ssh/id_ed25519 + chmod -v 600 ~/.ssh/* + - + if: ${{ inputs.action == 'destroy' }} + shell: bash + run: shred -v ~/.ssh/* diff --git a/.github/workflows/app-deployment.yml b/.github/workflows/app-deployment.yml new file mode 100644 index 00000000..27b56ea6 --- /dev/null +++ b/.github/workflows/app-deployment.yml @@ -0,0 +1,44 @@ +name: Bot Deployment + +on: + push: + branches: + - main + +jobs: + + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - + uses: actions/checkout@v3 + - + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - + id: metadata + uses: docker/metadata-action@v4 + with: + images: ghcr.io/${{ github.repository }} + - + uses: docker/build-push-action@v4 + with: + context: . + file: ./deploy/Containerfile + push: true + tags: ${{ steps.metadata.outputs.tags }} + labels: ${{ steps.metadata.outputs.labels }} + - + uses: ./.github/actions/deploy + with: + ssh_user: ci + ssh_identity: ${{ vars.deploy_target_identity }} + ssh_host: ${{ secrets.deploy_target_host }} + ssh_port: ${{ secrets.deploy_target_port }} + ssh_key: ${{ secrets.deploy_target_key }} diff --git a/config/default.json b/config/default.json index e930a7ba..640e2f36 100644 --- a/config/default.json +++ b/config/default.json @@ -1,22 +1,22 @@ { "bot": { - "timezone" : "Asia/Yerevan", + "timezone": "Asia/Yerevan", "chats": { - "main" : -1001605898533, - "horny" : -1687064759, - "offtopic" : -1555805688, - "test" : -830038395, - "key" : "-1001807382938", - "status" : -830038395 + "main": -1001605898533, + "horny": -1687064759, + "offtopic": -1555805688, + "test": -830038395, + "key": -1001807382938, + "status": -830038395 }, - "timeouts":{ + "timeouts": { "in": 60000, "out": 300000 }, "autoWish": true, "logpath": "log.log" }, - "printers" : { + "printers": { "anette": { "apibase": "http://printer-anette.lan", "camport": 8080 @@ -26,7 +26,7 @@ "camport": 8080 } }, - "embassy-api":{ + "embassy-api": { "timeout": 15000, "port": 8001, "queryMonitorInterval": 60000, @@ -44,14 +44,18 @@ "doorcam": "http://hass.lan:8123/api/camera_proxy/camera.outdoor", "ttspath": "http://hass.lan:8123/api/services/tts/google_translate_say", "playpath": "http://hass.lan:8123/api/services/media_player/play_media", - "hostsToMonitor": ["192.168.1.2", "jigglypuff.lan", "minimi.lan"] + "hostsToMonitor": [ + "192.168.1.2", + "jigglypuff.lan", + "minimi.lan" + ] }, - "currency":{ + "currency": { "default": "AMD", "cryptoUpdateInterval": 50000, "fiatUpdateInterval": 3600000 }, - "api":{ - "port":3000 + "api": { + "port": 3000 } - } \ No newline at end of file +} \ No newline at end of file diff --git a/deploy/Containerfile b/deploy/Containerfile new file mode 100644 index 00000000..ff677f73 --- /dev/null +++ b/deploy/Containerfile @@ -0,0 +1,8 @@ +FROM docker.io/library/node:lts-alpine +WORKDIR /app +COPY . . +RUN mv ./deploy/entrypoint.sh / &&\ + chmod +x /entrypoint.sh &&\ + npm ci +ENTRYPOINT ["/entrypoint.sh"] +CMD ["npm", "run", "start"] diff --git a/deploy/entrypoint.sh b/deploy/entrypoint.sh new file mode 100644 index 00000000..c31f5bbc --- /dev/null +++ b/deploy/entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -xe +if [ ! -f "/app/data/db/data.db" ]; then + cp -v /app/data/sample.db /app/data/db/data.db +fi +if [ -f "/app/config/sec/production.json" ]; then + cp -v /app/config/sec/production.json /app/config/production.json +fi +exec "$@" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..192a1bbc --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +services: + bot: + image: 'ghcr.io/hackerembassy/hackerembassy-tg-bot:local' + build: + context: '.' + dockerfile: ./deploy/Containerfile + volumes: + - data:/app/data + environment: + - BOTDEBUG=true + - HACKERBOTTOKEN=$HACKERBOTTOKEN + - UNLOCKKEY=$UNLOCKKEY +volumes: + data: + name: "hackerembassy-bot-data"