Update README and server configuration for VPS Tracker application
Docker / build (push) Failing after 2m55s
Docker / build (push) Failing after 2m55s
- Renamed project from "React + Vite" to "VPS Tracker" and updated the README to reflect the application's purpose and usage instructions. - Added detailed Docker setup instructions, including two methods for running the application: using Docker Compose and standalone Docker. - Implemented static file serving in the server configuration to serve the frontend from the 'dist' directory if it exists, enhancing the application's deployment capabilities.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
node_modules
|
||||
dist
|
||||
data
|
||||
.git
|
||||
.github
|
||||
.cursor
|
||||
*.md
|
||||
!README.md
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
coverage
|
||||
*.log
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
@@ -0,0 +1,45 @@
|
||||
name: Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Docker metadata
|
||||
id: meta
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: ghcr.io/${{ github.repository }}
|
||||
tags: |
|
||||
type=raw,value=latest,enable=${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
type=sha
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
FROM node:22-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
COPY index.html vite.config.js ./
|
||||
COPY public ./public
|
||||
COPY src ./src
|
||||
RUN npm run build
|
||||
|
||||
FROM node:22-alpine AS runtime
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci --omit=dev
|
||||
COPY server ./server
|
||||
COPY --from=builder /app/dist ./dist
|
||||
EXPOSE 3001
|
||||
CMD ["node", "server/index.js"]
|
||||
@@ -1,16 +1,101 @@
|
||||
# React + Vite
|
||||
# VPS Tracker
|
||||
|
||||
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
|
||||
Приложение для учёта виртуальных серверов (VPS), провайдеров, аккаунтов, платежей и балансов. Поддерживается синхронизация с BILLmanager 6 API.
|
||||
|
||||
Currently, two official plugins are available:
|
||||
Ниже — основной сценарий запуска **в Docker**. Разработка без контейнера описана кратко в конце. Подробности по коду и доменам — в [AGENTS.md](AGENTS.md).
|
||||
|
||||
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Babel](https://babeljs.io/) (or [oxc](https://oxc.rs) when used in [rolldown-vite](https://vite.dev/guide/rolldown)) for Fast Refresh
|
||||
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
|
||||
---
|
||||
|
||||
## React Compiler
|
||||
## Запуск в Docker
|
||||
|
||||
The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
|
||||
### Требования
|
||||
|
||||
## Expanding the ESLint configuration
|
||||
- [Docker](https://docs.docker.com/get-docker/) и [Docker Compose](https://docs.docker.com/compose/) v2 (`docker compose`).
|
||||
|
||||
If you are developing a production application, we recommend using TypeScript with type-aware lint rules enabled. Check out the [TS template](https://github.com/vitejs/vite/tree/main/packages/create-vite/template-react-ts) for information on how to integrate TypeScript and [`typescript-eslint`](https://typescript-eslint.io) in your project.
|
||||
### Важно: база данных
|
||||
|
||||
SQLite хранится в файле `data/vps-tracker.db` **внутри рабочей директории приложения** (`/app/data` в контейнере). Без **тома** (volume) при удалении или пересборке контейнера база пропадёт. Для постоянного хранения всегда монтируйте каталог на хосте в `/app/data`.
|
||||
|
||||
### Вариант 1: Docker Compose (рекомендуется)
|
||||
|
||||
В корне репозитория:
|
||||
|
||||
```powershell
|
||||
docker compose up --build
|
||||
```
|
||||
|
||||
Откройте в браузере: **http://localhost:3001** (и API на том же хосте, префикс `/api/...`).
|
||||
|
||||
Данные БД по умолчанию пишутся в `./data` на хосте (см. [docker-compose.yml](docker-compose.yml)). Каталог `data` можно создать заранее или он появится при первом запуске.
|
||||
|
||||
Остановка: `Ctrl+C` или в другом окне:
|
||||
|
||||
```powershell
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### Вариант 2: только Docker (без Compose)
|
||||
|
||||
Сборка образа:
|
||||
|
||||
```powershell
|
||||
docker build -t vps-tracker:local .
|
||||
```
|
||||
|
||||
Запуск с томом для БД (пример для PowerShell — подставьте свой путь):
|
||||
|
||||
```powershell
|
||||
New-Item -ItemType Directory -Force -Path .\data | Out-Null
|
||||
docker run --rm -p 3001:3001 -v "${PWD}\data:/app/data" vps-tracker:local
|
||||
```
|
||||
|
||||
Снова открывайте **http://localhost:3001**.
|
||||
|
||||
### Переменные окружения
|
||||
|
||||
| Переменная | Описание | По умолчанию |
|
||||
|------------|----------|--------------|
|
||||
| `PORT` | Порт HTTP внутри контейнера | `3001` |
|
||||
|
||||
При смене `PORT` пробросьте тот же порт наружу, например `-p 8080:8080` и `-e PORT=8080`.
|
||||
|
||||
### Образ из GitHub Container Registry (GHCR)
|
||||
|
||||
После push в ветку `main` workflow [.github/workflows/docker.yml](.github/workflows/docker.yml) собирает образ и публикует его в GHCR.
|
||||
|
||||
1. На GitHub: **Packages** → пакет образа для этого репозитория (при необходимости сделайте пакет **public**, чтобы не требовалась авторизация для `docker pull`).
|
||||
2. Имя образа: `ghcr.io/<владелец>/<репозиторий>:latest` (в GHCR имя образа задаётся в **нижнем** регистре).
|
||||
|
||||
Пример (замените `OWNER` и `REPO`):
|
||||
|
||||
```powershell
|
||||
docker pull ghcr.io/OWNER/REPO:latest
|
||||
New-Item -ItemType Directory -Force -Path .\data | Out-Null
|
||||
docker run --rm -p 3001:3001 -v "${PWD}\data:/app/data" ghcr.io/OWNER/REPO:latest
|
||||
```
|
||||
|
||||
Обновление: снова `docker pull ...:latest` и перезапуск контейнера.
|
||||
|
||||
### CI/CD (кратко)
|
||||
|
||||
- **Pull request** в `main`: в GitHub Actions выполняется только **сборка** образа (проверка, что Dockerfile валиден).
|
||||
- **Push** в `main`: сборка и **push** в GHCR с тегами `latest` и SHA коммита.
|
||||
|
||||
---
|
||||
|
||||
## Локальная разработка (без Docker)
|
||||
|
||||
```powershell
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Поднимаются Vite (фронт) и Express (API); API по умолчанию на порту **3001**, прокси настроен в [vite.config.js](vite.config.js).
|
||||
|
||||
Сборка фронта отдельно: `npm run build`. Для проверки production-сборки на одном порту: после `npm run build` запустите `npm run server` — сервер отдаст статику из `dist`, если каталог существует.
|
||||
|
||||
---
|
||||
|
||||
## Документация для разработчиков
|
||||
|
||||
- [AGENTS.md](AGENTS.md) — структура репозитория, сущности, где искать sync, тарифы, API.
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# VPS Tracker: приложение + SQLite в ./data (создайте каталог или он появится при первом запуске)
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- "3001:3001"
|
||||
environment:
|
||||
PORT: "3001"
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
@@ -1,6 +1,12 @@
|
||||
import express from 'express'
|
||||
import cors from 'cors'
|
||||
import { existsSync } from 'fs'
|
||||
import { dirname, join } from 'path'
|
||||
import { fileURLToPath } from 'url'
|
||||
import { initDb } from './db.js'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
const distPath = join(__dirname, '..', 'dist')
|
||||
import dataRouter from './routes/data.js'
|
||||
import migrateRouter from './routes/migrate.js'
|
||||
import vpsRouter from './routes/vps.js'
|
||||
@@ -34,6 +40,14 @@ app.use(express.json({ limit: '50mb' }))
|
||||
app.use('/api/projects', projectsRouter)
|
||||
app.use('/api/backup', backupRouter)
|
||||
|
||||
if (existsSync(distPath)) {
|
||||
app.use(express.static(distPath))
|
||||
app.get(/.*/, (req, res, next) => {
|
||||
if (req.path.startsWith('/api')) return next()
|
||||
res.sendFile(join(distPath, 'index.html'), (err) => (err ? next(err) : undefined))
|
||||
})
|
||||
}
|
||||
|
||||
const { startScheduler } = await import('./sync-scheduler.js')
|
||||
startScheduler()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user