Add frontend access instructions to README
Added instructions to access the frontend after running the container.
This commit is contained in:
@@ -1,3 +0,0 @@
|
|||||||
[submodule "excalidraw"]
|
|
||||||
path = excalidraw
|
|
||||||
url = git@github.com:ZimengXiong/excalidraw.git
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
# ExcaliDash Docker Setup
|
|
||||||
|
|
||||||
This Docker setup containerizes the ExcaliDash application with a multi-container architecture.
|
|
||||||
|
|
||||||
## Architecture
|
|
||||||
|
|
||||||
- **Frontend**: React/Vite app served by Nginx
|
|
||||||
- **Backend**: Express.js API with Socket.IO
|
|
||||||
- **Database**: SQLite (persisted in Docker volume)
|
|
||||||
|
|
||||||
## Single Port Exposure
|
|
||||||
|
|
||||||
The application exposes only **port 6767** externally, which serves the frontend. The frontend's Nginx acts as a reverse proxy to route:
|
|
||||||
|
|
||||||
- `/api/*` requests to the backend container
|
|
||||||
- `/socket.io/*` WebSocket connections to the backend container
|
|
||||||
|
|
||||||
All inter-container communication happens on an internal Docker network.
|
|
||||||
|
|
||||||
## Quick Start
|
|
||||||
|
|
||||||
### Option 1: Use Pre-built Images from Docker Hub (Recommended)
|
|
||||||
|
|
||||||
Pull and run the latest multi-platform images:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose -f docker-compose.prod.yml up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
### Option 2: Build Locally
|
|
||||||
|
|
||||||
Build and run all services locally:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose up -d --build
|
|
||||||
```
|
|
||||||
|
|
||||||
### Access the application:
|
|
||||||
|
|
||||||
[http://localhost:6767](http://localhost:6767)
|
|
||||||
|
|
||||||
## Publishing to Docker Hub
|
|
||||||
|
|
||||||
### Build and Push Multi-Platform Images
|
|
||||||
|
|
||||||
The `publish-docker.sh` script builds images for multiple platforms (amd64, arm64) and pushes them to Docker Hub:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build and push with 'latest' tag
|
|
||||||
./publish-docker.sh
|
|
||||||
|
|
||||||
# Build and push with a specific version
|
|
||||||
./publish-docker.sh v1.0.0
|
|
||||||
```
|
|
||||||
|
|
||||||
## Database
|
|
||||||
|
|
||||||
The SQLite database is stored in a Docker volume named `backend-data` which persists data across container restarts. Database migrations run automatically when the backend container starts.
|
|
||||||
|
|
||||||
## Environment Variables
|
|
||||||
|
|
||||||
Default configuration works out of the box. To customize:
|
|
||||||
|
|
||||||
Create `.env` files in `backend/` or `frontend/` directories:
|
|
||||||
|
|
||||||
**Backend `.env`:**
|
|
||||||
|
|
||||||
```
|
|
||||||
PORT=8000
|
|
||||||
NODE_ENV=production
|
|
||||||
```
|
|
||||||
|
|
||||||
**Frontend `.env`:**
|
|
||||||
|
|
||||||
```
|
|
||||||
VITE_API_URL=/api
|
|
||||||
```
|
|
||||||
|
|
||||||
## Port Mapping
|
|
||||||
|
|
||||||
- **6767** (external) → **80** (frontend nginx) → Routes to backend on internal network
|
|
||||||
- **8000** (internal only) - Backend API server
|
|
||||||
|
|
||||||
Only port 6767 is accessible from outside the Docker network.
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# ExcaliDash v0.1.0
|
# ExcaliDash v0.1.0
|
||||||
|
|
||||||
A beautiful, self hosted dashboard and organizer for [Excalidraw](https://github.com/excalidraw/excalidraw) with live collaboration.
|
A self hosted dashboard and organizer for [Excalidraw](https://github.com/excalidraw/excalidraw) with live collaboration.
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
@@ -52,6 +52,8 @@ docker compose -f docker-compose.prod.yml pull
|
|||||||
|
|
||||||
# Run container
|
# Run container
|
||||||
docker compose -f docker-compose.prod.yml up -d
|
docker compose -f docker-compose.prod.yml up -d
|
||||||
|
|
||||||
|
# Access the frontend at localhost:6767
|
||||||
```
|
```
|
||||||
|
|
||||||
## Docker build
|
## Docker build
|
||||||
|
|||||||
@@ -93,7 +93,6 @@ export const Dashboard: React.FC = () => {
|
|||||||
type SortField = 'name' | 'createdAt' | 'updatedAt';
|
type SortField = 'name' | 'createdAt' | 'updatedAt';
|
||||||
type SortDirection = 'asc' | 'desc';
|
type SortDirection = 'asc' | 'desc';
|
||||||
|
|
||||||
// ... (rest of existing state)
|
|
||||||
|
|
||||||
const searchInputRef = useRef<HTMLInputElement>(null);
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
@@ -126,7 +125,6 @@ export const Dashboard: React.FC = () => {
|
|||||||
refreshData();
|
refreshData();
|
||||||
}, [refreshData]);
|
}, [refreshData]);
|
||||||
|
|
||||||
// ... (Drag selection logic remains same)
|
|
||||||
// Drag File State
|
// Drag File State
|
||||||
const [isDraggingFile, setIsDraggingFile] = useState(false);
|
const [isDraggingFile, setIsDraggingFile] = useState(false);
|
||||||
const dragCounter = useRef(0);
|
const dragCounter = useRef(0);
|
||||||
@@ -222,7 +220,6 @@ export const Dashboard: React.FC = () => {
|
|||||||
setDragCurrent({ x: e.clientX, y: e.clientY });
|
setDragCurrent({ x: e.clientX, y: e.clientY });
|
||||||
};
|
};
|
||||||
|
|
||||||
// ... (Sorting logic remains same)
|
|
||||||
const sortedDrawings = React.useMemo(() => {
|
const sortedDrawings = React.useMemo(() => {
|
||||||
return [...drawings].sort((a, b) => {
|
return [...drawings].sort((a, b) => {
|
||||||
const { field, direction } = sortConfig;
|
const { field, direction } = sortConfig;
|
||||||
@@ -488,7 +485,6 @@ export const Dashboard: React.FC = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// ... (rest of handlers like Create/Edit/Delete Collection remain same)
|
|
||||||
const handleMoveToCollection = async (id: string, collectionId: string | null) => {
|
const handleMoveToCollection = async (id: string, collectionId: string | null) => {
|
||||||
setDrawings(prev => {
|
setDrawings(prev => {
|
||||||
return prev.map(d => d.id === id ? { ...d, collectionId } : d)
|
return prev.map(d => d.id === id ? { ...d, collectionId } : d)
|
||||||
|
|||||||
Reference in New Issue
Block a user