Docs Design updated

This commit is contained in:
Arunavo Ray
2025-06-16 00:01:45 +05:30
parent ee801f5d0e
commit 6e673249dc
8 changed files with 1257 additions and 573 deletions

View File

@@ -1,123 +0,0 @@
---
title: "Architecture"
description: "Comprehensive overview of the Gitea Mirror application architecture."
order: 1
updatedDate: 2025-05-22
---
<div class="mb-6">
<h1 class="text-2xl font-bold text-foreground">Gitea Mirror Architecture</h1>
<p class="text-muted-foreground mt-2">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
<div class="mb-4">
<p class="text-muted-foreground">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>
The application is built using:
- <span class="font-semibold text-foreground">Astro</span>: Web framework for the frontend
- <span class="font-semibold text-foreground">React</span>: Component library for interactive UI elements
- <span class="font-semibold text-foreground">Shadcn UI</span>: UI component library built on Tailwind CSS
- <span class="font-semibold text-foreground">SQLite</span>: Database for storing configuration, state, and events
- <span class="font-semibold text-foreground">Bun</span>: Runtime environment for the backend
- <span class="font-semibold text-foreground">Drizzle ORM</span>: Type-safe ORM for database interactions
## Architecture Diagram
```mermaid
graph TD
subgraph "Gitea Mirror"
Frontend["Frontend<br/>(Astro + React)"]
Backend["Backend<br/>(Bun)"]
Database["Database<br/>(SQLite + Drizzle)"]
Frontend <--> Backend
Backend <--> Database
end
subgraph "External APIs"
GitHub["GitHub API"]
Gitea["Gitea API"]
end
Backend --> GitHub
Backend --> Gitea
```
## Component Breakdown
### Frontend (Astro + React)
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.
Key frontend components:
- **Dashboard**: Overview of mirroring status and recent activity
- **Repository Management**: Interface for managing repositories to mirror
- **Organization Management**: Interface for managing GitHub organizations
- **Configuration**: Settings for GitHub and Gitea connections
- **Activity Log**: Detailed log of mirroring operations
### Backend (Bun)
The backend is built with Bun and provides API endpoints for the frontend to interact with. It handles:
- Authentication and user management
- GitHub API integration
- Gitea API integration
- Mirroring operations
- Database interactions
### Database (SQLite + Drizzle ORM)
SQLite with Bun's native SQLite driver is used for data persistence, with Drizzle ORM providing type-safe database interactions. The database stores:
- User accounts and authentication data
- GitHub and Gitea configuration
- Repository and organization information
- Mirroring job history and status
- Event notifications and their read status
## Data Flow
1. **User Authentication**: Users authenticate through the frontend, which communicates with the backend to validate credentials.
2. **Configuration**: Users configure GitHub and Gitea settings through the UI, which are stored in the SQLite database.
3. **Repository Discovery**: The backend queries the GitHub API to discover repositories based on user configuration.
4. **Mirroring Process**: When triggered, the backend fetches repository data from GitHub and pushes it to Gitea.
5. **Status Tracking**: All operations are logged in the database and displayed in the Activity Log.
## Project Structure
```
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
```
## Deployment Options
Gitea Mirror supports multiple deployment options:
1. **Docker**: Run as a containerized application using Docker and docker-compose
2. **LXC Containers**: Deploy in Linux Containers (LXC) on Proxmox VE (using community script by [Tobias/CrazyWolf13](https://github.com/CrazyWolf13)) or local workstations
3. **Native**: Run directly on the host system using Bun runtime
Each deployment method has its own advantages:
- **Docker**: Isolation, easy updates, consistent environment
- **LXC**: Lightweight virtualization, better performance than Docker, system-level isolation
- **Native**: Best performance, direct access to system resources

View File

@@ -1,177 +0,0 @@
---
title: "Configuration"
description: "Guide to configuring Gitea Mirror for your environment."
order: 2
updatedDate: 2025-05-22
---
<div class="mb-6">
<h1 class="text-2xl font-bold text-foreground">Gitea Mirror Configuration Guide</h1>
<p class="text-muted-foreground mt-2">This guide provides detailed information on how to configure Gitea Mirror for your environment.</p>
</div>
## Configuration Methods
Gitea Mirror can be configured using:
1. <span class="font-semibold text-foreground">Environment Variables</span>: Set configuration options through environment variables
2. <span class="font-semibold text-foreground">Web UI</span>: Configure the application through the web interface after installation
## Environment Variables
The following environment variables can be used to configure Gitea Mirror:
| Variable | Description | Default Value | Example |
|----------|-------------|---------------|---------|
| `NODE_ENV` | Runtime environment (development, production, test) | `development` | `production` |
| `DATABASE_URL` | SQLite database URL | `file:data/gitea-mirror.db` | `file:path/to/your/database.db` |
| `JWT_SECRET` | Secret key for JWT authentication | Auto-generated secure random string | `your-secure-random-string` |
| `HOST` | Server host | `localhost` | `0.0.0.0` |
| `PORT` | Server port | `4321` | `8080` |
### Important Security Note
The application will automatically generate a secure random `JWT_SECRET` on first run if one isn't provided or if the default value is used. This generated secret is stored in the data directory for persistence across container restarts.
While this auto-generation feature provides good security by default, you can still explicitly set your own `JWT_SECRET` for complete control over your deployment.
## Web UI Configuration
After installing and starting Gitea Mirror, you can configure it through the web interface:
1. Navigate to `http://your-server:port/`
2. If this is your first time, you'll be guided through creating an admin account
3. Log in with your credentials
4. Go to the Configuration page
### GitHub Configuration
The GitHub configuration section allows you to connect to GitHub and specify which repositories to mirror.
| Option | Description | Default |
|--------|-------------|---------|
| Username | Your GitHub username | - |
| Token | GitHub personal access token | - |
| Skip Forks | Skip forked repositories | `false` |
| Private Repositories | Include private repositories | `false` |
| Mirror Issues | Mirror issues from GitHub to Gitea | `false` |
| Mirror Wiki | Mirror wiki pages from GitHub to Gitea | `false` |
| Mirror Starred | Mirror starred repositories | `false` |
| Mirror Organizations | Mirror organization repositories | `false` |
| Only Mirror Orgs | Only mirror organization repositories | `false` |
| Preserve Org Structure | Maintain organization structure in Gitea | `false` |
| Skip Starred Issues | Skip mirroring issues for starred repositories | `false` |
#### GitHub Token Permissions
Your GitHub token needs the following permissions:
- `repo` - Full control of private repositories
- `read:org` - Read organization membership
- `read:user` - Read user profile data
To create a GitHub token:
1. Go to [GitHub Settings > Developer settings > Personal access tokens](https://github.com/settings/tokens)
2. Click "Generate new token"
3. Select the required permissions
4. Copy the generated token and paste it into Gitea Mirror
### Gitea Configuration
The Gitea configuration section allows you to connect to your Gitea instance and specify how repositories should be mirrored.
| Option | Description | Default |
|--------|-------------|---------|
| URL | Gitea server URL | - |
| Token | Gitea access token | - |
| Organization | Default organization for mirrored repositories | - |
| Visibility | Default visibility for mirrored repositories | `public` |
| Starred Repos Org | Organization for starred repositories | `github` |
#### Gitea Token Creation
To create a Gitea access token:
1. Log in to your Gitea instance
2. Go to Settings > Applications
3. Under "Generate New Token", enter a name for your token
4. Click "Generate Token"
5. Copy the generated token and paste it into Gitea Mirror
### Schedule Configuration
You can configure automatic mirroring on a schedule:
| Option | Description | Default |
|--------|-------------|---------|
| Enable Scheduling | Enable automatic mirroring | `false` |
| Interval (seconds) | Time between mirroring operations | `3600` (1 hour) |
## Advanced Configuration
### Repository Filtering
You can include or exclude specific repositories using patterns:
- Include patterns: Only repositories matching these patterns will be mirrored
- Exclude patterns: Repositories matching these patterns will be skipped
Example patterns:
- `*` - All repositories
- `org-name/*` - All repositories in a specific organization
- `username/repo-name` - A specific repository
### Database Management
Gitea Mirror includes several database management tools that can be run from the command line:
```bash
# Initialize the database (only if it doesn't exist)
bun run init-db
# Check database status
bun run check-db
# Fix database location issues
bun run fix-db
# Reset all users (for testing signup flow)
bun run reset-users
# Remove database files completely
bun run cleanup-db
```
### Event Management
Events in Gitea Mirror (such as repository mirroring operations) are stored in the SQLite database. You can manage these events using the following scripts:
```bash
# View all events in the database
bun scripts/check-events.ts
# Mark all events as read
bun scripts/mark-events-read.ts
```
For cleaning up old activities and events, use the cleanup button in the Activity Log page of the web interface.
### Health Check Endpoint
Gitea Mirror includes a built-in health check endpoint at `/api/health` that provides:
- System status and uptime
- Database connectivity check
- Memory usage statistics
- Environment information
You can use this endpoint for monitoring your deployment:
```bash
# Basic check (returns 200 OK if healthy)
curl -I http://your-server:port/api/health
# Detailed health information (JSON)
curl http://your-server:port/api/health
```

View File

@@ -1,182 +0,0 @@
---
title: "Quick Start Guide"
description: "Get started with Gitea Mirror quickly."
order: 3
updatedDate: 2025-05-22
---
<div class="mb-6">
<h1 class="text-2xl font-bold text-foreground">Gitea Mirror Quick Start Guide</h1>
<p class="text-muted-foreground mt-2">This guide will help you get Gitea Mirror up and running quickly.</p>
</div>
## Prerequisites
Before you begin, make sure you have:
1. <span class="font-semibold text-foreground">A GitHub account with a personal access token</span>
2. <span class="font-semibold text-foreground">A Gitea instance with an access token</span>
3. <span class="font-semibold text-foreground">One of the following:</span>
- Docker and docker-compose (for Docker deployment)
- Bun 1.2.9+ (for native deployment)
- Proxmox VE or LXD (for LXC container deployment)
## Installation Options
Choose the installation method that works best for your environment.
### Using Docker (Recommended for most users)
Docker provides the easiest way to get started with minimal configuration.
1. Clone the repository:
```bash
git clone https://github.com/arunavo4/gitea-mirror.git
cd gitea-mirror
```
2. Start the application in production mode:
```bash
docker compose up -d
```
3. Access the application at [http://localhost:4321](http://localhost:4321)
### Using Bun (Native Installation)
If you prefer to run the application directly on your system:
1. Clone the repository:
```bash
git clone https://github.com/arunavo4/gitea-mirror.git
cd gitea-mirror
```
2. Run the quick setup script:
```bash
bun run setup
```
This installs dependencies and initializes the database.
3. Choose how to run the application:
**Development Mode:**
```bash
bun run dev
```
Note: For Bun-specific features, use:
```bash
bunx --bun astro dev
```
**Production Mode:**
```bash
bun run build
bun run start
```
4. Access the application at [http://localhost:4321](http://localhost:4321)
### Using LXC Containers (Recommended for server deployments)
#### Proxmox VE (Online Installation)
For deploying on a Proxmox VE host with internet access:
```bash
# Optional env overrides: CTID HOSTNAME STORAGE DISK_SIZE CORES MEMORY BRIDGE IP_CONF
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-proxmox.sh)"
```
This script:
- Creates a privileged LXC container
- Installs Bun and dependencies
- Clones and builds the application
- Sets up a systemd service
#### Local LXD (Offline-friendly Installation)
For testing on a local workstation or in environments without internet access:
1. Clone the repository locally:
```bash
git clone https://github.com/arunavo4/gitea-mirror.git
```
2. Download the Bun installer once:
```bash
curl -L -o /tmp/bun-linux-x64.zip https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64.zip
```
3. Run the local LXC installer:
```bash
sudo LOCAL_REPO_DIR=~/path/to/gitea-mirror ./gitea-mirror/scripts/gitea-mirror-lxc-local.sh
```
For more details on LXC deployment, see the [LXC Container Deployment Guide](https://github.com/arunavo4/gitea-mirror/blob/main/scripts/README-lxc.md).
## Initial Configuration
Follow these steps to configure Gitea Mirror for first use:
1. **Create Admin Account**
- Upon first access, you'll be prompted to create an admin account
- Choose a secure username and password
- This will be your administrator account
2. **Configure GitHub Connection**
- Navigate to the Configuration page
- Enter your GitHub username
- Enter your GitHub personal access token
- Select which repositories to mirror (all, starred, organizations)
- Configure repository filtering options
3. **Configure Gitea Connection**
- Enter your Gitea server URL
- Enter your Gitea access token
- Configure organization and visibility settings
4. **Set Up Scheduling (Optional)**
- Enable automatic mirroring if desired
- Set the mirroring interval (in seconds)
5. **Save Configuration**
- Click the "Save" button to store your settings
## Performing Your First Mirror
After completing the configuration, you can start mirroring repositories:
1. Click "Import GitHub Data" to fetch repositories from GitHub
2. Go to the Repositories page to view your imported repositories
3. Select the repositories you want to mirror
4. Click "Mirror Selected" to start the mirroring process
5. Monitor the progress on the Activity page
6. You'll receive toast notifications about the success or failure of operations
## Troubleshooting
If you encounter any issues:
- Check the Activity Log for detailed error messages
- Verify your GitHub and Gitea tokens have the correct permissions
- Ensure your Gitea instance is accessible from the machine running Gitea Mirror
- Check logs based on your deployment method:
- Docker: `docker logs gitea-mirror`
- Native: Check the terminal output or system logs
- LXC: `systemctl status gitea-mirror` or `journalctl -u gitea-mirror -f`
- Use the health check endpoint to verify system status: `curl http://your-server:4321/api/health`
- For database issues, try the database management tools: `bun run check-db` or `bun run fix-db`
## Next Steps
After your initial setup:
- Explore the dashboard for an overview of your mirroring status
- Set up automatic mirroring schedules for hands-off operation
- Configure organization mirroring for team repositories
- Check out the [Configuration Guide](/configuration) for advanced settings
- Review the [Architecture Documentation](/architecture) to understand the system
- For server deployments, set up monitoring using the health check endpoint
- Use the cleanup button in the Activity Log page to manage old events and activities

View File

@@ -1,63 +0,0 @@
---
import { getCollection } from 'astro:content';
import MainLayout from '../../layouts/main.astro';
// Enable prerendering for this dynamic route
export const prerender = true;
// Generate static paths for all documentation pages
export async function getStaticPaths() {
const docs = await getCollection('docs');
return docs.map(entry => ({
params: { slug: entry.slug },
props: { entry },
}));
}
// Get the documentation entry from props
const { entry } = Astro.props;
const { Content } = await entry.render();
---
<MainLayout title={entry.data.title}>
<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 border border-border">
<div class="prose prose-neutral dark:prose-invert prose-code:bg-muted prose-code:text-foreground prose-pre:bg-muted prose-pre:text-foreground prose-pre:rounded-lg prose-pre:p-4 prose-table:rounded-lg prose-table:bg-muted prose-th:text-foreground prose-td:text-muted-foreground prose-blockquote:border-l-4 prose-blockquote:border-muted prose-blockquote:bg-muted/50 prose-blockquote:p-4">
<Content />
</div>
</article>
<script type="module">
// Mermaid diagram rendering for code blocks
import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.esm.min.mjs';
mermaid.initialize({ startOnLoad: false, theme: document.documentElement.classList.contains('dark') ? 'dark' : 'default' });
function renderMermaidDiagrams() {
document.querySelectorAll('pre code.language-mermaid').forEach((block, i) => {
const parent = block.parentElement;
if (!parent) return;
const code = block.textContent;
const id = `mermaid-diagram-${i}`;
const container = document.createElement('div');
container.className = 'my-6';
container.id = id;
parent.replaceWith(container);
mermaid.render(id, code, (svgCode) => {
container.innerHTML = svgCode;
});
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', renderMermaidDiagrams);
} else {
renderMermaidDiagrams();
}
</script>
</main>
</MainLayout>

View File

@@ -0,0 +1,330 @@
---
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>

View File

@@ -0,0 +1,423 @@
---
import MainLayout from '../../layouts/main.astro';
const envVars = [
{ name: 'NODE_ENV', desc: 'Runtime environment', default: 'development', example: 'production' },
{ name: 'DATABASE_URL', desc: 'SQLite database URL', default: 'file:data/gitea-mirror.db', example: 'file:path/to/database.db' },
{ name: 'JWT_SECRET', desc: 'Secret key for JWT auth', default: 'Auto-generated', example: 'your-secure-string' },
{ name: 'HOST', desc: 'Server host', default: 'localhost', example: '0.0.0.0' },
{ name: 'PORT', desc: 'Server port', default: '4321', example: '8080' }
];
const githubOptions = [
{ name: 'Username', desc: 'Your GitHub username', default: '-' },
{ name: 'Token', desc: 'GitHub personal access token', default: '-' },
{ name: 'Skip Forks', desc: 'Skip forked repositories', default: 'false' },
{ name: 'Private Repositories', desc: 'Include private repositories', default: 'false' },
{ name: 'Mirror Issues', desc: 'Mirror issues from GitHub to Gitea', default: 'false' },
{ name: 'Mirror Wiki', desc: 'Mirror wiki pages from GitHub to Gitea', default: 'false' },
{ name: 'Mirror Starred', desc: 'Mirror starred repositories', default: 'false' },
{ name: 'Mirror Organizations', desc: 'Mirror organization repositories', default: 'false' },
{ name: 'Only Mirror Orgs', desc: 'Only mirror organization repositories', default: 'false' },
{ name: 'Preserve Org Structure', desc: 'Maintain organization structure in Gitea', default: 'false' },
{ name: 'Skip Starred Issues', desc: 'Skip mirroring issues for starred repositories', default: 'false' }
];
const giteaOptions = [
{ name: 'URL', desc: 'Gitea server URL', default: '-' },
{ name: 'Token', desc: 'Gitea access token', default: '-' },
{ name: 'Organization', desc: 'Default organization for mirrored repositories', default: '-' },
{ name: 'Visibility', desc: 'Default visibility for mirrored repositories', default: 'public' },
{ name: 'Starred Repos Org', desc: 'Organization for starred repositories', default: 'github' }
];
---
<MainLayout title="Configuration - 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="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"/>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"/>
</svg>
<span>Configuration Guide</span>
</div>
<h1 class="text-4xl font-bold tracking-tight">Gitea Mirror Configuration</h1>
<p class="text-lg text-muted-foreground leading-relaxed max-w-4xl">
This guide provides detailed information on how to configure Gitea Mirror for your environment.
</p>
</div>
<!-- Configuration Methods -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Configuration Methods</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8">
<div class="bg-card rounded-lg border border-border p-6 hover:border-primary/50 transition-colors">
<div class="flex items-start gap-4">
<div class="text-2xl">🔧</div>
<div>
<h3 class="font-semibold text-lg mb-2">Environment Variables</h3>
<p class="text-sm text-muted-foreground">Set configuration options through environment variables for automated deployments</p>
</div>
</div>
</div>
<div class="bg-card rounded-lg border border-border p-6 hover:border-primary/50 transition-colors">
<div class="flex items-start gap-4">
<div class="text-2xl">🖥️</div>
<div>
<h3 class="font-semibold text-lg mb-2">Web UI</h3>
<p class="text-sm text-muted-foreground">Configure the application through the web interface after installation</p>
</div>
</div>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Environment Variables -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Environment Variables</h2>
<p class="text-muted-foreground mb-6">The following environment variables can be used to configure Gitea Mirror:</p>
<div class="overflow-x-auto">
<table class="w-full border-collapse">
<thead>
<tr class="border-b border-border">
<th class="text-left py-3 px-4 font-semibold">Variable</th>
<th class="text-left py-3 px-4 font-semibold">Description</th>
<th class="text-left py-3 px-4 font-semibold">Default</th>
<th class="text-left py-3 px-4 font-semibold">Example</th>
</tr>
</thead>
<tbody>
{envVars.map((v, i) => (
<tr class={`border-b border-border/50 hover:bg-muted/30 ${i === envVars.length - 1 ? 'border-b-0' : ''}`}>
<td class="py-3 px-4">
<code class="text-sm bg-muted px-1.5 py-0.5 rounded">{v.name}</code>
</td>
<td class="py-3 px-4 text-sm text-muted-foreground">{v.desc}</td>
<td class="py-3 px-4 text-sm"><code>{v.default}</code></td>
<td class="py-3 px-4 text-sm"><code>{v.example}</code></td>
</tr>
))}
</tbody>
</table>
</div>
<!-- Security Note -->
<div class="bg-amber-500/10 border border-amber-500/20 rounded-lg p-4 mt-6">
<div class="flex gap-3">
<div class="text-amber-600 dark:text-amber-500">
<svg class="w-5 h-5 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg>
</div>
<div>
<h4 class="font-semibold text-amber-600 dark:text-amber-500 mb-1">Security Note</h4>
<p class="text-sm">The application will automatically generate a secure random <code class="bg-amber-500/10 px-1 py-0.5 rounded">JWT_SECRET</code> on first run if one isn't provided. This generated secret is stored in the data directory for persistence across container restarts.</p>
<p class="text-sm mt-2">While this auto-generation feature provides good security by default, you can still explicitly set your own <code class="bg-amber-500/10 px-1 py-0.5 rounded">JWT_SECRET</code> for complete control over your deployment.</p>
</div>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Web UI Configuration -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Web UI Configuration</h2>
<p class="text-muted-foreground mb-6">After installing and starting Gitea Mirror, you can configure it through the web interface:</p>
<div class="bg-gradient-to-r from-primary/5 to-transparent rounded-lg p-6 border-l-4 border-primary mb-8">
<ol class="space-y-3">
{[
'Navigate to <code class="bg-muted px-1.5 py-0.5 rounded text-sm">http://your-server:port/</code>',
'If this is your first time, you\'ll be guided through creating an admin account',
'Log in with your credentials',
'Go to the Configuration page'
].map((step, i) => (
<li class="flex gap-3">
<span class="flex-shrink-0 w-6 h-6 bg-primary/10 rounded-full flex items-center justify-center text-sm font-semibold">{i + 1}</span>
<span set:html={step}></span>
</li>
))}
</ol>
</div>
<!-- GitHub Configuration -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">GitHub Configuration</h3>
<p class="text-muted-foreground mb-4">The GitHub configuration section allows you to connect to GitHub and specify which repositories to mirror.</p>
<div class="overflow-x-auto mb-6">
<table class="w-full border-collapse">
<thead>
<tr class="border-b border-border">
<th class="text-left py-3 px-4 font-semibold">Option</th>
<th class="text-left py-3 px-4 font-semibold">Description</th>
<th class="text-left py-3 px-4 font-semibold">Default</th>
</tr>
</thead>
<tbody>
{githubOptions.map((opt, i) => (
<tr class={`border-b border-border/50 hover:bg-muted/30 ${i === githubOptions.length - 1 ? 'border-b-0' : ''}`}>
<td class="py-3 px-4 font-medium">{opt.name}</td>
<td class="py-3 px-4 text-sm text-muted-foreground">{opt.desc}</td>
<td class="py-3 px-4 text-sm"><code>{opt.default}</code></td>
</tr>
))}
</tbody>
</table>
</div>
<!-- GitHub Token Permissions -->
<div class="bg-blue-500/10 border border-blue-500/20 rounded-lg p-4 mb-6">
<div class="flex gap-3">
<div class="text-blue-600 dark:text-blue-500">
<svg class="w-5 h-5 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<div>
<h4 class="font-semibold text-blue-600 dark:text-blue-500 mb-2">Required Permissions</h4>
<p class="text-sm mb-3">Your GitHub token needs the following permissions:</p>
<ul class="space-y-1 text-sm">
<li class="flex gap-2">
<span class="text-blue-600 dark:text-blue-500">•</span>
<span><code class="bg-blue-500/10 px-1 py-0.5 rounded">repo</code> - Full control of private repositories</span>
</li>
<li class="flex gap-2">
<span class="text-blue-600 dark:text-blue-500">•</span>
<span><code class="bg-blue-500/10 px-1 py-0.5 rounded">read:org</code> - Read organization membership</span>
</li>
<li class="flex gap-2">
<span class="text-blue-600 dark:text-blue-500">•</span>
<span><code class="bg-blue-500/10 px-1 py-0.5 rounded">read:user</code> - Read user profile data</span>
</li>
</ul>
</div>
</div>
</div>
<div class="pl-4 border-l-2 border-primary/20">
<h5 class="font-semibold mb-3">To create a GitHub token:</h5>
<ol class="space-y-2 text-sm">
<li>Go to <a href="https://github.com/settings/tokens" class="text-primary hover:underline">GitHub Settings > Developer settings > Personal access tokens</a></li>
<li>Click "Generate new token"</li>
<li>Select the required permissions</li>
<li>Copy the generated token and paste it into Gitea Mirror</li>
</ol>
</div>
</div>
<!-- Gitea Configuration -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">Gitea Configuration</h3>
<p class="text-muted-foreground mb-4">The Gitea configuration section allows you to connect to your Gitea instance and specify how repositories should be mirrored.</p>
<div class="overflow-x-auto mb-6">
<table class="w-full border-collapse">
<thead>
<tr class="border-b border-border">
<th class="text-left py-3 px-4 font-semibold">Option</th>
<th class="text-left py-3 px-4 font-semibold">Description</th>
<th class="text-left py-3 px-4 font-semibold">Default</th>
</tr>
</thead>
<tbody>
{giteaOptions.map((opt, i) => (
<tr class={`border-b border-border/50 hover:bg-muted/30 ${i === giteaOptions.length - 1 ? 'border-b-0' : ''}`}>
<td class="py-3 px-4 font-medium">{opt.name}</td>
<td class="py-3 px-4 text-sm text-muted-foreground">{opt.desc}</td>
<td class="py-3 px-4 text-sm"><code>{opt.default}</code></td>
</tr>
))}
</tbody>
</table>
</div>
<div class="pl-4 border-l-2 border-primary/20">
<h5 class="font-semibold mb-3">To create a Gitea access token:</h5>
<ol class="space-y-2 text-sm">
<li>Log in to your Gitea instance</li>
<li>Go to Settings > Applications</li>
<li>Under "Generate New Token", enter a name for your token</li>
<li>Click "Generate Token"</li>
<li>Copy the generated token and paste it into Gitea Mirror</li>
</ol>
</div>
</div>
<!-- Schedule Configuration -->
<div>
<h3 class="text-xl font-semibold mb-4">Schedule Configuration</h3>
<p class="text-muted-foreground mb-4">You can configure automatic mirroring on a schedule:</p>
<div class="overflow-x-auto">
<table class="w-full border-collapse">
<thead>
<tr class="border-b border-border">
<th class="text-left py-3 px-4 font-semibold">Option</th>
<th class="text-left py-3 px-4 font-semibold">Description</th>
<th class="text-left py-3 px-4 font-semibold">Default</th>
</tr>
</thead>
<tbody>
<tr class="border-b border-border/50 hover:bg-muted/30">
<td class="py-3 px-4 font-medium">Enable Scheduling</td>
<td class="py-3 px-4 text-sm text-muted-foreground">Enable automatic mirroring</td>
<td class="py-3 px-4 text-sm"><code>false</code></td>
</tr>
<tr class="hover:bg-muted/30">
<td class="py-3 px-4 font-medium">Interval (seconds)</td>
<td class="py-3 px-4 text-sm text-muted-foreground">Time between mirroring operations</td>
<td class="py-3 px-4 text-sm"><code>3600</code> (1 hour)</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Advanced Configuration -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Advanced Configuration</h2>
<!-- Repository Filtering -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">Repository Filtering</h3>
<div class="bg-gradient-to-r from-primary/5 to-transparent rounded-lg p-6 border-l-4 border-primary">
<p class="mb-4">You can include or exclude specific repositories using patterns:</p>
<div class="space-y-4">
<div>
<h4 class="font-semibold mb-2">Include Patterns</h4>
<p class="text-sm text-muted-foreground">Only repositories matching these patterns will be mirrored</p>
</div>
<div>
<h4 class="font-semibold mb-2">Exclude Patterns</h4>
<p class="text-sm text-muted-foreground">Repositories matching these patterns will be skipped</p>
</div>
</div>
<div class="mt-6 bg-muted/30 rounded-lg p-4">
<h5 class="font-semibold mb-2">Example Patterns</h5>
<ul class="space-y-1 text-sm font-mono">
<li><code>*</code> - All repositories</li>
<li><code>org-name/*</code> - All repositories in a specific organization</li>
<li><code>username/repo-name</code> - A specific repository</li>
</ul>
</div>
</div>
</div>
<!-- Database Management -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">Database Management</h3>
<p class="text-muted-foreground mb-4">Gitea Mirror includes several database management tools that can be run from the command line:</p>
<div class="bg-muted/30 rounded-lg p-4">
<pre class="text-sm"><code>{`# Initialize the database (only if it doesn't exist)
bun run init-db
# Check database status
bun run check-db
# Fix database location issues
bun run fix-db
# Reset all users (for testing signup flow)
bun run reset-users
# Remove database files completely
bun run cleanup-db`}</code></pre>
</div>
</div>
<!-- Event Management -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4">Event Management</h3>
<p class="text-muted-foreground mb-4">Events in Gitea Mirror (such as repository mirroring operations) are stored in the SQLite database. You can manage these events using the following scripts:</p>
<div class="bg-muted/30 rounded-lg p-4 mb-4">
<pre class="text-sm"><code>{`# View all events in the database
bun scripts/check-events.ts
# Mark all events as read
bun scripts/mark-events-read.ts`}</code></pre>
</div>
<div class="bg-green-500/10 border border-green-500/20 rounded-lg p-4">
<div class="flex gap-3">
<div class="text-green-600 dark:text-green-500">
<svg class="w-5 h-5 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
</svg>
</div>
<div>
<p class="text-sm">For cleaning up old activities and events, use the cleanup button in the Activity Log page of the web interface.</p>
</div>
</div>
</div>
</div>
<!-- Health Check Endpoint -->
<div>
<h3 class="text-xl font-semibold mb-4">Health Check Endpoint</h3>
<div class="bg-card rounded-lg border border-border p-6">
<h4 class="font-semibold mb-3">System Health Monitoring</h4>
<p class="text-muted-foreground mb-4">Gitea Mirror includes a built-in health check endpoint at <code class="bg-muted px-1.5 py-0.5 rounded">/api/health</code> that provides:</p>
<ul class="space-y-2 mb-6">
<li class="flex gap-2">
<span class="text-primary">✓</span>
<span>System status and uptime</span>
</li>
<li class="flex gap-2">
<span class="text-primary">✓</span>
<span>Database connectivity check</span>
</li>
<li class="flex gap-2">
<span class="text-primary">✓</span>
<span>Memory usage statistics</span>
</li>
<li class="flex gap-2">
<span class="text-primary">✓</span>
<span>Environment information</span>
</li>
</ul>
<div class="bg-muted/30 rounded-lg p-4">
<pre class="text-sm"><code>{`# Basic check (returns 200 OK if healthy)
curl -I http://your-server:port/api/health
# Detailed health information (JSON)
curl http://your-server:port/api/health`}</code></pre>
</div>
</div>
</div>
</section>
</article>
</main>
</MainLayout>

View File

@@ -1,18 +1,37 @@
--- ---
import { getCollection } from 'astro:content';
import MainLayout from '../../layouts/main.astro'; import MainLayout from '../../layouts/main.astro';
import { LuSettings, LuRocket, LuBookOpen } from 'react-icons/lu'; import { LuSettings, LuRocket, LuBookOpen } from 'react-icons/lu';
// Helper to pick an icon based on doc.slug // Define our documentation pages directly
// We'll use inline conditional rendering instead of this function const docs = [
{
slug: 'architecture',
title: 'Architecture',
description: 'Comprehensive overview of the Gitea Mirror application architecture.',
order: 1,
icon: LuBookOpen,
href: '/docs/architecture'
},
{
slug: 'configuration',
title: 'Configuration',
description: 'Guide to configuring Gitea Mirror for your environment.',
order: 2,
icon: LuSettings,
href: '/docs/configuration'
},
{
slug: 'quickstart',
title: 'Quick Start Guide',
description: 'Get started with Gitea Mirror quickly.',
order: 3,
icon: LuRocket,
href: '/docs/quickstart'
}
];
// Get all documentation entries, sorted by order // Sort by order
const docs = await getCollection('docs'); const sortedDocs = docs.sort((a, b) => a.order - b.order);
const sortedDocs = docs.sort((a, b) => {
const orderA = a.data.order || 999;
const orderB = b.data.order || 999;
return orderA - orderB;
});
--- ---
<MainLayout title="Documentation"> <MainLayout title="Documentation">
@@ -21,24 +40,25 @@ const sortedDocs = docs.sort((a, b) => {
<p class="mb-10 text-lg text-muted-foreground text-center">Browse guides and technical docs for Gitea Mirror.</p> <p class="mb-10 text-lg text-muted-foreground text-center">Browse guides and technical docs for Gitea Mirror.</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> <div class="grid grid-cols-1 md:grid-cols-2 gap-8">
{sortedDocs.map(doc => ( {sortedDocs.map(doc => {
<a const Icon = doc.icon;
href={`/docs/${doc.slug}`}
class="group block p-7 border border-border rounded-2xl bg-card hover:bg-muted transition-colors shadow-lg focus:ring-2 focus:ring-ring outline-none" return (
tabindex="0" <a
> href={doc.href}
<div class="flex items-center gap-3 mb-2"> class="group block p-7 border border-border rounded-2xl bg-card hover:bg-muted transition-colors shadow-lg focus:ring-2 focus:ring-ring outline-none"
<div class="w-10 h-10 bg-muted rounded-full flex items-center justify-center text-muted-foreground"> tabindex="0"
{doc.slug === 'architecture' && <LuBookOpen className="w-5 h-5" />} >
{doc.slug === 'configuration' && <LuSettings className="w-5 h-5" />} <div class="flex items-center gap-3 mb-2">
{doc.slug === 'quickstart' && <LuRocket className="w-5 h-5" />} <div class="w-10 h-10 bg-muted rounded-full flex items-center justify-center text-muted-foreground">
{!['architecture', 'configuration', 'quickstart'].includes(doc.slug) && <LuBookOpen className="w-5 h-5" />} <Icon className="w-5 h-5" />
</div>
<h2 class="text-xl font-semibold group-hover:text-foreground transition">{doc.title}</h2>
</div> </div>
<h2 class="text-xl font-semibold group-hover:text-foreground transition">{doc.data.title}</h2> <p class="text-muted-foreground">{doc.description}</p>
</div> </a>
<p class="text-muted-foreground">{doc.data.description}</p> );
</a> })}
))}
</div> </div>
</main> </main>
</MainLayout> </MainLayout>

View File

@@ -0,0 +1,456 @@
---
import MainLayout from '../../layouts/main.astro';
---
<MainLayout title="Quick Start Guide - 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="M13 10V3L4 14h7v7l9-11h-7z"/>
</svg>
<span>Quick Start</span>
</div>
<h1 class="text-4xl font-bold tracking-tight">Gitea Mirror Quick Start Guide</h1>
<p class="text-lg text-muted-foreground leading-relaxed max-w-4xl">
This guide will help you get Gitea Mirror up and running quickly.
</p>
</div>
<!-- Prerequisites -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Prerequisites</h2>
<div class="bg-gradient-to-r from-primary/5 to-transparent rounded-lg p-6 border-l-4 border-primary mb-8">
<h3 class="font-semibold mb-4">Before you begin, make sure you have:</h3>
<div class="space-y-3">
<div class="flex items-start gap-3">
<div class="flex-shrink-0 w-6 h-6 bg-primary/10 rounded-full flex items-center justify-center text-sm font-semibold">1</div>
<div>
<span class="font-semibold text-foreground">A GitHub account with a personal access token</span>
<p class="text-sm text-muted-foreground mt-1">Create one at <a href="https://github.com/settings/tokens" class="text-primary hover:underline">GitHub Settings</a></p>
</div>
</div>
<div class="flex items-start gap-3">
<div class="flex-shrink-0 w-6 h-6 bg-primary/10 rounded-full flex items-center justify-center text-sm font-semibold">2</div>
<div>
<span class="font-semibold text-foreground">A Gitea instance with an access token</span>
<p class="text-sm text-muted-foreground mt-1">Available in your Gitea Settings > Applications</p>
</div>
</div>
<div class="flex items-start gap-3">
<div class="flex-shrink-0 w-6 h-6 bg-primary/10 rounded-full flex items-center justify-center text-sm font-semibold">3</div>
<div>
<span class="font-semibold text-foreground">One of the following:</span>
<ul class="mt-2 space-y-1 text-sm text-muted-foreground pl-4">
<li class="flex gap-2"><span>•</span> Docker and docker-compose (for Docker deployment)</li>
<li class="flex gap-2"><span>•</span> Bun 1.2.9+ (for native deployment)</li>
<li class="flex gap-2"><span>•</span> Proxmox VE or LXD (for LXC container deployment)</li>
</ul>
</div>
</div>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Installation Options -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Installation Options</h2>
<p class="text-muted-foreground mb-8">Choose the installation method that works best for your environment.</p>
<!-- Docker Installation -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4 flex items-center gap-2">
🐳 Using Docker <span class="text-sm text-muted-foreground font-normal">(Recommended for most users)</span>
</h3>
<div class="bg-card rounded-lg border border-border p-6">
<p class="text-muted-foreground mb-4">Docker provides the easiest way to get started with minimal configuration.</p>
<div class="space-y-4">
{[
{ step: 'Clone the repository', cmd: 'git clone https://github.com/arunavo4/gitea-mirror.git\ncd gitea-mirror' },
{ step: 'Start the application in production mode', cmd: 'docker compose up -d' },
{ step: 'Access the application', cmd: null, text: 'Open your browser and navigate to <a href="http://localhost:4321" class="text-primary hover:underline font-medium">http://localhost:4321</a>' }
].map((item, i) => (
<div>
<div class="flex items-center gap-2 mb-2">
<span class="text-sm font-semibold text-muted-foreground">STEP {i + 1}</span>
<span class="text-sm text-muted-foreground">{item.step}</span>
</div>
{item.cmd ? (
<div class="bg-muted/30 rounded-lg p-4">
<pre class="text-sm"><code>{item.cmd}</code></pre>
</div>
) : (
<p class="text-sm" set:html={item.text}></p>
)}
</div>
))}
</div>
</div>
</div>
<!-- Bun Installation -->
<div class="mb-8">
<h3 class="text-xl font-semibold mb-4 flex items-center gap-2">
🏃 Using Bun <span class="text-sm text-muted-foreground font-normal">(Native Installation)</span>
</h3>
<div class="bg-card rounded-lg border border-border p-6">
<p class="text-muted-foreground mb-4">If you prefer to run the application directly on your system:</p>
<div class="space-y-4">
<div>
<div class="flex items-center gap-2 mb-2">
<span class="text-sm font-semibold text-muted-foreground">STEP 1</span>
<span class="text-sm text-muted-foreground">Clone the repository</span>
</div>
<div class="bg-muted/30 rounded-lg p-4">
<pre class="text-sm"><code>git clone https://github.com/arunavo4/gitea-mirror.git
cd gitea-mirror</code></pre>
</div>
</div>
<div>
<div class="flex items-center gap-2 mb-2">
<span class="text-sm font-semibold text-muted-foreground">STEP 2</span>
<span class="text-sm text-muted-foreground">Run the quick setup script</span>
</div>
<div class="bg-muted/30 rounded-lg p-4">
<pre class="text-sm"><code>bun run setup</code></pre>
</div>
<p class="text-sm text-muted-foreground mt-2">This installs dependencies and initializes the database.</p>
</div>
<div>
<div class="flex items-center gap-2 mb-2">
<span class="text-sm font-semibold text-muted-foreground">STEP 3</span>
<span class="text-sm text-muted-foreground">Choose how to run the application</span>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-3">
<div class="border border-border rounded-lg p-4">
<h5 class="font-semibold mb-2">Development Mode</h5>
<div class="bg-muted/30 rounded-lg p-3 text-sm">
<pre><code>bun run dev</code></pre>
</div>
<p class="text-xs text-muted-foreground mt-2">For Bun-specific features, use: <code class="bg-muted px-1 rounded">bunx --bun astro dev</code></p>
</div>
<div class="border border-border rounded-lg p-4">
<h5 class="font-semibold mb-2">Production Mode</h5>
<div class="bg-muted/30 rounded-lg p-3 text-sm">
<pre><code>bun run build
bun run start</code></pre>
</div>
</div>
</div>
</div>
<div>
<div class="flex items-center gap-2 mb-2">
<span class="text-sm font-semibold text-muted-foreground">STEP 4</span>
<span class="text-sm text-muted-foreground">Access the application</span>
</div>
<p class="text-sm">Open your browser and navigate to <a href="http://localhost:4321" class="text-primary hover:underline font-medium">http://localhost:4321</a></p>
</div>
</div>
</div>
</div>
<!-- LXC Installation -->
<div>
<h3 class="text-xl font-semibold mb-4 flex items-center gap-2">
📦 Using LXC Containers <span class="text-sm text-muted-foreground font-normal">(Recommended for server deployments)</span>
</h3>
<div class="bg-card rounded-lg border border-border p-6">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-4">
<h4 class="font-semibold flex items-center gap-2">
<span>Proxmox VE</span>
<span class="text-xs text-muted-foreground font-normal">(Online Installation)</span>
</h4>
<p class="text-sm text-muted-foreground">For deploying on a Proxmox VE host with internet access:</p>
<div class="bg-muted/30 rounded-lg p-4">
<pre class="text-sm"><code># Optional env overrides:
# CTID HOSTNAME STORAGE DISK_SIZE
# CORES MEMORY BRIDGE IP_CONF
sudo bash -c "$(curl -fsSL https://raw.githubusercontent.com/arunavo4/gitea-mirror/main/scripts/gitea-mirror-lxc-proxmox.sh)"</code></pre>
</div>
<div class="text-sm text-muted-foreground space-y-1">
<p class="font-medium">This script:</p>
<ul class="space-y-1 pl-4">
<li class="flex gap-2"><span>•</span> Creates a privileged LXC container</li>
<li class="flex gap-2"><span>•</span> Installs Bun and dependencies</li>
<li class="flex gap-2"><span>•</span> Clones and builds the application</li>
<li class="flex gap-2"><span>•</span> Sets up a systemd service</li>
</ul>
</div>
</div>
<div class="space-y-4">
<h4 class="font-semibold flex items-center gap-2">
<span>Local LXD</span>
<span class="text-xs text-muted-foreground font-normal">(Offline-friendly)</span>
</h4>
<p class="text-sm text-muted-foreground">For testing or environments without internet access:</p>
<ol class="space-y-3 text-sm">
<li>
<span class="text-muted-foreground">1. Clone the repository locally:</span>
<div class="bg-muted/30 rounded-lg p-3 mt-1">
<pre><code>git clone https://github.com/arunavo4/gitea-mirror.git</code></pre>
</div>
</li>
<li>
<span class="text-muted-foreground">2. Download Bun installer:</span>
<div class="bg-muted/30 rounded-lg p-3 mt-1">
<pre><code>curl -L -o /tmp/bun-linux-x64.zip \
https://github.com/oven-sh/bun/releases/latest/download/bun-linux-x64.zip</code></pre>
</div>
</li>
<li>
<span class="text-muted-foreground">3. Run local LXC installer:</span>
<div class="bg-muted/30 rounded-lg p-3 mt-1">
<pre><code>sudo LOCAL_REPO_DIR=~/path/to/gitea-mirror \
./gitea-mirror/scripts/gitea-mirror-lxc-local.sh</code></pre>
</div>
</li>
</ol>
</div>
</div>
<div class="mt-4 pt-4 border-t border-border">
<p class="text-sm text-muted-foreground">For more details, see the <a href="https://github.com/arunavo4/gitea-mirror/blob/main/scripts/README-lxc.md" class="text-primary hover:underline">LXC Container Deployment Guide</a>.</p>
</div>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Initial Configuration -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Initial Configuration</h2>
<p class="text-muted-foreground mb-6">Follow these steps to configure Gitea Mirror for first use:</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
{[
{
num: '1',
title: 'Create Admin Account',
items: [
"You'll be prompted on first access",
'Choose a secure username and password',
'This will be your administrator account'
]
},
{
num: '2',
title: 'Configure GitHub Connection',
items: [
'Navigate to the Configuration page',
'Enter your GitHub credentials',
'Select repositories to mirror',
'Configure filtering options'
]
},
{
num: '3',
title: 'Configure Gitea Connection',
items: [
'Enter your Gitea server URL',
'Enter your Gitea access token',
'Configure organization settings',
'Set default visibility'
]
},
{
num: '4',
title: 'Set Up Scheduling',
items: [
'Enable automatic mirroring',
'Set the mirroring interval',
'Save your configuration'
]
}
].map(step => (
<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="flex-shrink-0 w-8 h-8 bg-primary/10 rounded-full flex items-center justify-center text-sm font-semibold">{step.num}</div>
<div>
<h4 class="font-semibold mb-1">{step.title}</h4>
<ul class="text-sm text-muted-foreground space-y-1">
{step.items.map(item => (
<li>• {item}</li>
))}
</ul>
</div>
</div>
</div>
))}
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Performing Your First Mirror -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Performing Your First Mirror</h2>
<div class="bg-gradient-to-r from-primary/5 to-transparent rounded-lg p-6 border-l-4 border-primary">
<h3 class="font-semibold mb-4">After completing the configuration, you can start mirroring repositories:</h3>
<ol class="space-y-3">
{[
'Click <strong>"Import GitHub Data"</strong> to fetch repositories from GitHub',
'Go to the <strong>Repositories</strong> page to view your imported repositories',
'Select the repositories you want to mirror',
'Click <strong>"Mirror Selected"</strong> to start the mirroring process',
'Monitor the progress on the <strong>Activity</strong> page',
"You'll receive toast notifications about the success or failure of operations"
].map((step, i) => (
<li class="flex gap-3">
<span class="flex-shrink-0 w-6 h-6 bg-primary/10 rounded-full flex items-center justify-center text-sm font-semibold">{i + 1}</span>
<span set:html={step}></span>
</li>
))}
</ol>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Troubleshooting -->
<section class="mb-12">
<h2 class="text-2xl font-bold mb-6">Troubleshooting</h2>
<div class="bg-amber-500/10 border border-amber-500/20 rounded-lg p-4">
<div class="flex gap-3">
<div class="text-amber-600 dark:text-amber-500">
<svg class="w-5 h-5 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
</svg>
</div>
<div class="space-y-3">
<h4 class="font-semibold text-amber-600 dark:text-amber-500">If you encounter any issues:</h4>
<div class="space-y-2 text-sm">
<div class="flex gap-2">
<span class="text-amber-600 dark:text-amber-500">•</span>
<span>Check the <strong>Activity Log</strong> for detailed error messages</span>
</div>
<div class="flex gap-2">
<span class="text-amber-600 dark:text-amber-500">•</span>
<span>Verify your GitHub and Gitea tokens have the correct permissions</span>
</div>
<div class="flex gap-2">
<span class="text-amber-600 dark:text-amber-500">•</span>
<span>Ensure your Gitea instance is accessible from the machine running Gitea Mirror</span>
</div>
</div>
<div class="mt-4 space-y-3">
<h5 class="font-semibold">Check logs based on your deployment method:</h5>
<div class="bg-amber-500/5 rounded-lg p-3 space-y-2">
<div class="grid grid-cols-1 gap-2 text-sm">
<div>
<span class="font-medium">Docker:</span>
<code class="bg-amber-500/10 px-1.5 py-0.5 rounded ml-2">docker logs gitea-mirror</code>
</div>
<div>
<span class="font-medium">Native:</span>
<span class="text-muted-foreground ml-2">Check terminal output or system logs</span>
</div>
<div>
<span class="font-medium">LXC:</span>
<code class="bg-amber-500/10 px-1.5 py-0.5 rounded ml-2">systemctl status gitea-mirror</code>
<span class="text-muted-foreground ml-1">or</span>
<code class="bg-amber-500/10 px-1.5 py-0.5 rounded ml-1">journalctl -u gitea-mirror -f</code>
</div>
</div>
</div>
<div class="space-y-2 text-sm">
<div class="flex gap-2">
<span class="text-amber-600 dark:text-amber-500">•</span>
<span>Use the health check endpoint: <code class="bg-amber-500/10 px-1.5 py-0.5 rounded">curl http://your-server:4321/api/health</code></span>
</div>
<div class="flex gap-2">
<span class="text-amber-600 dark:text-amber-500">•</span>
<span>For database issues: <code class="bg-amber-500/10 px-1.5 py-0.5 rounded">bun run check-db</code> or <code class="bg-amber-500/10 px-1.5 py-0.5 rounded">bun run fix-db</code></span>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<div class="my-12 h-px bg-border/50"></div>
<!-- Next Steps -->
<section>
<h2 class="text-2xl font-bold mb-6">Next Steps</h2>
<div class="bg-gradient-to-br from-primary/5 via-transparent to-primary/5 rounded-lg p-6 border border-border">
<h3 class="font-semibold mb-4">After your initial setup:</h3>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="space-y-3">
{[
'Explore the dashboard for an overview of your mirroring status',
'Set up automatic mirroring schedules for hands-off operation',
'Configure organization mirroring for team repositories',
'Use the cleanup button in Activity Log to manage old events'
].map(item => (
<div class="flex gap-3">
<span class="text-primary">✓</span>
<span>{item}</span>
</div>
))}
</div>
<div class="space-y-3">
<div class="flex gap-3">
<span class="text-primary">📖</span>
<span>Check out the <a href="/docs/configuration" class="text-primary hover:underline font-medium">Configuration Guide</a> for advanced settings</span>
</div>
<div class="flex gap-3">
<span class="text-primary">🏗️</span>
<span>Review the <a href="/docs/architecture" class="text-primary hover:underline font-medium">Architecture Documentation</a> to understand the system</span>
</div>
<div class="flex gap-3">
<span class="text-primary">📊</span>
<span>For server deployments, set up monitoring using the health check endpoint</span>
</div>
</div>
</div>
</div>
</section>
</article>
</main>
</MainLayout>