feat: Add initial local Docker Swarm deployment setup and frontend application structure with project state management.
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
Some checks failed
Build and Deploy / build-and-deploy (push) Has been cancelled
This commit is contained in:
52
deploy/local/README.md
Normal file
52
deploy/local/README.md
Normal file
@@ -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.
|
||||
68
deploy/local/docker-compose.yml
Normal file
68
deploy/local/docker-compose.yml
Normal file
@@ -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
|
||||
@@ -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 (
|
||||
<Layout style={{ height: '100vh' }}>
|
||||
<Sider width={300} theme="light">
|
||||
<Sider width={300} theme="light" style={{ borderRight: '1px solid #f0f0f0' }}>
|
||||
<Sidebar />
|
||||
</Sider>
|
||||
<Layout>
|
||||
<Content>
|
||||
<Content style={{ background: '#fff' }}>
|
||||
<MindMap />
|
||||
</Content>
|
||||
</Layout>
|
||||
|
||||
@@ -16,8 +16,17 @@ interface ProjectState {
|
||||
setExpandedKeys: (keys: string[]) => void;
|
||||
setSelectedKey: (key: string | null) => void;
|
||||
expandNode: (key: string) => void;
|
||||
fetchProjects: () => Promise<void>;
|
||||
}
|
||||
|
||||
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<ProjectState>((set) => ({
|
||||
projects: [],
|
||||
expandedKeys: [],
|
||||
@@ -31,4 +40,19 @@ export const useProjectStore = create<ProjectState>((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 });
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user