chore: setup docker, gitea actions pipeline and docs
Some checks failed
Build and Deploy / build-and-push (push) Failing after 3m18s
Some checks failed
Build and Deploy / build-and-push (push) Failing after 3m18s
This commit is contained in:
43
.gitea/workflows/deploy.yaml
Normal file
43
.gitea/workflows/deploy.yaml
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
name: Build and Deploy
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- master
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-latest # Adjust if your runner uses a different label
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Login to Gitea Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: gitea.blyzer.com.br
|
||||||
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
|
password: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
push: true
|
||||||
|
tags: |
|
||||||
|
gitea.blyzer.com.br/${{ gitea.repository }}:latest
|
||||||
|
gitea.blyzer.com.br/${{ gitea.repository }}:${{ gitea.sha }}
|
||||||
|
build-args: |
|
||||||
|
API_KEY=${{ secrets.API_KEY || '' }}
|
||||||
|
|
||||||
|
- name: Deploy to Portainer
|
||||||
|
run: |
|
||||||
|
if [ -n "${{ secrets.PORTAINER_WEBHOOK }}" ]; then
|
||||||
|
curl -k -X POST "${{ secrets.PORTAINER_WEBHOOK }}"
|
||||||
|
else
|
||||||
|
echo "PORTAINER_WEBHOOK secret not set, skipping deployment trigger."
|
||||||
|
fi
|
||||||
47
Dockerfile
Normal file
47
Dockerfile
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
# Stage 1: Build the React application
|
||||||
|
FROM node:20-alpine AS builder
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Copy package.json and package-lock.json first to leverage Docker cache
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN npm ci
|
||||||
|
|
||||||
|
# Copy the rest of the application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Accept the API_KEY as a build argument
|
||||||
|
ARG API_KEY
|
||||||
|
ENV API_KEY=$API_KEY
|
||||||
|
|
||||||
|
# Build the application
|
||||||
|
RUN npm run build
|
||||||
|
|
||||||
|
# Stage 2: Serve the application with Node.js
|
||||||
|
FROM node:20-alpine AS runner
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Set environment to production
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
ENV PORT=8080
|
||||||
|
|
||||||
|
# Copy package.json and package-lock.json for production dependencies
|
||||||
|
COPY package*.json ./
|
||||||
|
|
||||||
|
# Install only production dependencies
|
||||||
|
RUN npm ci --only=production
|
||||||
|
|
||||||
|
# Copy the built assets from the builder stage
|
||||||
|
COPY --from=builder /app/dist ./dist
|
||||||
|
|
||||||
|
# Copy the server script
|
||||||
|
COPY server.js .
|
||||||
|
|
||||||
|
# Expose the port the app runs on
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Start the server
|
||||||
|
CMD ["node", "server.js"]
|
||||||
61
GEMINI.md
Normal file
61
GEMINI.md
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
# Project: ComFi Management System
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
ComFi is a React-based financial and management dashboard.
|
||||||
|
- **Frontend:** React 19, Vite, TypeScript.
|
||||||
|
- **Serving (Production):** Node.js (Express) via `server.js`.
|
||||||
|
- **State Management:** Context API (`ComFiContext`, `ToastContext`).
|
||||||
|
- **Styling:** CSS / Lucide React icons.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Current (Local)
|
||||||
|
- **Dev Server:** `vite` (HMR, local dev).
|
||||||
|
- **Prod Preview:** `node server.js` serving `dist/`.
|
||||||
|
|
||||||
|
### Target (Production)
|
||||||
|
- **Containerization:** Docker (Multi-stage build).
|
||||||
|
- **Orchestration:** Docker Swarm (managed via Portainer).
|
||||||
|
- **CI/CD:** Gitea Actions.
|
||||||
|
- **Reverse Proxy:** Traefik or Nginx (implied by Swarm/Portainer setup, usually handles SSL termination).
|
||||||
|
|
||||||
|
## Deployment Roadmap
|
||||||
|
|
||||||
|
### 1. Dockerization
|
||||||
|
- Create `Dockerfile`:
|
||||||
|
- **Stage 1 (Builder):** Install deps, run `npm run build` to generate `dist/`.
|
||||||
|
- **Stage 2 (Runner):** Alpine Node image, copy `dist/`, `server.js`, and `package.json`. Run `npm install --production`.
|
||||||
|
- Create `docker-compose.yml` for local testing of the production build.
|
||||||
|
|
||||||
|
### 2. CI/CD (Gitea Actions)
|
||||||
|
- Define workflow `.gitea/workflows/deploy.yaml`.
|
||||||
|
- **Steps:**
|
||||||
|
- Checkout code.
|
||||||
|
- Login to Container Registry.
|
||||||
|
- Build and Push Docker Image (tagged with commit SHA and `latest`).
|
||||||
|
- Trigger Deployment (Portainer Webhook).
|
||||||
|
|
||||||
|
### 3. Portainer & Swarm Configuration
|
||||||
|
- **Stack Definition:** A `docker-compose` style file for Swarm.
|
||||||
|
- **Secrets Management:**
|
||||||
|
- Registry Credentials (if private).
|
||||||
|
- Environment variables (if any, e.g., API endpoints).
|
||||||
|
- **Update Mechanism:** Webhook URL provided by Portainer Service.
|
||||||
|
|
||||||
|
## Required Configuration & Secrets
|
||||||
|
To proceed, we will need to define:
|
||||||
|
1. **Registry URL:** `gitea.blyzer.com.br`
|
||||||
|
2. **Image Name:** `gitea.blyzer.com.br/blyzer/comfi`
|
||||||
|
3. **Portainer Webhook:** The URL Portainer provides to trigger a service update.
|
||||||
|
|
||||||
|
### Secrets (Gitea)
|
||||||
|
Set these in your Gitea repository settings (Settings > Actions > Secrets):
|
||||||
|
- `REGISTRY_USERNAME`: Your Gitea username.
|
||||||
|
- `REGISTRY_TOKEN`: Your Gitea password or token.
|
||||||
|
- `PORTAINER_WEBHOOK`: The full webhook URL from Portainer.
|
||||||
|
- `API_KEY`: (Optional) Google GenAI API key.
|
||||||
|
|
||||||
|
## Directives
|
||||||
|
- **Conventions:** Follow existing TypeScript and React patterns.
|
||||||
|
- **Safety:** Do not commit `.env` files.
|
||||||
|
- **Style:** Maintain the clean, dashboard-style UI.
|
||||||
@@ -20,6 +20,10 @@ interface Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const AIChatAssistant: React.FC<AIChatAssistantProps> = ({ userName, contextData }) => {
|
export const AIChatAssistant: React.FC<AIChatAssistantProps> = ({ userName, contextData }) => {
|
||||||
|
if (!process.env.API_KEY) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [isTyping, setIsTyping] = useState(false);
|
const [isTyping, setIsTyping] = useState(false);
|
||||||
const [inputValue, setInputValue] = useState('');
|
const [inputValue, setInputValue] = useState('');
|
||||||
|
|||||||
12
docker-compose.yml
Normal file
12
docker-compose.yml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
version: '3.8'
|
||||||
|
|
||||||
|
services:
|
||||||
|
comfi-app:
|
||||||
|
build: .
|
||||||
|
image: gitea.blyzer.com.br/blyzer/comfi:latest
|
||||||
|
container_name: comfi-dashboard
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
- NODE_ENV=production
|
||||||
|
restart: unless-stopped
|
||||||
Reference in New Issue
Block a user