8914f4dce9
- Created `TV_SHOWS_SQL_QUERY_PATTERNS.md` to document SQL query patterns for TV shows, including performance issues and missing indexes. - Added `README.md` for Linux package building, detailing steps for creating Debian and Red Hat packages. - Implemented build scripts for Debian and Red Hat, including service files and post-installation hooks. - Added necessary scripts for managing Jellyfin service lifecycle on both Debian and Red Hat systems. - Included package specifications and installation instructions for both distributions.
440 lines
10 KiB
Markdown
440 lines
10 KiB
Markdown
# Building a Debian Package
|
|
|
|
This document describes how to build a Debian (`.deb`) package from the Jellyfin project using the current publishing parameters.
|
|
|
|
## Overview
|
|
|
|
The Jellyfin project is configured to publish as a self-contained Linux application. These published files can be packaged into a Debian package for easy distribution and installation on Debian-based systems.
|
|
|
|
### Current Publishing Parameters
|
|
|
|
The project is configured with the following publishing settings (from [rebuild-solution.sh](rebuild-solution.sh)):
|
|
|
|
| Parameter | Value | Purpose |
|
|
|-----------|-------|---------|
|
|
| **Runtime** | `linux-x64` | Self-contained binary for 64-bit Linux |
|
|
| **Configuration** | `Release` | Optimized production build |
|
|
| **Self-contained** | `true` | Includes all .NET runtime dependencies |
|
|
| **Output Directory** | `/opt/jellyfin` | Standard Linux application directory |
|
|
|
|
## Prerequisites
|
|
|
|
Install the required tools on your system:
|
|
|
|
```bash
|
|
# Update package list
|
|
sudo apt-get update
|
|
|
|
# Install build tools
|
|
sudo apt-get install -y \
|
|
dotnet-sdk-11.0 \
|
|
ruby-dev \
|
|
build-essential
|
|
|
|
# Install FPM (Effing Package Manager) for easy package creation
|
|
sudo gem install fpm --no-document
|
|
```
|
|
|
|
## Method 1: Using FPM (Recommended)
|
|
|
|
FPM automates the package creation process and handles dependencies, scripts, and metadata.
|
|
|
|
### Step 1: Publish the Application
|
|
|
|
```bash
|
|
cd /home/wjones/projects/pgsql-jellyfin
|
|
|
|
# Restore dependencies
|
|
dotnet restore Jellyfin.sln -r linux-x64
|
|
|
|
# Build for Release
|
|
dotnet build Jellyfin.sln --configuration Release
|
|
|
|
# Publish as self-contained
|
|
dotnet publish Jellyfin.Server/Jellyfin.Server.csproj \
|
|
--configuration Release \
|
|
--self-contained true \
|
|
--runtime linux-x64 \
|
|
--output /tmp/jellyfin-build
|
|
```
|
|
|
|
**Expected output location**: `/tmp/jellyfin-build/`
|
|
|
|
### Step 2: Extract Version
|
|
|
|
Get the version from the SharedVersion.cs file:
|
|
|
|
```bash
|
|
# Extract version number
|
|
VERSION=$(grep -oP 'Version\s*=\s*"\K[^"]+' SharedVersion.cs)
|
|
echo "Building Jellyfin version: $VERSION"
|
|
```
|
|
|
|
### Step 3: Create the Debian Package
|
|
|
|
```bash
|
|
# Navigate to project root
|
|
cd /home/wjones/projects/pgsql-jellyfin
|
|
|
|
# Build the .deb package
|
|
fpm -s dir \
|
|
-t deb \
|
|
-n jellyfin \
|
|
-v "$VERSION" \
|
|
-C /tmp/jellyfin-build \
|
|
-p "jellyfin-${VERSION}_amd64.deb" \
|
|
--license "LICENSE" \
|
|
--vendor "Jellyfin Contributors" \
|
|
--maintainer "Your Name <your.email@example.com>" \
|
|
--description "Jellyfin Media Server - a free software media server" \
|
|
--url "https://jellyfin.org" \
|
|
--architecture x86_64 \
|
|
--depends "libssl3" \
|
|
--depends "libicu72" \
|
|
--depends "libfontconfig1" \
|
|
--depends "libc6 (>= 2.31)" \
|
|
opt/=opt/jellyfin \
|
|
etc/=etc/jellyfin
|
|
```
|
|
|
|
**Output**: `jellyfin-{VERSION}_amd64.deb`
|
|
|
|
### Step 4 (Optional): Add Service Files
|
|
|
|
To include systemd integration, create service files:
|
|
|
|
```bash
|
|
# Create directories for package contents
|
|
mkdir -p fpm-package/etc/jellyfin
|
|
mkdir -p fpm-package/usr/lib/systemd/system
|
|
mkdir -p fpm-package/opt/jellyfin
|
|
|
|
# Copy published files
|
|
cp -r /tmp/jellyfin-build/* fpm-package/opt/jellyfin/
|
|
|
|
# Create systemd service file
|
|
cat > fpm-package/usr/lib/systemd/system/jellyfin.service << 'EOF'
|
|
[Unit]
|
|
Description=Jellyfin Media Server
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=jellyfin
|
|
Group=jellyfin
|
|
WorkingDirectory=/opt/jellyfin
|
|
ExecStart=/opt/jellyfin/jellyfin
|
|
Restart=on-failure
|
|
RestartSec=10
|
|
StandardOutput=journal
|
|
StandardError=journal
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
EOF
|
|
|
|
# Update FPM command to include systemd service
|
|
fpm -s dir \
|
|
-t deb \
|
|
-n jellyfin \
|
|
-v "$VERSION" \
|
|
-C fpm-package \
|
|
-p "jellyfin-${VERSION}_amd64.deb" \
|
|
--after-install ./scripts/debian/postinst \
|
|
--before-remove ./scripts/debian/prerm \
|
|
--license "LICENSE" \
|
|
--description "Jellyfin Media Server" \
|
|
--url "https://jellyfin.org" \
|
|
--architecture x86_64 \
|
|
--depends "libssl3" \
|
|
--depends "libicu72" \
|
|
opt/ \
|
|
usr/
|
|
```
|
|
|
|
## Method 2: Using dpkg-deb (Manual)
|
|
|
|
For more control over the package structure, use `dpkg-deb` directly.
|
|
|
|
### Step 1-2: Same as Method 1
|
|
|
|
Publish the application (Steps 1-2 above).
|
|
|
|
### Step 3: Create Package Directory Structure
|
|
|
|
```bash
|
|
# Create control directory
|
|
mkdir -p jellyfin-pkg/DEBIAN
|
|
mkdir -p jellyfin-pkg/opt/jellyfin
|
|
mkdir -p jellyfin-pkg/etc/jellyfin
|
|
mkdir -p jellyfin-pkg/usr/lib/systemd/system
|
|
|
|
# Copy published application files
|
|
cp -r /tmp/jellyfin-build/* jellyfin-pkg/opt/jellyfin/
|
|
|
|
# Copy configuration template
|
|
cp jellyfin-setup.iss jellyfin-pkg/etc/jellyfin/jellyfin.conf.example
|
|
```
|
|
|
|
### Step 4: Create DEBIAN Control Files
|
|
|
|
Create `jellyfin-pkg/DEBIAN/control`:
|
|
|
|
```ini
|
|
Package: jellyfin
|
|
Version: 10.x.x
|
|
Architecture: amd64
|
|
Maintainer: Jellyfin Contributors <https://jellyfin.org>
|
|
Depends: libssl3, libicu72, libfontconfig1, libc6 (>= 2.31)
|
|
Homepage: https://jellyfin.org
|
|
Description: Jellyfin Media Server
|
|
Jellyfin is a free software media server application
|
|
that allows you to collect, manage, and share your
|
|
digital media (video, music, photos) anywhere.
|
|
```
|
|
|
|
Create `jellyfin-pkg/DEBIAN/postinst` (post-install script):
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
# Create jellyfin user if it doesn't exist
|
|
if ! getent passwd jellyfin > /dev/null; then
|
|
useradd --system --home /var/lib/jellyfin --shell /bin/false jellyfin
|
|
fi
|
|
|
|
# Create necessary directories
|
|
mkdir -p /var/lib/jellyfin /var/log/jellyfin /etc/jellyfin
|
|
chown -R jellyfin:jellyfin /var/lib/jellyfin /var/log/jellyfin /etc/jellyfin
|
|
|
|
# Reload systemd
|
|
systemctl daemon-reload
|
|
|
|
# Start the service
|
|
systemctl enable jellyfin.service
|
|
systemctl start jellyfin.service
|
|
|
|
exit 0
|
|
```
|
|
|
|
Create `jellyfin-pkg/DEBIAN/prerm` (pre-remove script):
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
# Stop the service
|
|
systemctl stop jellyfin.service || true
|
|
systemctl disable jellyfin.service || true
|
|
|
|
exit 0
|
|
```
|
|
|
|
Create `jellyfin-pkg/DEBIAN/postrm` (post-remove script):
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
# Clean up user and directories (optional)
|
|
# userdel jellyfin || true
|
|
# rm -rf /var/lib/jellyfin
|
|
|
|
exit 0
|
|
```
|
|
|
|
Make scripts executable:
|
|
|
|
```bash
|
|
chmod 0755 jellyfin-pkg/DEBIAN/postinst
|
|
chmod 0755 jellyfin-pkg/DEBIAN/prerm
|
|
chmod 0755 jellyfin-pkg/DEBIAN/postrm
|
|
```
|
|
|
|
### Step 5: Build the Package
|
|
|
|
```bash
|
|
# Get version
|
|
VERSION=$(grep -oP 'Version\s*=\s*"\K[^"]+' SharedVersion.cs)
|
|
|
|
# Create the .deb package
|
|
dpkg-deb --build jellyfin-pkg "jellyfin-${VERSION}_amd64.deb"
|
|
|
|
# Verify the package
|
|
dpkg-deb --info "jellyfin-${VERSION}_amd64.deb"
|
|
```
|
|
|
|
**Output**: `jellyfin-{VERSION}_amd64.deb`
|
|
|
|
## Installation
|
|
|
|
Once you have created the `.deb` package:
|
|
|
|
```bash
|
|
# Install the package
|
|
sudo dpkg -i jellyfin-10.x.x_amd64.deb
|
|
|
|
# If dependencies are missing, install them
|
|
sudo apt-get install -f
|
|
|
|
# Check service status
|
|
sudo systemctl status jellyfin
|
|
|
|
# View logs
|
|
sudo journalctl -u jellyfin -f
|
|
```
|
|
|
|
## Verification
|
|
|
|
### Check Package Contents
|
|
|
|
```bash
|
|
# List files in the package
|
|
dpkg-deb -c jellyfin-10.x.x_amd64.deb
|
|
|
|
# View package metadata
|
|
dpkg-deb -I jellyfin-10.x.x_amd64.deb
|
|
```
|
|
|
|
### Test Installation
|
|
|
|
```bash
|
|
# Create a test environment
|
|
mkdir -p /tmp/jellyfin-test
|
|
cd /tmp/jellyfin-test
|
|
|
|
# Extract package contents
|
|
dpkg -x /path/to/jellyfin-10.x.x_amd64.deb .
|
|
dpkg -e /path/to/jellyfin-10.x.x_amd64.deb DEBIAN
|
|
|
|
# Review extracted files
|
|
ls -la
|
|
cat DEBIAN/control
|
|
```
|
|
|
|
## Distribution
|
|
|
|
### Options for Distribution
|
|
|
|
1. **Local Repository**: Host `.deb` files on a private apt repository
|
|
2. **GitHub Releases**: Upload to GitHub releases for easy download
|
|
3. **Package Repository**: Submit to Ubuntu/Debian repositories
|
|
4. **Direct Download**: Provide `.deb` file download link
|
|
|
|
### Example: Create Local APT Repository
|
|
|
|
```bash
|
|
# Create repository directory
|
|
mkdir -p /var/www/jellyfin-repo/pool/main
|
|
|
|
# Copy package
|
|
cp jellyfin-10.x.x_amd64.deb /var/www/jellyfin-repo/pool/main/
|
|
|
|
# Generate package index (requires apt-utils)
|
|
cd /var/www/jellyfin-repo
|
|
dpkg-scanpackages pool/main /dev/null | gzip > Packages.gz
|
|
|
|
# Users can then add to their apt sources:
|
|
# echo "deb file:///var/www/jellyfin-repo /" | sudo tee /etc/apt/sources.list.d/jellyfin.list
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Issue**: `dpkg-deb: error: unable to open jellyfin-pkg/DEBIAN/control (No such file or directory)`
|
|
|
|
**Solution**: Ensure the DEBIAN directory exists and control file is properly created:
|
|
```bash
|
|
mkdir -p jellyfin-pkg/DEBIAN
|
|
# Recreate control file with proper permissions
|
|
```
|
|
|
|
**Issue**: Package installs but service won't start
|
|
|
|
**Solution**: Check if jellyfin user exists and has proper permissions:
|
|
```bash
|
|
sudo systemctl status jellyfin
|
|
sudo journalctl -u jellyfin -n 50
|
|
sudo ls -la /opt/jellyfin
|
|
sudo ls -la /var/lib/jellyfin
|
|
```
|
|
|
|
**Issue**: Missing dependencies warning
|
|
|
|
**Solution**: Ensure all required libraries are listed in the `Depends:` field:
|
|
```bash
|
|
ldd /opt/jellyfin/jellyfin | grep "not found"
|
|
```
|
|
|
|
## Automation Script
|
|
|
|
Create `scripts/linux/build-deb-package.sh`:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
set -e
|
|
|
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
PROJECT_ROOT="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
|
VERSION=$(grep -oP 'Version\s*=\s*"\K[^"]+' "$PROJECT_ROOT/SharedVersion.cs")
|
|
BUILD_DIR="/tmp/jellyfin-build-$$"
|
|
OUTPUT_DIR="$PROJECT_ROOT/dist"
|
|
|
|
echo "Building Jellyfin Debian package v$VERSION..."
|
|
|
|
# Create output directory
|
|
mkdir -p "$OUTPUT_DIR"
|
|
|
|
# Build and publish
|
|
cd "$PROJECT_ROOT"
|
|
dotnet restore Jellyfin.sln -r linux-x64
|
|
dotnet build Jellyfin.sln --configuration Release
|
|
dotnet publish Jellyfin.Server/Jellyfin.Server.csproj \
|
|
--configuration Release \
|
|
--self-contained true \
|
|
--runtime linux-x64 \
|
|
--output "$BUILD_DIR"
|
|
|
|
# Create package
|
|
fpm -s dir \
|
|
-t deb \
|
|
-n jellyfin \
|
|
-v "$VERSION" \
|
|
-C "$BUILD_DIR" \
|
|
-p "$OUTPUT_DIR/jellyfin-${VERSION}_amd64.deb" \
|
|
--license "LICENSE" \
|
|
--description "Jellyfin Media Server" \
|
|
--url "https://jellyfin.org" \
|
|
--architecture x86_64 \
|
|
--depends "libssl3" \
|
|
--depends "libicu72" \
|
|
opt/=opt/jellyfin
|
|
|
|
# Cleanup
|
|
rm -rf "$BUILD_DIR"
|
|
|
|
echo "Package created: $OUTPUT_DIR/jellyfin-${VERSION}_amd64.deb"
|
|
dpkg-deb -I "$OUTPUT_DIR/jellyfin-${VERSION}_amd64.deb"
|
|
```
|
|
|
|
Make it executable:
|
|
|
|
```bash
|
|
chmod +x scripts/linux/build-deb-package.sh
|
|
```
|
|
|
|
Run it:
|
|
|
|
```bash
|
|
./scripts/linux/build-deb-package.sh
|
|
```
|
|
|
|
## References
|
|
|
|
- [Debian New Maintainers' Guide](https://www.debian.org/doc/manuals/maint-guide/)
|
|
- [Packaging with fpm](https://github.com/jordansissel/fpm)
|
|
- [dpkg-deb Manual](https://manpages.debian.org/dpkg-deb)
|
|
- [systemd Unit Files](https://www.freedesktop.org/software/systemd/man/systemd.unit.html)
|