mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-05 02:43:32 +00:00
feat: move docker files to root
This commit is contained in:
parent
ae728f33ad
commit
525b623703
9 changed files with 124 additions and 84 deletions
19
.dockerignore
Normal file
19
.dockerignore
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
.git
|
||||
.gitignore
|
||||
.DS_Store
|
||||
|
||||
node_modules
|
||||
**/node_modules
|
||||
|
||||
dist
|
||||
**/dist
|
||||
coverage
|
||||
**/coverage
|
||||
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
.gitnexus
|
||||
gitnexus-web/playwright-report
|
||||
gitnexus-web/test-results
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
IMAGE_NAME=ghcr.io/abhigyanpatwari/gitnexus-web:latest
|
||||
CONTAINER_NAME=gitnexus-web
|
||||
HOST_PORT=8080
|
||||
HOST_PORT=4173
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -23,6 +23,7 @@ Thumbs.db
|
|||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
docker/.env
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
|
@ -95,4 +96,4 @@ GitNexus.sln
|
|||
|
||||
.swarm/
|
||||
|
||||
local_docs/
|
||||
local_docs/
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
FROM node:20-alpine AS builder
|
||||
ARG BUILDPLATFORM
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
FROM --platform=$BUILDPLATFORM node:20-bookworm-slim AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
|
|
@ -15,11 +18,13 @@ RUN npm ci --prefix gitnexus-web
|
|||
COPY gitnexus-web ./gitnexus-web
|
||||
RUN npm run build --prefix gitnexus-web
|
||||
|
||||
FROM nginx:1.27-alpine AS runtime
|
||||
FROM --platform=$TARGETPLATFORM node:20-bookworm-slim AS runtime
|
||||
|
||||
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=builder /app/gitnexus-web/dist /usr/share/nginx/html
|
||||
WORKDIR /app
|
||||
|
||||
EXPOSE 80
|
||||
COPY --from=builder /app/gitnexus-web/dist ./dist
|
||||
COPY docker-server.mjs ./docker-server.mjs
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
EXPOSE 4173
|
||||
|
||||
CMD ["node", "docker-server.mjs"]
|
||||
25
README.md
25
README.md
|
|
@ -340,17 +340,36 @@ npm run dev
|
|||
```bash
|
||||
docker run --rm \
|
||||
--name gitnexus-web \
|
||||
-p 8080:80 \
|
||||
-p 4173:4173 \
|
||||
ghcr.io/abhigyanpatwari/gitnexus-web:latest
|
||||
```
|
||||
|
||||
Or with Docker Compose:
|
||||
|
||||
```bash
|
||||
docker compose -f docker/compose.yaml up -d
|
||||
docker compose -f docker-compose.yaml up -d
|
||||
```
|
||||
|
||||
Docker details, including the example `.env`, compose file, and the source [docker/Dockerfile](docker/Dockerfile), live in [docker/README.md](docker/README.md).
|
||||
Optional env file:
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
set -a
|
||||
source .env
|
||||
set +a
|
||||
```
|
||||
|
||||
Docker files:
|
||||
|
||||
- [Dockerfile](Dockerfile) is the source for the published `gitnexus-web` image. It builds `gitnexus-shared` and `gitnexus-web`, then runs the app directly with Vite preview.
|
||||
- [docker-compose.yaml](docker-compose.yaml) starts the published image with Docker Compose.
|
||||
- [.env.example](.env.example) sets the image name, container name, and exposed port for the example commands.
|
||||
|
||||
Notes:
|
||||
|
||||
- The published image serves the production frontend only. It does not start `gitnexus serve`.
|
||||
- In backend mode, the app still defaults to `http://localhost:4747` unless you change the server URL in the UI.
|
||||
- If you do not want an env file, the defaults are `ghcr.io/abhigyanpatwari/gitnexus-web:latest`, container name `gitnexus-web`, and port `4173`.
|
||||
|
||||
The web UI uses the same indexing pipeline as the CLI but runs entirely in WebAssembly (Tree-sitter WASM, LadybugDB WASM, in-browser embeddings). It's great for quick exploration but limited by browser memory for larger repos.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
services:
|
||||
gitnexus-web:
|
||||
image: ${IMAGE_NAME:-ghcr.io/abhigyanpatwari/gitnexus-web:latest}
|
||||
image: ${IMAGE_NAME:-ghcr.io/abhigyanpatwari/gitnexus:latest}
|
||||
container_name: ${CONTAINER_NAME:-gitnexus-web}
|
||||
ports:
|
||||
- "${HOST_PORT:-8080}:80"
|
||||
- "${HOST_PORT:-4173}:4173"
|
||||
restart: unless-stopped
|
||||
67
docker-server.mjs
Normal file
67
docker-server.mjs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { createReadStream, existsSync } from 'node:fs';
|
||||
import { stat } from 'node:fs/promises';
|
||||
import { createServer } from 'node:http';
|
||||
import { extname, join, normalize } from 'node:path';
|
||||
|
||||
const host = '0.0.0.0';
|
||||
const port = Number(process.env.PORT || '4173');
|
||||
const root = join(process.cwd(), 'dist');
|
||||
|
||||
const contentTypes = {
|
||||
'.css': 'text/css; charset=utf-8',
|
||||
'.html': 'text/html; charset=utf-8',
|
||||
'.js': 'text/javascript; charset=utf-8',
|
||||
'.json': 'application/json; charset=utf-8',
|
||||
'.map': 'application/json; charset=utf-8',
|
||||
'.png': 'image/png',
|
||||
'.svg': 'image/svg+xml',
|
||||
'.txt': 'text/plain; charset=utf-8',
|
||||
'.woff': 'font/woff',
|
||||
'.woff2': 'font/woff2',
|
||||
};
|
||||
|
||||
function resolvePath(urlPath) {
|
||||
const cleanPath = normalize(decodeURIComponent(urlPath).replace(/^\/+/, ''));
|
||||
const candidate = join(root, cleanPath);
|
||||
if (!candidate.startsWith(root)) return null;
|
||||
return candidate;
|
||||
}
|
||||
|
||||
const server = createServer(async (req, res) => {
|
||||
const requestPath = req.url?.split('?')[0] || '/';
|
||||
let filePath = resolvePath(requestPath);
|
||||
|
||||
if (!filePath) {
|
||||
res.writeHead(400);
|
||||
res.end('Bad request');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const fileStat = await stat(filePath).catch(() => null);
|
||||
if (fileStat?.isDirectory()) {
|
||||
filePath = join(filePath, 'index.html');
|
||||
} else if (!fileStat?.isFile()) {
|
||||
filePath = join(root, 'index.html');
|
||||
}
|
||||
|
||||
if (!existsSync(filePath)) {
|
||||
res.writeHead(404);
|
||||
res.end('Not found');
|
||||
return;
|
||||
}
|
||||
|
||||
res.writeHead(200, {
|
||||
'Cache-Control': filePath.includes('/assets/') ? 'public, max-age=31536000, immutable' : 'no-cache',
|
||||
'Content-Type': contentTypes[extname(filePath)] || 'application/octet-stream',
|
||||
});
|
||||
createReadStream(filePath).pipe(res);
|
||||
} catch (error) {
|
||||
res.writeHead(500);
|
||||
res.end(error instanceof Error ? error.message : 'Internal server error');
|
||||
}
|
||||
});
|
||||
|
||||
server.listen(port, host, () => {
|
||||
console.log(`gitnexus-web listening on http://${host}:${port}`);
|
||||
});
|
||||
|
|
@ -1,55 +0,0 @@
|
|||
# Docker
|
||||
|
||||
This folder contains the Docker assets for `gitnexus-web`.
|
||||
|
||||
## Files
|
||||
|
||||
- `Dockerfile` is the source for the published `gitnexus-web` image. It builds `gitnexus-shared` and `gitnexus-web` in a Node builder stage, then copies only the compiled static site into a tiny `nginx:alpine` runtime image.
|
||||
- `nginx.conf` serves the built assets and falls back to `index.html` so client-side routes keep working.
|
||||
- `compose.yaml` starts the published image with Docker Compose.
|
||||
- `.env.example` is an optional shell env file for the example commands below. It sets the image name, container name, and exposed port. It does not inject application config into the frontend bundle.
|
||||
|
||||
## Optional env file
|
||||
|
||||
Create a local env file if you want reusable image/container names and host port settings:
|
||||
|
||||
```bash
|
||||
cp docker/.env.example docker/.env
|
||||
set -a
|
||||
source docker/.env
|
||||
set +a
|
||||
```
|
||||
|
||||
`docker/.env` is ignored by git via the repository-wide `.env` rules.
|
||||
|
||||
## Run with Docker
|
||||
|
||||
```bash
|
||||
docker run --rm \
|
||||
--name "${CONTAINER_NAME:-gitnexus-web}" \
|
||||
-p "${HOST_PORT:-8080}:80" \
|
||||
"${IMAGE_NAME:-ghcr.io/abhigyanpatwari/gitnexus-web:latest}"
|
||||
```
|
||||
|
||||
Then open `http://localhost:${HOST_PORT:-8080}`.
|
||||
|
||||
## Run with Docker Compose
|
||||
|
||||
```bash
|
||||
docker compose --env-file docker/.env -f docker/compose.yaml up -d
|
||||
```
|
||||
|
||||
If you do not want an env file, the defaults in `compose.yaml` are already set to:
|
||||
|
||||
```text
|
||||
image: ghcr.io/abhigyanpatwari/gitnexus-web:latest
|
||||
container_name: gitnexus-web
|
||||
port: 8080 -> 80
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The published image serves the production frontend only. It does not start `gitnexus serve`.
|
||||
- In backend mode, the app still defaults to `http://localhost:4747` unless you change the server URL in the UI.
|
||||
- The Dockerfile is kept here so the published image definition is versioned with the app, even if most users only need `docker run` or `docker compose`.
|
||||
- For iterative frontend development, `cd gitnexus-web && npm run dev` is still the faster workflow.
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /assets/ {
|
||||
expires 1y;
|
||||
add_header Cache-Control "public, immutable";
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue