Skip to content

Deploying F-Droid

Introduction

F-Droid is a free and open-source Android app repository focused on privacy and freedom. While most people know F-Droid as a Google Play alternative, the F-Droid project also provides server software that lets you host your own private app repository. This is incredibly powerful for organizations that need to distribute internal Android apps, independent developers who want full control over their app distribution, or anyone building a curated collection of Android applications.

The F-Droid repository server handles everything needed to run a complete Android app store: APK hosting, metadata management, automatic updates, cryptographic signing, and client-side repository discovery. Apps published to your F-Droid repository can be installed and automatically updated through the official F-Droid client app, providing a seamless experience similar to mainstream app stores but with complete transparency and control.

Why F-Droid?

F-Droid offers unique advantages for Android app distribution:

  • Complete Control: Own your app distribution infrastructure without third-party gatekeepers
  • Privacy-Focused: No tracking, no ads, no data collection—just apps
  • Reproducible Builds: Verify that published apps match their source code
  • Automatic Updates: Users get app updates automatically through the F-Droid client
  • Cryptographic Signing: Built-in repository signing ensures app integrity
  • Metadata Management: Rich app descriptions, screenshots, changelogs, and versioning
  • Multi-Language Support: Localized app metadata and descriptions
  • Build Server Integration: Automate app builds from source code
  • Anti-Features Tracking: Transparent labeling of tracking, ads, or non-free components
  • Open Source: AGPL-3.0 licensed with full access to server code
  • No Google Dependencies: Completely independent from Google services
  • Internal Distribution: Perfect for enterprise app deployment
  • Custom Categories: Organize apps however makes sense for your use case
  • Version Control: Maintain multiple app versions simultaneously
  • Low Bandwidth Mode: Optimized for slow connections
  • Archive Support: Access to historical app versions
  • Mirrors Support: Distribute repository load across multiple servers
  • Client Compatibility: Works with official F-Droid client and compatible alternatives

F-Droid server is ideal for organizations distributing internal Android apps, developer teams managing beta releases, open-source projects maintaining their own app channels, educational institutions, and privacy-focused communities building curated app collections.

Why Deploy on Klutch.sh?

Deploying F-Droid on Klutch.sh provides significant operational advantages:

  • Simplified Deployment: Deploy directly from GitHub with automatic Docker detection
  • Persistent Storage: Built-in volume support for APKs, metadata, and repository data
  • HTTPS by Default: Automatic SSL certificates for secure app distribution
  • Custom Domains: Use your own domain for professional app repository hosting
  • Environment Management: Secure configuration of signing keys and secrets
  • High Availability: Reliable infrastructure ensures your app store is always accessible
  • Scalable Storage: Grow your APK storage as your app collection expands
  • Fast CDN: Quick app downloads for users worldwide
  • Backup Support: Easy data backup and disaster recovery
  • Low Latency: Fast repository synchronization and app updates

Prerequisites

Before deploying F-Droid, ensure you have:

  • A Klutch.sh account
  • A GitHub account with a repository for your deployment configuration
  • Basic understanding of Android APK files and app signing
  • (Optional) Android development environment for building apps
  • (Optional) GPG keys for repository signing (can be generated during setup)

Preparing Your Repository

Create a new GitHub repository for your F-Droid deployment with the following structure:

fdroid-repo/
├── Dockerfile
├── .dockerignore
├── .gitignore
├── nginx.conf
├── entrypoint.sh
├── config.yml
├── README.md
└── .env.example

Dockerfile

Create a production-ready Dockerfile for F-Droid server:

FROM debian:bookworm-slim
# Install F-Droid server dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
python3 \
python3-pip \
python3-venv \
fdroidserver \
nginx \
git \
rsync \
wget \
curl \
gnupg \
openjdk-17-jdk-headless \
&& rm -rf /var/lib/apt/lists/*
# Create fdroid user and directories
RUN useradd -m -s /bin/bash fdroid && \
mkdir -p /home/fdroid/fdroid/repo \
/home/fdroid/fdroid/metadata \
/home/fdroid/fdroid/tmp \
/var/www/fdroid && \
chown -R fdroid:fdroid /home/fdroid /var/www/fdroid
# Set working directory
WORKDIR /home/fdroid/fdroid
# Copy configuration files
COPY --chown=fdroid:fdroid config.yml /home/fdroid/fdroid/
COPY nginx.conf /etc/nginx/sites-available/fdroid
COPY entrypoint.sh /usr/local/bin/
# Enable nginx site
RUN rm /etc/nginx/sites-enabled/default && \
ln -s /etc/nginx/sites-available/fdroid /etc/nginx/sites-enabled/fdroid && \
chmod +x /usr/local/bin/entrypoint.sh
# Create necessary directories with correct permissions
RUN mkdir -p /var/www/fdroid/repo \
/var/www/fdroid/archive \
/var/lib/nginx/tmp && \
chown -R fdroid:fdroid /var/www/fdroid && \
chown -R www-data:www-data /var/lib/nginx
# Switch to fdroid user for repository operations
USER fdroid
# Initialize repository structure
RUN fdroid init --repo-url https://example-app.klutch.sh/fdroid/repo
# Switch back to root for service startup
USER root
# Expose HTTP port
EXPOSE 8080
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/fdroid/repo/index.xml || exit 1
# Start services
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]

Nginx Configuration

Create nginx.conf for serving the F-Droid repository:

server {
listen 8080;
server_name _;
root /var/www/fdroid;
# Enable directory listing for repository browsing
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
# Increase client body size for APK uploads
client_max_body_size 500M;
# F-Droid repository location
location /fdroid/repo {
alias /var/www/fdroid/repo;
# Serve index files
index index.html index.xml;
# Enable CORS for F-Droid client
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, OPTIONS";
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
# Cache APK files
location ~* \.apk$ {
expires 7d;
add_header Cache-Control "public, immutable";
}
# Cache repository metadata
location ~* \.(xml|json|jar)$ {
expires 1h;
add_header Cache-Control "public, must-revalidate";
}
# Cache images
location ~* \.(png|jpg|jpeg|gif|svg)$ {
expires 7d;
add_header Cache-Control "public, immutable";
}
}
# Archive location for old versions
location /fdroid/archive {
alias /var/www/fdroid/archive;
autoindex on;
location ~* \.apk$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}
# Repository root redirect
location = /fdroid {
return 301 /fdroid/repo;
}
# Main site location
location / {
try_files $uri $uri/ =404;
# Add security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
}
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
# Logging
access_log /var/log/nginx/fdroid-access.log;
error_log /var/log/nginx/fdroid-error.log;
}

F-Droid Configuration

Create config.yml with F-Droid server configuration:

# Repository metadata
repo_name: "My F-Droid Repository"
repo_description: "Custom Android app repository"
repo_url: "https://example-app.klutch.sh/fdroid/repo"
repo_icon: "icon.png"
# Archive configuration for old versions
archive_name: "My F-Droid Archive"
archive_description: "Archive of older app versions"
archive_url: "https://example-app.klutch.sh/fdroid/archive"
archive_older: 3 # Number of versions to keep before archiving
# Repository paths
repo_dir: "/var/www/fdroid/repo"
archive_dir: "/var/www/fdroid/archive"
# Build and signing configuration
build_server_always: false
update_stats: true
# App metadata defaults
repo_maxage: 0
repo_pubkey: "" # Will be generated on first run
# Archive settings
archive_older: 3
# Cache settings
make_current_version_link: true
# Mirror settings
mirrors:
- url: "https://example-app.klutch.sh/fdroid/repo"
# Anti-features to track
antifeatures:
Ads: "App contains advertising"
Tracking: "App tracks user activity"
NonFreeNet: "App relies on non-free network services"
NonFreeDep: "App depends on non-free components"
NonFreeAdd: "App promotes non-free addons"
UpstreamNonFree: "Upstream source is not fully free"

Entrypoint Script

Create entrypoint.sh to initialize and start services:

#!/bin/bash
set -e
# Function to log messages
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}
log "Starting F-Droid repository server..."
# Initialize repository if not exists
if [ ! -f "/var/www/fdroid/repo/index.xml" ]; then
log "Initializing F-Droid repository..."
su - fdroid -c "cd /home/fdroid/fdroid && fdroid update --create-metadata"
fi
# Generate signing key if not exists
if [ ! -f "/home/fdroid/fdroid/keystore.p12" ]; then
log "Generating repository signing keystore..."
su - fdroid -c "cd /home/fdroid/fdroid && fdroid update --create-key"
fi
# Set repository URL from environment
if [ -n "$FDROID_REPO_URL" ]; then
log "Setting repository URL to: $FDROID_REPO_URL"
su - fdroid -c "cd /home/fdroid/fdroid && sed -i \"s|repo_url:.*|repo_url: '$FDROID_REPO_URL'|\" config.yml"
fi
# Update repository metadata
log "Updating repository metadata..."
su - fdroid -c "cd /home/fdroid/fdroid && fdroid update"
# Sync to nginx document root
log "Syncing repository to web root..."
rsync -av --delete /home/fdroid/fdroid/repo/ /var/www/fdroid/repo/
chown -R www-data:www-data /var/www/fdroid/repo/
# Start nginx
log "Starting nginx..."
nginx -g 'daemon off;'

Make the entrypoint script executable:

Terminal window
chmod +x entrypoint.sh

Additional Configuration Files

Create .dockerignore:

.git
.github
*.md
.env
.env.*
!.env.example
*.log
tmp/
.DS_Store

Create .gitignore:

# Environment files
.env
.env.local
# Repository data
repo/
archive/
metadata/
tmp/
# Signing keys (NEVER commit these!)
keystore.p12
keystore.jks
*.p12
*.jks
# Logs
*.log
logs/
# OS files
.DS_Store
Thumbs.db
# IDE
.vscode/
.idea/
*.swp
*.swo

Create .env.example:

Terminal window
# F-Droid Repository Configuration
FDROID_REPO_URL=https://example-app.klutch.sh/fdroid/repo
FDROID_REPO_NAME=My F-Droid Repository
FDROID_REPO_DESCRIPTION=Custom Android app repository
# Archive URL
FDROID_ARCHIVE_URL=https://example-app.klutch.sh/fdroid/archive
# Server Configuration
PORT=8080
# Optional: Signing key passwords (if using existing keys)
# FDROID_KEYSTORE_PASSWORD=your-secure-password
# FDROID_KEY_PASSWORD=your-secure-password
# Optional: Admin contact
# FDROID_ADMIN_EMAIL=admin@example.com
# Optional: Update check interval (seconds)
# FDROID_UPDATE_INTERVAL=3600

Create README.md:

# F-Droid Repository Server
Custom F-Droid repository for hosting and distributing Android apps.
## Features
- Self-hosted Android app repository
- Automatic repository metadata generation
- Support for multiple app versions
- Archive for older versions
- Cryptographic signing
- Compatible with F-Droid client
## Setup
1. Clone this repository
2. Copy `.env.example` to `.env` and configure
3. Add your APK files to the repository
4. Push to GitHub
5. Deploy on Klutch.sh
## Adding Apps
Place APK files in the repository directory and run:
```bash
fdroid update

Repository URL

Add this URL to your F-Droid client:

https://example-app.klutch.sh/fdroid/repo

Documentation

See the full deployment guide at docs.klutch.sh

## Deploying on Klutch.sh
<ol>
<li>
### Push Repository to GitHub
Initialize your Git repository and push to GitHub:
```bash
git init
git add .
git commit -m "Initial F-Droid repository setup"
git branch -M main
git remote add origin https://github.com/yourusername/fdroid-repo.git
git push -u origin main
  • Create New Project

    Log in to your Klutch.sh dashboard and create a new project for your F-Droid repository.

  • Create New App

    In your project, click Create App and configure:

    • Git Source: Select your GitHub repository
    • Branch: Choose main (or your default branch)
    • Traffic Type: Select HTTP
    • Internal Port: Set to 8080

    Klutch.sh will automatically detect the Dockerfile in your repository.

  • Configure Environment Variables

    Add the following environment variables in the Klutch.sh dashboard:

    Required Variables:

    Terminal window
    FDROID_REPO_URL=https://your-app-name.klutch.sh/fdroid/repo
    FDROID_REPO_NAME=My F-Droid Repository
    FDROID_REPO_DESCRIPTION=Custom Android app repository

    Optional Variables:

    Terminal window
    FDROID_ARCHIVE_URL=https://your-app-name.klutch.sh/fdroid/archive
    FDROID_ADMIN_EMAIL=admin@example.com

    Replace your-app-name with your actual Klutch.sh app name.

  • Attach Persistent Volumes

    F-Droid requires persistent storage for repository data:

    Repository Volume:

    • Mount Path: /var/www/fdroid/repo
    • Size: Start with 10GB (scale based on number/size of APKs)

    Archive Volume:

    • Mount Path: /var/www/fdroid/archive
    • Size: Start with 5GB

    Metadata Volume:

    • Mount Path: /home/fdroid/fdroid/metadata
    • Size: 1GB

    Keystore Volume (Important!):

    • Mount Path: /home/fdroid/fdroid
    • Size: 1GB

    This ensures your repository signing keys persist across deployments.

  • Deploy Application

    Click Deploy to build and launch your F-Droid repository. The initial deployment will:

    1. Install F-Droid server tools
    2. Initialize the repository structure
    3. Generate signing keys
    4. Start the nginx web server
    5. Make the repository accessible via HTTPS
  • Verify Deployment

    Once deployed, visit your repository URL to verify:

    https://your-app-name.klutch.sh/fdroid/repo

    You should see the F-Droid repository index. Test the health endpoint:

    Terminal window
    curl https://your-app-name.klutch.sh/fdroid/repo/index.xml
  • Managing Your Repository

    Adding Apps to Your Repository

    There are several ways to add Android apps to your F-Droid repository:

    Method 1: Direct APK Upload

    1. Build your Android app and generate a signed APK
    2. SSH into your container (or use volume management):
    Terminal window
    # Copy APK to repository
    cp your-app-1.0.apk /home/fdroid/fdroid/repo/
    # Update repository metadata
    cd /home/fdroid/fdroid
    fdroid update
    # Sync to web directory
    rsync -av --delete repo/ /var/www/fdroid/repo/
    1. Commit the updated repository to your volume

    Method 2: Metadata-Based Management

    Create app metadata files for better organization:

    Terminal window
    # Create metadata directory if not exists
    mkdir -p /home/fdroid/fdroid/metadata
    # Create metadata file for your app
    cat > /home/fdroid/fdroid/metadata/com.example.myapp.yml << EOF
    Categories:
    - System
    License: Apache-2.0
    WebSite: https://example.com
    SourceCode: https://github.com/yourusername/myapp
    IssueTracker: https://github.com/yourusername/myapp/issues
    AutoName: My App
    Summary: Short description of your app
    Description: |
    Detailed description of your app.
    Features:
    * Feature 1
    * Feature 2
    * Feature 3
    RepoType: git
    Repo: https://github.com/yourusername/myapp
    Builds:
    - versionName: '1.0'
    versionCode: 1
    commit: v1.0
    subdir: app
    gradle:
    - yes
    EOF
    # Update repository
    fdroid update

    Method 3: Automated Building from Source

    F-Droid can build apps directly from source:

    # In metadata/com.example.myapp.yml
    Builds:
    - versionName: '1.0'
    versionCode: 1
    commit: v1.0
    subdir: app
    gradle:
    - yes
    prebuild: echo "Running prebuild tasks"
    build: ./gradlew assembleRelease

    Then run:

    Terminal window
    fdroid build com.example.myapp
    fdroid update

    Updating Repository Metadata

    After adding or modifying apps, always update the repository:

    Terminal window
    # Update repository index
    fdroid update
    # Update and generate statistics
    fdroid update --stats
    # Update and create archive for old versions
    fdroid update --archive

    Repository Maintenance Commands

    Check repository status:

    Terminal window
    fdroid checkupdates

    Verify repository integrity:

    Terminal window
    fdroid verify

    Clean up old temporary files:

    Terminal window
    fdroid clean

    Generate repository statistics:

    Terminal window
    fdroid stats

    Configuring F-Droid Client

    Users can add your repository to their F-Droid client:

    Method 1: Manual Configuration

    1. Open F-Droid app on Android device

    2. Navigate to SettingsRepositories

    3. Tap the + icon to add repository

    4. Enter your repository URL:

      https://your-app-name.klutch.sh/fdroid/repo
    5. Give your repository a name (e.g., “My Private Repo”)

    6. Tap Add Repository

    7. Wait for repository sync to complete

    Method 2: QR Code Configuration

    Generate a QR code for easy repository addition:

    Terminal window
    # Install qrencode
    apt-get install qrencode
    # Generate QR code
    qrencode -o repo-qr.png 'fdroidrepo://your-app-name.klutch.sh/fdroid/repo?fingerprint=YOUR_FINGERPRINT'

    Users can scan this QR code from F-Droid app → Settings → Repositories → Scan QR Code

    Create a web page with an fdroidrepo link:

    <!DOCTYPE html>
    <html>
    <head>
    <title>Add My F-Droid Repository</title>
    </head>
    <body>
    <h1>Add Repository to F-Droid</h1>
    <p>Click the button below to add this repository to your F-Droid client:</p>
    <a href="fdroidrepo://your-app-name.klutch.sh/fdroid/repo">
    <button>Add Repository</button>
    </a>
    <p>Or add manually: https://your-app-name.klutch.sh/fdroid/repo</p>
    </body>
    </html>

    Repository Security

    Repository Signing

    F-Droid uses cryptographic signing to ensure repository integrity:

    View your repository fingerprint:

    Terminal window
    fdroid server init
    fdroid server update

    The fingerprint will be displayed and should be shared with users to verify repository authenticity.

    Backup signing keys:

    Terminal window
    # IMPORTANT: Backup these files securely!
    cp /home/fdroid/fdroid/keystore.p12 /backup/location/
    cp /home/fdroid/fdroid/config.yml /backup/location/

    Never commit signing keys to Git! Store them securely in your persistent volume.

    Access Control

    Implement basic authentication for private repositories:

    Add to nginx.conf:

    location /fdroid/repo {
    auth_basic "F-Droid Repository";
    auth_basic_user_file /etc/nginx/.htpasswd;
    # ... rest of configuration
    }

    Generate password file:

    Terminal window
    # Install apache2-utils
    apt-get install apache2-utils
    # Create user
    htpasswd -c /etc/nginx/.htpasswd username

    HTTPS Enforcement

    Klutch.sh provides HTTPS by default. Ensure your repository URL uses https://:

    # In config.yml
    repo_url: "https://your-app-name.klutch.sh/fdroid/repo"

    Production Best Practices

    Repository Management

    1. Version Control: Keep metadata in Git, APKs in persistent volumes
    2. Regular Updates: Update repository metadata after any changes
    3. Archive Old Versions: Configure automatic archiving of old app versions
    4. Metadata Quality: Provide comprehensive app descriptions and screenshots
    5. Category Organization: Use meaningful categories for app discovery

    Performance Optimization

    1. Enable Caching: Configure aggressive caching for APK files
    2. Use CDN: Consider CDN for global app distribution
    3. Optimize Images: Compress app icons and screenshots
    4. Incremental Updates: Use F-Droid’s delta update support
    5. Mirror Setup: Configure repository mirrors for redundancy

    Security Hardening

    1. Secure Signing Keys: Store signing keys in encrypted persistent volumes
    2. Regular Backups: Backup repository data and signing keys regularly
    3. Access Logs: Monitor nginx access logs for suspicious activity
    4. Update Dependencies: Keep F-Droid server tools updated
    5. Verify APKs: Check APK signatures before adding to repository

    Monitoring

    Monitor key metrics:

    Terminal window
    # Check repository size
    du -sh /var/www/fdroid/repo/
    # Monitor nginx access
    tail -f /var/log/nginx/fdroid-access.log
    # Check for errors
    tail -f /var/log/nginx/fdroid-error.log

    Backup Strategy

    Implement regular backups:

    backup-fdroid.sh
    #!/bin/bash
    BACKUP_DIR="/backup/fdroid-$(date +%Y%m%d)"
    mkdir -p "$BACKUP_DIR"
    # Backup repository data
    rsync -av /var/www/fdroid/repo/ "$BACKUP_DIR/repo/"
    rsync -av /var/www/fdroid/archive/ "$BACKUP_DIR/archive/"
    # Backup metadata
    rsync -av /home/fdroid/fdroid/metadata/ "$BACKUP_DIR/metadata/"
    # Backup configuration and keys
    cp /home/fdroid/fdroid/config.yml "$BACKUP_DIR/"
    cp /home/fdroid/fdroid/keystore.p12 "$BACKUP_DIR/"
    # Create tarball
    tar -czf "fdroid-backup-$(date +%Y%m%d).tar.gz" "$BACKUP_DIR"

    Troubleshooting

    Repository Not Accessible

    Issue: Cannot access repository URL

    Solutions:

    1. Verify deployment status in Klutch.sh dashboard

    2. Check nginx is running:

      Terminal window
      ps aux | grep nginx
    3. Verify port configuration (should be 8080)

    4. Check nginx error logs:

      Terminal window
      tail -f /var/log/nginx/fdroid-error.log

    APKs Not Appearing

    Issue: Added APKs don’t show in repository

    Solutions:

    1. Ensure APKs are in correct directory:

      Terminal window
      ls -la /home/fdroid/fdroid/repo/
    2. Update repository metadata:

      Terminal window
      fdroid update
    3. Sync to web directory:

      Terminal window
      rsync -av /home/fdroid/fdroid/repo/ /var/www/fdroid/repo/
    4. Check file permissions:

      Terminal window
      chown -R fdroid:fdroid /home/fdroid/fdroid/
      chown -R www-data:www-data /var/www/fdroid/

    Repository Signing Errors

    Issue: Signing key errors during repository update

    Solutions:

    1. Check if keystore exists:

      Terminal window
      ls -la /home/fdroid/fdroid/keystore.p12
    2. Regenerate keys if corrupted:

      Terminal window
      fdroid update --create-key
    3. Verify permissions:

      Terminal window
      chown fdroid:fdroid /home/fdroid/fdroid/keystore.p12

    Client Cannot Connect

    Issue: F-Droid client cannot connect to repository

    Solutions:

    1. Verify repository URL is correct and uses HTTPS

    2. Check repository index is accessible:

      Terminal window
      curl https://your-app-name.klutch.sh/fdroid/repo/index.xml
    3. Verify CORS headers are set in nginx

    4. Check client is using correct fingerprint

    5. Try disabling client-side cache and refresh

    Metadata Parsing Errors

    Issue: Errors when running fdroid update

    Solutions:

    1. Validate YAML syntax in metadata files:

      Terminal window
      python3 -c "import yaml; yaml.safe_load(open('metadata/com.example.app.yml'))"
    2. Check for required fields (Categories, License, etc.)

    3. Verify build instructions are correct

    4. Remove problematic metadata temporarily to isolate issue

    Advanced Configuration

    Custom Repository Branding

    Customize repository appearance:

    # In config.yml
    repo_name: "My Company Apps"
    repo_description: "Official app repository for My Company"
    repo_icon: "icon.png"
    # Custom colors and themes
    archive_name: "My Company Archive"
    repo_maxage: 0

    Add custom icon:

    Terminal window
    # Place 512x512 PNG image
    cp company-icon.png /var/www/fdroid/repo/icon.png

    Multi-Repository Setup

    Run multiple repositories:

    # In nginx.conf
    location /fdroid/production {
    alias /var/www/fdroid/production;
    }
    location /fdroid/beta {
    alias /var/www/fdroid/beta;
    }

    Automated Publishing

    Set up CI/CD for automated app publishing:

    .github/workflows/publish.yml
    name: Publish to F-Droid
    on:
    release:
    types: [created]
    jobs:
    publish:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Build APK
    run: ./gradlew assembleRelease
    - name: Deploy to F-Droid
    env:
    FDROID_SSH_KEY: ${{ secrets.FDROID_SSH_KEY }}
    run: |
    # Copy APK to repository
    scp app/build/outputs/apk/release/app-release.apk \
    fdroid-server:/home/fdroid/fdroid/repo/
    # Update repository
    ssh fdroid-server 'cd /home/fdroid/fdroid && fdroid update'

    Repository Statistics

    Generate usage statistics:

    Terminal window
    # Enable statistics in config.yml
    update_stats: true
    # Generate statistics
    fdroid stats
    # View statistics
    cat stats/stats.json

    Example Apps Structure

    Example metadata for a complete app:

    metadata/com.example.myapp.yml
    Categories:
    - System
    - Utilities
    License: GPL-3.0-or-later
    WebSite: https://example.com/myapp
    SourceCode: https://github.com/example/myapp
    IssueTracker: https://github.com/example/myapp/issues
    Translation: https://hosted.weblate.org/projects/myapp
    Changelog: https://github.com/example/myapp/blob/master/CHANGELOG.md
    Donate: https://example.com/donate
    AutoName: My Awesome App
    Summary: One-line description of app
    Description: |
    My Awesome App is a powerful utility for Android devices.
    Features:
    * Feature one with detailed explanation
    * Feature two with benefits
    * Feature three highlighting uniqueness
    Privacy:
    * No tracking or analytics
    * All data stored locally
    * No network permissions required
    Requirements:
    * Android 5.0 or higher
    * 10MB storage space
    RepoType: git
    Repo: https://github.com/example/myapp
    Builds:
    - versionName: '1.0.0'
    versionCode: 1
    commit: v1.0.0
    subdir: app
    gradle:
    - yes
    output: build/outputs/apk/release/app-release-unsigned.apk
    prebuild: echo "sdk.dir=$$SDK$$" > local.properties
    - versionName: '1.1.0'
    versionCode: 2
    commit: v1.1.0
    subdir: app
    gradle:
    - yes
    output: build/outputs/apk/release/app-release-unsigned.apk
    MaintainerNotes: |
    Built using standard Gradle process.
    APK is reproducible if built with same SDK version.
    AutoUpdateMode: Version v%v
    UpdateCheckMode: Tags
    CurrentVersion: '1.1.0'
    CurrentVersionCode: 2

    Client Usage Examples

    Adding Repository via App

    // Android code to programmatically add repository
    val intent = Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse("fdroidrepo://your-app-name.klutch.sh/fdroid/repo?fingerprint=YOUR_FINGERPRINT")
    }
    startActivity(intent)

    Fetching Repository Data

    Terminal window
    # Download repository index
    curl -O https://your-app-name.klutch.sh/fdroid/repo/index-v1.json
    # Parse repository data
    cat index-v1.json | jq '.apps[] | {packageName, name, summary}'

    Checking for Updates

    Terminal window
    # F-Droid client checks for updates by comparing versions
    # in repository index with installed apps
    # Manually check repository
    curl https://your-app-name.klutch.sh/fdroid/repo/index-v1.json | \
    jq '.packages."com.example.myapp"[0].versionCode'

    Additional Resources

    Conclusion

    You now have a fully functional F-Droid repository server running on Klutch.sh. Your private Android app store can distribute apps securely to your users with automatic updates, cryptographic signing, and complete control over the distribution process. F-Droid provides a privacy-respecting, open-source alternative to mainstream app stores while giving you full ownership of your app distribution infrastructure.

    For questions or issues, consult the F-Droid documentation or reach out to the community forum.