From 28f498e881b40d6ccce03bcd13095f7daba51b37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magnus=20Str=C3=B8mseng?= Date: Wed, 28 Feb 2024 11:36:25 +0100 Subject: [PATCH] 95 autoredeploy on main change (#114) * feat(backend): :rocket: update deployment config for ntnu server * feat(backend): :rocket: try to setup pm2 with strapi * update docs * fix(backend): :construction: wip pm2 strapi setup * fix: :green_heart: fix strapi env variable * fix(frontend): :bug: fix env variable * run action in our development branch * test push * test again * build backend before frontend * update docs * feat: :sparkles: Docker compose with github runner * Update autoredeploy.yml * feat: :sparkles: Remove env file copy * feat: :sparkles: Autocreate env files in autorunner * feat: :sparkles: Change in dockerfile syntax * feat: :sparkles: dockerfile node 20 * Test change action runner * Add -d for detached mode in docker files * update deployment docs * update docs * runner test * prepare for main deploy --------- Co-authored-by: EliasKnudsen --- .github/workflows/autoredeploy.yml | 50 ++++++++------------- Dockerfile-backend | 9 ++++ Dockerfile-frontend | 8 ++++ backend/config/env/production/database.js | 27 ++++-------- backend/config/env/production/server.js | 14 +----- backend/config/plugins.js | 5 ++- backend/server.js | 2 + docker-compose.yml | 21 +++++++++ docs/deployment.md | 53 +++++++++++++++++++++++ frontend/.env.production | 4 +- 10 files changed, 127 insertions(+), 66 deletions(-) create mode 100644 Dockerfile-backend create mode 100644 Dockerfile-frontend create mode 100644 backend/server.js create mode 100644 docker-compose.yml create mode 100644 docs/deployment.md diff --git a/.github/workflows/autoredeploy.yml b/.github/workflows/autoredeploy.yml index f7e69ef..d338829 100644 --- a/.github/workflows/autoredeploy.yml +++ b/.github/workflows/autoredeploy.yml @@ -4,40 +4,28 @@ on: branches: ["main"] jobs: - frontend-build: + docker-build: strategy: matrix: node-version: [20.x] - defaults: - run: - working-directory: ./frontend runs-on: self-hosted steps: - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - - run: npm ci - - run: npm run build - - run: pm2 restart nextfrontend - - - backend-build: - strategy: - matrix: - node-version: [20.x] - defaults: - run: - working-directory: ./backend - runs-on: self-hosted - steps: - - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node-version }} - cache: "npm" - - run: npm ci - - run: npm run build - - run: pm2 restart strapibackend + - name: Create .env files + run: | + # Create .env with all variables except HOST_URL Backend + echo "HOST=${{ vars.HOST }}" >> .env + echo "PORT=${{ vars.PORT }}" >> .env + echo "DATABASE_CLIENT=${{ vars.DATABASE_CLIENT }}" >> .env + echo "DATABASE_FILENAME=${{ vars.DATABASE_FILENAME }}" >> .env + echo "ADMIN_JWT_SECRET=${{ secrets.ADMIN_JWT_SECRET }}" >> .env + echo "API_TOKEN_SALT=${{ secrets.API_TOKEN_SALT }}" >> .env + echo "APP_KEYS=${{ secrets.APP_KEYS }}" >> .env + echo "JWT_SECRET=${{ secrets.JWT_SECRET }}" >> .env + echo "TRANSFER_TOKEN_SALT=${{ secrets.TRANSFER_TOKEN_SALT }}" >> .env + # Create .env.production with HOST_URL Frontend + echo "HOST_URL=${{ vars.HOST_URL }}" >> .env.production + - name: Docker build + run: sudo docker-compose build + - name: Docker up + run: sudo docker-compose up -d diff --git a/Dockerfile-backend b/Dockerfile-backend new file mode 100644 index 0000000..413b3da --- /dev/null +++ b/Dockerfile-backend @@ -0,0 +1,9 @@ +FROM node:20 +WORKDIR /usr/src/app +COPY backend /usr/src/app/backend +COPY .env /usr/src/app/backend/.env +WORKDIR /usr/src/app/backend/ +RUN npm install +RUN NODE_ENV=production npm run build +EXPOSE 1337 +CMD ["npm", "run", "start"] diff --git a/Dockerfile-frontend b/Dockerfile-frontend new file mode 100644 index 0000000..4f5dd12 --- /dev/null +++ b/Dockerfile-frontend @@ -0,0 +1,8 @@ +FROM node:20 +WORKDIR /usr/src/app/frontend +COPY frontend /usr/src/app/frontend +COPY .env.production /usr/src/app/frontend/.env.production +RUN npm i +RUN npm run build +EXPOSE 3000 +CMD ["npm", "run", "start"] \ No newline at end of file diff --git a/backend/config/env/production/database.js b/backend/config/env/production/database.js index 702230d..03b6a89 100644 --- a/backend/config/env/production/database.js +++ b/backend/config/env/production/database.js @@ -1,22 +1,11 @@ -// path: ./config/env/production/database.js +const path = require("node:path"); -const { parse } = require("pg-connection-string"); - -module.exports = ({ env }) => { - const { host, port, database, user, password } = parse(env("DATABASE_URL")); - - return { +module.exports = ({ env }) => ({ + connection: { + client: "sqlite", connection: { - client: "postgres", - connection: { - host, - port, - database, - user, - password, - ssl: { rejectUnauthorized: false }, - }, - debug: false, + filename: env("DATABASE_FILENAME", "/tmp/strapi.db") }, - }; -}; + useNullAsDefault: true, + }, +}); diff --git a/backend/config/env/production/server.js b/backend/config/env/production/server.js index a991061..4ba610a 100644 --- a/backend/config/env/production/server.js +++ b/backend/config/env/production/server.js @@ -2,16 +2,6 @@ // starting from Strapi v 4.6.1 server.js has to be the following module.exports = ({ env }) => ({ - proxy: true, - host: "0.0.0.0", - port: process.env.PORT, - url: env("MY_HEROKU_URL"), - app: { - keys: env.array("APP_KEYS"), - }, - admin: { - auth: { - secret: env("ADMIN_JWT_SECRET"), - }, - }, + host: env("HOST", "0.0.0.0"), + port: env.int("PORT", 1337), }); diff --git a/backend/config/plugins.js b/backend/config/plugins.js index 87e159f..bce7ff4 100644 --- a/backend/config/plugins.js +++ b/backend/config/plugins.js @@ -4,11 +4,12 @@ module.exports = { config: { endpoint: "/graphql", shadowCRUD: true, - playgroundAlways: false, + playgroundAlways: true, depthLimit: 20, amountLimit: 100, apolloServer: { tracing: false, + introspection: true, }, }, }, @@ -16,7 +17,7 @@ module.exports = { // enables the plugin only in development mode // if you also want to use it in production, set this to true // keep in mind that graphql playground has to be enabled - enabled: process.env.NODE_ENV === "production" ? false : true, + enabled: true // endpoint: "https://tunneled-strapi.com/graphql", // OPTIONAL - endpoint has to be accessible from the browser }, }; diff --git a/backend/server.js b/backend/server.js new file mode 100644 index 0000000..81a6de9 --- /dev/null +++ b/backend/server.js @@ -0,0 +1,2 @@ +const strapi = require("@strapi/strapi"); +strapi().start(); diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b4a4a1b --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,21 @@ +version: "3.8" +services: + backend-app: + volumes: + - type: bind + source: /var/data/ + target: /var/data/ + build: + context: . + dockerfile: Dockerfile-backend + ports: + - "1337:1337" + environment: + - NODE_ENV=production + + frontend-app: + build: + context: . + dockerfile: Dockerfile-frontend + ports: + - "3000:3000" diff --git a/docs/deployment.md b/docs/deployment.md new file mode 100644 index 0000000..bb27669 --- /dev/null +++ b/docs/deployment.md @@ -0,0 +1,53 @@ +See the following docs for more info about strapi deployment: +[https://docs.strapi.io/dev-docs/deployment](https://docs.strapi.io/dev-docs/deployment) + +We use [`pm2`](https://www.npmjs.com/package/pm2) as our process manager to run our node.js frontend and backend. + +### Setting up ntnu halfadministrated server + +###### SSH + +We have created a firewall rule to allow remote ssh connections, such that we can remote in form a github runner and autodeploy. First we create a firewall rule: + +`/etc/local/firewall.d $ touch ipv4-magnastr-docker-website-git-autodeply.conf` + +do `sudo nano ipv4-magnastr-docker-website-git-autodeply.conf` to enter the file and edit the content + +paste the lines + +``` +-I INPUT -p tcp -m tcp --dport 22 -j ACCEPT +-I INPUT -p tcp -m tcp --dport 3000 -j ACCEPT +``` + +###### PKGSYNC + +Make sure docker compose is installed on the server. + +Can be checked by running `docker compose version` + +Also make sure to install `pm2` + +###### Github Runner + +Setup a self hosted GitHub runner for the repository. + +###### Secrets and variables + +The secrets should all be filled in and generated using `openssl rand -base64 32` + +The GitHub repo should define the following secrets: + +- ADMIN_JWT_SECRET +- API_TOKEN_SALT +- APP_KEYS +- JWT_SECRET +- TRANSFER_TOKEN_SALT + +And the following variables: + +- DATABASE_CLIENT=sqlite +- DATABASE_FILENAME=/var/data/strapi.db +- HOST=0.0.0.0 +- HOST_URL=http://backend-app:1337 +- PORT=1337 \ No newline at end of file diff --git a/frontend/.env.production b/frontend/.env.production index 517cff9..ba9e7ab 100644 --- a/frontend/.env.production +++ b/frontend/.env.production @@ -1,2 +1,2 @@ -# Heroku Database API -HOST_URL=https://small-sat-lab-6ad3da13947b.herokuapp.com \ No newline at end of file +# Database url +HOST_URL=http://backend-app:1337