diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0e851a7 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +.env +node_modules/ +.DS_Store \ No newline at end of file diff --git a/.github/workflows/fly-deploy.yml b/.github/workflows/fly-deploy.yml new file mode 100644 index 0000000..b0c246e --- /dev/null +++ b/.github/workflows/fly-deploy.yml @@ -0,0 +1,18 @@ +# See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/ + +name: Fly Deploy +on: + push: + branches: + - main +jobs: + deploy: + name: Deploy app + runs-on: ubuntu-latest + concurrency: deploy-group # optional: ensure only one action runs at a time + steps: + - uses: actions/checkout@v4 + - uses: superfly/flyctl-actions/setup-flyctl@master + - run: flyctl deploy --remote-only + env: + FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }} diff --git a/.prettierignore b/.prettierignore index 55b5f83..46ccef8 100644 --- a/.prettierignore +++ b/.prettierignore @@ -10,5 +10,5 @@ Thumbs.db # Docs files *_spec3.json - +.github README.md \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8da4aed --- /dev/null +++ b/Dockerfile @@ -0,0 +1,45 @@ +# syntax = docker/dockerfile:1 + +# Adjust NODE_VERSION as desired +ARG NODE_VERSION=21.6.1 +FROM node:${NODE_VERSION}-slim as base + +LABEL fly_launch_runtime="Node.js" + +# Node.js app lives here +WORKDIR /app + +# Set production environment +ENV NODE_ENV="production" + + +# Throw-away build stage to reduce size of final image +FROM base as build + +# Install packages needed to build node modules +RUN apt-get update -qq && \ + apt-get install --no-install-recommends -y build-essential node-gyp pkg-config python-is-python3 + +# Install node modules +COPY --link package-lock.json package.json ./ +RUN npm ci --include=dev + +# Copy application code +COPY --link . . + +# Build application +RUN npm run build + +# Remove development dependencies +RUN npm prune --omit=dev + + +# Final stage for app image +FROM base + +# Copy built application +COPY --from=build /app /app + +# Start the server by default, this can be overwritten at runtime +EXPOSE 3000 +CMD [ "npm", "run", "start" ] diff --git a/README.md b/README.md index 67e271a..41304fa 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,16 @@ Discord Bot for Turizak projects -All you need: +All you need to know: ``` -npm run build && npm run start -``` \ No newline at end of file +npm install && npm run build + +npm run start +``` + +Deployed on Fly.io + +``` +fly deploy +``` diff --git a/fly.toml b/fly.toml new file mode 100644 index 0000000..a9612c7 --- /dev/null +++ b/fly.toml @@ -0,0 +1,22 @@ +# fly.toml app configuration file generated for turizak-bot on 2024-08-23T20:03:47-04:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = 'turizak-bot' +primary_region = 'ord' + +[build] + +[http_service] + internal_port = 3000 + force_https = true + auto_stop_machines = false + auto_start_machines = false + min_machines_running = 0 + processes = ['app'] + +[[vm]] + memory = '1gb' + cpu_kind = 'shared' + cpus = 1 diff --git a/package-lock.json b/package-lock.json index f91afc9..0289192 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ }, "devDependencies": { "@eslint/js": "^9.9.1", + "@flydotio/dockerfile": "^0.5.8", "eslint": "^9.9.1", "globals": "^15.9.0", "husky": "^8.0.0" @@ -263,6 +264,37 @@ "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@flydotio/dockerfile": { + "version": "0.5.8", + "resolved": "https://npm.oplogic.com/@flydotio/dockerfile/-/dockerfile-0.5.8.tgz", + "integrity": "sha512-119l9s4xUEATRWTQPddE0f+jZjVBhpnJiGA/aHzDiOUet2L7SD3G5jbSGvOXJm1Ks3kGmxUcPdt3BpLQRef+ow==", + "dev": true, + "dependencies": { + "chalk": "^5.3.0", + "diff": "^5.1.0", + "ejs": "^3.1.9", + "shell-quote": "^1.8.1", + "yargs": "^17.7.2" + }, + "bin": { + "dockerfile": "index.js" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@flydotio/dockerfile/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://npm.oplogic.com/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://npm.oplogic.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -497,6 +529,20 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://npm.oplogic.com/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/color": { "version": "3.2.1", "resolved": "https://npm.oplogic.com/color/-/color-3.2.1.tgz", @@ -605,6 +651,15 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://npm.oplogic.com/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/discord-api-types": { "version": "0.37.83", "resolved": "https://npm.oplogic.com/discord-api-types/-/discord-api-types-0.37.83.tgz", @@ -646,11 +701,41 @@ "url": "https://dotenvx.com" } }, + "node_modules/ejs": { + "version": "3.1.10", + "resolved": "https://npm.oplogic.com/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://npm.oplogic.com/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/enabled": { "version": "2.0.0", "resolved": "https://npm.oplogic.com/enabled/-/enabled-2.0.0.tgz", "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==" }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://npm.oplogic.com/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://npm.oplogic.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -874,6 +959,36 @@ "node": ">=16.0.0" } }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://npm.oplogic.com/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://npm.oplogic.com/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://npm.oplogic.com/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://npm.oplogic.com/find-up/-/find-up-5.0.0.tgz", @@ -925,6 +1040,15 @@ "node": ">=12.20.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://npm.oplogic.com/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://npm.oplogic.com/glob-parent/-/glob-parent-6.0.2.tgz", @@ -1026,6 +1150,15 @@ "node": ">=0.10.0" } }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://npm.oplogic.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://npm.oplogic.com/is-glob/-/is-glob-4.0.3.tgz", @@ -1064,6 +1197,24 @@ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, + "node_modules/jake": { + "version": "10.9.2", + "resolved": "https://npm.oplogic.com/jake/-/jake-10.9.2.tgz", + "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.4", + "minimatch": "^3.1.2" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://npm.oplogic.com/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1381,6 +1532,15 @@ "node": ">= 6" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://npm.oplogic.com/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://npm.oplogic.com/resolve-from/-/resolve-from-4.0.0.tgz", @@ -1471,6 +1631,15 @@ "node": ">=8" } }, + "node_modules/shell-quote": { + "version": "1.8.1", + "resolved": "https://npm.oplogic.com/shell-quote/-/shell-quote-1.8.1.tgz", + "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/simple-swizzle": { "version": "0.2.2", "resolved": "https://npm.oplogic.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz", @@ -1495,6 +1664,20 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://npm.oplogic.com/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://npm.oplogic.com/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1665,6 +1848,23 @@ "node": ">=0.10.0" } }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://npm.oplogic.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/ws": { "version": "8.18.0", "resolved": "https://npm.oplogic.com/ws/-/ws-8.18.0.tgz", @@ -1685,6 +1885,42 @@ } } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://npm.oplogic.com/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://npm.oplogic.com/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://npm.oplogic.com/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://npm.oplogic.com/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index 1f6c59c..bc3a463 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ }, "devDependencies": { "@eslint/js": "^9.9.1", + "@flydotio/dockerfile": "^0.5.8", "eslint": "^9.9.1", "globals": "^15.9.0", "husky": "^8.0.0"