From 066c16221d2512e7f2293588f2a3b22285063fa0 Mon Sep 17 00:00:00 2001 From: gitmuhammedalbayrak Date: Mon, 24 Nov 2025 05:15:49 +0300 Subject: [PATCH] feat: Add initial local Docker Swarm deployment setup and frontend application structure with project state management. --- deploy/local/README.md | 52 ++++++++++++++++++++ deploy/local/docker-compose.yml | 68 +++++++++++++++++++++++++++ frontend/src/App.tsx | 11 ++++- frontend/src/store/useProjectStore.ts | 24 ++++++++++ 4 files changed, 153 insertions(+), 2 deletions(-) create mode 100644 deploy/local/README.md create mode 100644 deploy/local/docker-compose.yml diff --git a/deploy/local/README.md b/deploy/local/README.md new file mode 100644 index 0000000..5c55718 --- /dev/null +++ b/deploy/local/README.md @@ -0,0 +1,52 @@ +# Local Development with Docker Swarm + +This directory contains the configuration to run the Evrak application locally using Docker Swarm on Windows 11. + +## Prerequisites + +1. **Docker Desktop**: Ensure Docker Desktop is installed and running. +2. **Swarm Mode**: Enable Swarm mode if not already enabled: + ```powershell + docker swarm init + ``` + +## How to Deploy + +### 1. Build Images +First, build the Docker images locally. `docker stack deploy` does not build images, so this step is required. + +```powershell +docker compose -f deploy/local/docker-compose.yml build +``` + +### 2. Deploy to Swarm +Deploy the stack to your local Swarm cluster. + +```powershell +docker stack deploy -c deploy/local/docker-compose.yml evrak +``` + +### 3. Verify +Check if the services are running: + +```powershell +docker service ls +docker stack ps evrak +``` + +Access the application: +* **Frontend**: http://localhost +* **Backend API**: http://localhost:3000 +* **Database**: localhost:5432 + +### 4. Remove Stack +To stop and remove the application: + +```powershell +docker stack rm evrak +``` + +## Troubleshooting + +* **Image not found**: Make sure you ran the build step. +* **Ports occupied**: Ensure ports 80, 3000, and 5432 are free on your host machine. diff --git a/deploy/local/docker-compose.yml b/deploy/local/docker-compose.yml new file mode 100644 index 0000000..968f222 --- /dev/null +++ b/deploy/local/docker-compose.yml @@ -0,0 +1,68 @@ +version: '3.8' + +services: + postgres: + image: postgres:14-alpine + environment: + POSTGRES_USER: evrak_user + POSTGRES_PASSWORD: evrak_password + POSTGRES_DB: evrak + ports: + - "5432:5432" + volumes: + - db_data:/var/lib/postgresql/data + networks: + - evrak-net + deploy: + replicas: 1 + restart_policy: + condition: on-failure + + backend: + # Note: 'docker stack deploy' ignores 'build'. You must run 'docker compose build' first. + build: + context: ../../backend + dockerfile: Dockerfile + image: evrak-backend:local + environment: + DB_HOST: postgres + DB_PORT: 5432 + DB_USERNAME: evrak_user + DB_PASSWORD: evrak_password + DB_DATABASE: evrak + PORT: 3000 + ports: + - "3000:3000" + depends_on: + - postgres + networks: + - evrak-net + deploy: + replicas: 1 + restart_policy: + condition: on-failure + + frontend: + build: + context: ../../frontend + dockerfile: Dockerfile + image: evrak-frontend:local + ports: + - "80:80" + depends_on: + - backend + networks: + - evrak-net + deploy: + replicas: 1 + restart_policy: + condition: on-failure + +volumes: + db_data: + + +networks: + evrak-net: + driver: overlay + attachable: true diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 2019aa0..4eeea0f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -2,17 +2,24 @@ import React from 'react'; import { Layout } from 'antd'; import Sidebar from './components/Sidebar'; import MindMap from './components/MindMap'; +import { useProjectStore } from './store/useProjectStore'; const { Sider, Content } = Layout; const App: React.FC = () => { + const { fetchProjects } = useProjectStore(); + + React.useEffect(() => { + fetchProjects(); + }, [fetchProjects]); + return ( - + - + diff --git a/frontend/src/store/useProjectStore.ts b/frontend/src/store/useProjectStore.ts index e69ee90..2ec2365 100644 --- a/frontend/src/store/useProjectStore.ts +++ b/frontend/src/store/useProjectStore.ts @@ -16,8 +16,17 @@ interface ProjectState { setExpandedKeys: (keys: string[]) => void; setSelectedKey: (key: string | null) => void; expandNode: (key: string) => void; + fetchProjects: () => Promise; } +const DUMMY_PROJECTS: Project[] = [ + { id: '1', name: 'Genel Merkez', path: 'root', parentId: null }, + { id: '2', name: 'Yazılım Departmanı', path: 'root.software', parentId: '1' }, + { id: '3', name: 'İnsan Kaynakları', path: 'root.hr', parentId: '1' }, + { id: '4', name: 'Evrak Projesi', path: 'root.software.evrak', parentId: '2' }, + { id: '5', name: 'Website Yenileme', path: 'root.software.website', parentId: '2' }, +]; + export const useProjectStore = create((set) => ({ projects: [], expandedKeys: [], @@ -31,4 +40,19 @@ export const useProjectStore = create((set) => ({ ? state.expandedKeys : [...state.expandedKeys, key], })), + fetchProjects: async () => { + try { + const response = await fetch('http://localhost:3000/projects'); + if (response.ok) { + const data = await response.json(); + set({ projects: data }); + } else { + console.error('Failed to fetch projects'); + set({ projects: DUMMY_PROJECTS }); + } + } catch (error) { + console.error('Error fetching projects:', error); + set({ projects: DUMMY_PROJECTS }); + } + }, }));