Files
gitea-mirror/src/pages/docs/architecture.astro
2025-06-16 00:01:45 +05:30

330 lines
16 KiB
Plaintext

---
import MainLayout from '../../layouts/main.astro';
---
<MainLayout title="Architecture - Gitea Mirror">
<main class="max-w-5xl mx-auto px-4 py-12">
<div class="sticky top-4 z-10 mb-6">
<a
href="/docs/"
class="inline-flex items-center gap-2 px-3 py-1.5 rounded-md bg-card text-foreground hover:bg-muted transition-colors border border-border focus:ring-2 focus:ring-ring outline-none"
>
<span aria-hidden="true">&larr;</span> Back to Documentation
</a>
</div>
<article class="bg-card rounded-2xl shadow-lg p-6 md:p-8 border border-border">
<!-- Header -->
<div class="mb-12 space-y-4">
<div class="flex items-center gap-2 text-sm text-muted-foreground mb-2">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-1 4h1m-1 4h1"/>
</svg>
<span>Architecture Overview</span>
</div>
<h1 class="text-4xl font-bold tracking-tight">Gitea Mirror Architecture</h1>
<p class="text-lg text-muted-foreground leading-relaxed max-w-4xl">
This document provides a comprehensive overview of the Gitea Mirror application architecture, including component diagrams, project structure, and detailed explanations of each part of the system.
</p>
</div>
<!-- System Overview -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">System Overview</h2>
<div class="bg-card/50 border border-border/50 rounded-lg p-6 mb-8">
<p class="text-base leading-relaxed mb-6">
Gitea Mirror is a web application that automates the mirroring of GitHub repositories to Gitea instances. It provides a user-friendly interface for configuring, monitoring, and managing mirroring operations without requiring users to edit configuration files or run Docker commands.
</p>
<div class="space-y-1">
<h3 class="text-sm font-semibold text-muted-foreground uppercase tracking-wider mb-3">Technology Stack</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-3">
{[
{ name: 'Astro', desc: 'Web framework for the frontend' },
{ name: 'React', desc: 'Component library for interactive UI elements' },
{ name: 'Shadcn UI', desc: 'UI component library built on Tailwind CSS' },
{ name: 'SQLite', desc: 'Database for storing configuration, state, and events' },
{ name: 'Bun', desc: 'Runtime environment for the backend' },
{ name: 'Drizzle ORM', desc: 'Type-safe ORM for database interactions' }
].map(tech => (
<div class="flex items-start gap-3">
<div class="w-2 h-2 rounded-full bg-primary mt-2"></div>
<div>
<span class="font-semibold text-foreground">{tech.name}</span>
<p class="text-sm text-muted-foreground">{tech.desc}</p>
</div>
</div>
))}
</div>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Architecture Diagram -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Architecture Diagram</h2>
<div class="my-8">
<div class="architecture-diagram bg-muted/30 rounded-xl p-8 border border-border">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Gitea Mirror System -->
<div class="bg-card rounded-lg border-2 border-primary/20 p-6">
<h3 class="text-lg font-semibold mb-6 text-center text-primary">Gitea Mirror System</h3>
<div class="space-y-4">
{[
{ icon: '🎨', name: 'Frontend', tech: 'Astro + React' },
{ icon: '⚙️', name: 'Backend', tech: 'Bun Runtime' },
{ icon: '🗄️', name: 'Database', tech: 'SQLite + Drizzle' }
].map((component, index) => (
<>
<div class="bg-primary/10 rounded-lg p-4 text-center">
<div class="text-2xl mb-2">{component.icon}</div>
<h4 class="font-semibold">{component.name}</h4>
<p class="text-sm text-muted-foreground mt-1">{component.tech}</p>
</div>
{index < 2 && (
<div class="flex justify-center">
<div class="text-muted-foreground">
<svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16V4m0 0L3 8m4-4l4 4m6 0v12m0 0l4-4m-4 4l-4-4"/>
</svg>
</div>
</div>
)}
</>
))}
</div>
</div>
<!-- External APIs -->
<div class="space-y-4">
<div class="bg-card rounded-lg border-2 border-amber-500/20 p-6">
<h3 class="text-lg font-semibold mb-6 text-center text-amber-600 dark:text-amber-500">External APIs</h3>
<div class="space-y-4">
<div class="bg-amber-500/10 rounded-lg p-4 text-center">
<div class="text-2xl mb-2">🐙</div>
<h4 class="font-semibold">GitHub API</h4>
<p class="text-sm text-muted-foreground mt-1">Repository Data Source</p>
</div>
<div class="bg-amber-500/10 rounded-lg p-4 text-center">
<div class="text-2xl mb-2">🍵</div>
<h4 class="font-semibold">Gitea API</h4>
<p class="text-sm text-muted-foreground mt-1">Mirror Destination</p>
</div>
</div>
</div>
<div class="flex items-center justify-center gap-4 mt-6">
<div class="text-center">
<div class="text-sm text-muted-foreground mb-2">Data Flow</div>
<div class="flex items-center gap-2">
<span class="text-primary font-semibold">Backend</span>
<svg class="w-6 h-6 text-muted-foreground" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 8l4 4m0 0l-4 4m4-4H3"/>
</svg>
<span class="text-amber-600 dark:text-amber-500 font-semibold">APIs</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Component Breakdown -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Component Breakdown</h2>
<!-- Frontend -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">Frontend (Astro + React)</h3>
<div class="pl-4 border-l-2 border-primary/20">
<p class="text-muted-foreground mb-4">
The frontend is built with Astro, a modern web framework that allows for server-side rendering and partial hydration. React components are used for interactive elements, providing a responsive and dynamic user interface.
</p>
<h4 class="font-semibold mb-3">Key Frontend Components</h4>
<div class="space-y-3">
{[
{ name: 'Dashboard', desc: 'Overview of mirroring status and recent activity' },
{ name: 'Repository Management', desc: 'Interface for managing repositories to mirror' },
{ name: 'Organization Management', desc: 'Interface for managing GitHub organizations' },
{ name: 'Configuration', desc: 'Settings for GitHub and Gitea connections' },
{ name: 'Activity Log', desc: 'Detailed log of mirroring operations' }
].map(component => (
<div class="flex gap-3">
<span class="text-primary font-mono text-sm">▸</span>
<div>
<strong>{component.name}</strong>
<p class="text-sm text-muted-foreground mt-1">{component.desc}</p>
</div>
</div>
))}
</div>
</div>
</div>
<!-- Backend -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">Backend (Bun)</h3>
<div class="pl-4 border-l-2 border-primary/20">
<p class="text-muted-foreground mb-4">
The backend is built with Bun and provides API endpoints for the frontend to interact with. It handles:
</p>
<div class="space-y-3">
{[
'Authentication and user management',
'GitHub API integration',
'Gitea API integration',
'Mirroring operations',
'Database interactions'
].map(item => (
<div class="flex gap-3">
<span class="text-primary font-mono text-sm">▸</span>
<span>{item}</span>
</div>
))}
</div>
</div>
</div>
<!-- Database -->
<div>
<h3 class="text-xl font-semibold mb-4">Database (SQLite + Drizzle ORM)</h3>
<div class="pl-4 border-l-2 border-primary/20">
<p class="text-muted-foreground mb-4">
SQLite with Bun's native SQLite driver is used for data persistence, with Drizzle ORM providing type-safe database interactions. The database stores:
</p>
<div class="space-y-3">
{[
'User accounts and authentication data',
'GitHub and Gitea configuration',
'Repository and organization information',
'Mirroring job history and status',
'Event notifications and their read status'
].map(item => (
<div class="flex gap-3">
<span class="text-primary font-mono text-sm">▸</span>
<span>{item}</span>
</div>
))}
</div>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Data Flow -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Data Flow</h2>
<div class="bg-gradient-to-r from-primary/5 to-transparent rounded-lg p-6 border-l-4 border-primary">
<ol class="space-y-4">
{[
{ title: 'User Authentication', desc: 'Users authenticate through the frontend, which communicates with the backend to validate credentials.' },
{ title: 'Configuration', desc: 'Users configure GitHub and Gitea settings through the UI, which are stored in the SQLite database.' },
{ title: 'Repository Discovery', desc: 'The backend queries the GitHub API to discover repositories based on user configuration.' },
{ title: 'Mirroring Process', desc: 'When triggered, the backend fetches repository data from GitHub and pushes it to Gitea.' },
{ title: 'Status Tracking', desc: 'All operations are logged in the database and displayed in the Activity Log.' }
].map((step, index) => (
<li class="flex gap-4">
<span class="flex-shrink-0 w-8 h-8 bg-primary/10 rounded-full flex items-center justify-center text-sm font-semibold">
{index + 1}
</span>
<div>
<strong class="text-foreground">{step.title}</strong>
<p class="text-sm text-muted-foreground mt-1">{step.desc}</p>
</div>
</li>
))}
</ol>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Project Structure -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Project Structure</h2>
<div class="bg-muted/30 rounded-lg p-4">
<pre class="text-sm"><code>{`gitea-mirror/
├── src/ # Source code
│ ├── components/ # React components
│ ├── content/ # Documentation and content
│ ├── layouts/ # Astro layout components
│ ├── lib/ # Utility functions and database
│ ├── pages/ # Astro pages and API routes
│ └── styles/ # CSS and Tailwind styles
├── public/ # Static assets
├── data/ # Database and persistent data
├── docker/ # Docker configuration
└── scripts/ # Utility scripts for deployment and maintenance
├── gitea-mirror-lxc-local.sh # Local LXC deployment script
└── manage-db.ts # Database management tool`}</code></pre>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Deployment Options -->
<section>
<h2 class="text-2xl font-bold mb-6">Deployment Options</h2>
<p class="text-muted-foreground mb-6">Gitea Mirror supports multiple deployment options:</p>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 mb-6">
{[
{ icon: '🐳', name: 'Docker', desc: 'Run as a containerized application using Docker and docker-compose' },
{ icon: '📦', name: 'LXC Containers', desc: 'Deploy in Linux Containers on Proxmox VE or local workstations' },
{ icon: '🏃', name: 'Native', desc: 'Run directly on the host system using Bun runtime' }
].map(option => (
<div class="bg-card rounded-lg border border-border p-4 hover:border-primary/50 transition-colors">
<div class="flex items-start gap-3">
<div class="text-2xl">{option.icon}</div>
<div>
<h4 class="font-semibold mb-1">{option.name}</h4>
<p class="text-sm text-muted-foreground">{option.desc}</p>
</div>
</div>
</div>
))}
</div>
<div class="bg-muted/30 rounded-lg p-4 mt-6">
<h4 class="font-semibold mb-3">Deployment Advantages</h4>
<div class="space-y-2">
<div class="flex gap-3">
<strong class="text-primary">Docker:</strong>
<span class="text-muted-foreground">Isolation, easy updates, consistent environment</span>
</div>
<div class="flex gap-3">
<strong class="text-primary">LXC:</strong>
<span class="text-muted-foreground">Lightweight virtualization, better performance than Docker, system-level isolation</span>
</div>
<div class="flex gap-3">
<strong class="text-primary">Native:</strong>
<span class="text-muted-foreground">Best performance, direct access to system resources</span>
</div>
</div>
</div>
<div class="mt-4 text-sm text-muted-foreground">
<p><strong>Note:</strong> LXC deployment includes a community script by <a href="https://github.com/CrazyWolf13" class="text-primary hover:underline">Tobias/CrazyWolf13</a></p>
</div>
</section>
</article>
</main>
</MainLayout>