From 787c97a52f03b4bf04e13ef53eaef253908598a3 Mon Sep 17 00:00:00 2001 From: Mike Johnston Date: Wed, 28 Jan 2026 23:52:15 -0500 Subject: [PATCH] initial commit --- .env.example | 6 +++ .gitea/workflows/rebuild-prod.yaml | 76 ++++++++++++++++++++++++++++++ .gitignore | 15 ++++++ README.md | 36 ++++++++++++++ backend/Dockerfile | 7 +++ backend/package.json | 17 +++++++ backend/src/index.js | 17 +++++++ docker-compose.yml | 42 +++++++++++++++++ frontend/Dockerfile | 7 +++ frontend/index.html | 12 +++++ frontend/package.json | 17 +++++++ frontend/src/main.jsx | 9 ++++ prod-compose.yml | 29 ++++++++++++ 13 files changed, 290 insertions(+) create mode 100644 .env.example create mode 100644 .gitea/workflows/rebuild-prod.yaml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 backend/Dockerfile create mode 100644 backend/package.json create mode 100644 backend/src/index.js create mode 100644 docker-compose.yml create mode 100644 frontend/Dockerfile create mode 100644 frontend/index.html create mode 100644 frontend/package.json create mode 100644 frontend/src/main.jsx create mode 100644 prod-compose.yml diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..0be3edc --- /dev/null +++ b/.env.example @@ -0,0 +1,6 @@ +# Backend +PORT=4000 +JWT_SECRET=your_jwt_secret +DATABASE_URL=postgres://postgres:postgres@db:5432/whats_the_point +# Frontend +VITE_API_URL=http://localhost:4000 diff --git a/.gitea/workflows/rebuild-prod.yaml b/.gitea/workflows/rebuild-prod.yaml new file mode 100644 index 0000000..51d55e1 --- /dev/null +++ b/.gitea/workflows/rebuild-prod.yaml @@ -0,0 +1,76 @@ +# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions +name: Build Images and Deploy +run-name: ${{ gitea.actor }} is building new PROD images and redeploying the existing stack 🚀 +on: + push: + # not working right now https://github.com/actions/runner/issues/2324 + # paths-ignore: + # - **.yml + branches: + - main + +env: + STACK_NAME: wtp-prod + DOT_ENV: ${{ secrets.PROD_ENV }} + PORTAINER_TOKEN: ${{ secrets.PORTAINER_TOKEN }} + PORTAINER_API_URL: https://portainer.dev.nervesocket.com/api + ENDPOINT_NAME: "mini" #sometimes "primary" + IMAGE_TAG: "reg.dev.nervesocket.com/wtp-prod:release" + +jobs: + Update-PROD-Stack: + runs-on: ubuntu-latest + steps: + # if: contains(github.event.pull_request.head.ref, 'init-stack') + - name: Checkout + uses: actions/checkout@v4 + with: + ref: main + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v1 + + - name: Build and push PROD Docker image + run: | + echo $DOT_ENV | base64 -d > .env + echo .env + docker buildx build --push -t $IMAGE_TAG . + + - name: Get the endpoint ID + # Usually ID is 1, but you can get it from the API. Only skip this if you are VERY sure. + run: | + ENDPOINT_ID=$(curl -s -H "X-API-Key: $PORTAINER_TOKEN" "$PORTAINER_API_URL/endpoints" | jq -r ".[] | select(.Name==\"$ENDPOINT_NAME\") | .Id") + echo "ENDPOINT_ID=$ENDPOINT_ID" >> $GITHUB_ENV + echo "Got stack Endpoint ID: $ENDPOINT_ID" + + - name: Fetch stack ID from Portainer + run: | + STACK_ID=$(curl -s -H "X-API-Key: $PORTAINER_TOKEN" "$PORTAINER_API_URL/stacks" | jq -r ".[] | select(.Name==\"$STACK_NAME\" and .EndpointId==$ENDPOINT_ID) | .Id") + + echo "STACK_ID=$STACK_ID" >> $GITHUB_ENV + echo "Got stack ID: $STACK_ID matched with Endpoint ID: $ENDPOINT_ID" + + - name: Redeploy stack in Portainer + run: | + # Read stack file content + STACK_FILE_CONTENT=$(echo "$( { + res.json({ message: "What's The Point API" }); +}); + +const PORT = process.env.PORT || 4000; +app.listen(PORT, () => { + console.log(`API running on port ${PORT}`); +}); diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f84c0c3 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,42 @@ +version: '3.8' +services: + db: + image: postgres:15 + restart: unless-stopped + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: whats_the_point + volumes: + - db_data:/var/lib/postgresql/data + ports: + - "5432:5432" + + backend: + build: ./backend + restart: unless-stopped + environment: + PORT: 4000 + JWT_SECRET: your_jwt_secret + DATABASE_URL: postgres://postgres:postgres@db:5432/whats_the_point + depends_on: + - db + ports: + - "4000:4000" + volumes: + - ./backend:/app + + frontend: + build: ./frontend + restart: unless-stopped + environment: + VITE_API_URL: http://localhost:4000 + depends_on: + - backend + ports: + - "5173:5173" + volumes: + - ./frontend:/app + +volumes: + db_data: diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..342df35 --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,7 @@ +FROM node:20-alpine +WORKDIR /app +COPY package*.json ./ +RUN npm install +COPY . . +EXPOSE 5173 +CMD ["npm", "run", "dev"] diff --git a/frontend/index.html b/frontend/index.html new file mode 100644 index 0000000..46eea29 --- /dev/null +++ b/frontend/index.html @@ -0,0 +1,12 @@ + + + + + + What's The Point + + +
+ + + diff --git a/frontend/package.json b/frontend/package.json new file mode 100644 index 0000000..a3cf751 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,17 @@ +{ + "name": "wtp-frontend", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview" + }, + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "vite": "^5.0.0" + } +} diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx new file mode 100644 index 0000000..27e12b5 --- /dev/null +++ b/frontend/src/main.jsx @@ -0,0 +1,9 @@ +import React from 'react'; +import ReactDOM from 'react-dom/client'; + +const App = () =>
+

What's The Point

+

Welcome! The app is running.

+
; + +ReactDOM.createRoot(document.getElementById('root')).render(); diff --git a/prod-compose.yml b/prod-compose.yml new file mode 100644 index 0000000..7fd6f3b --- /dev/null +++ b/prod-compose.yml @@ -0,0 +1,29 @@ +services: + web: + image: reg.dev.nervesocket.com/wtp-prod:release + depends_on: + - db + restart: unless-stopped + environment: + - APACHE_LOG_DIR=/var/www/app + - TZ=America/Toronto + volumes: + - /volume1/docker/wtp-prod/production_web:/app/public/storage + ports: + - 22798:80 + + db: + # image: mariadb:10.7 + image: linuxserver/mariadb + restart: unless-stopped + environment: + - MYSQL_ROOT_PASSWORD=XLxXDnUvfkTbDzDlEP5Gy8It + - TZ=America/Toronto + volumes: + - /volume1/docker/wtp-prod/db:/config + + adminer: + image: adminer + restart: unless-stopped + ports: + - 22582:8080 \ No newline at end of file