💡 Tam çalışan örnek GitHub’da mevcuttur:
python-linux-container-pdf-signing
Giriş
Betik yerel olarak çalışıyor. python:3.11-slim üzerinde konteynerleştiriyorsunuz ve import groupdocs.signature satırında başarısız oluyor. Bunu düzeltiyorsunuz, ancak ilk imzada tekrar hata alıyorsunuz. Hangi bileşenin eksik olduğunu belirten bir hata mesajı yok.
Python ile konteyner imzalama, iki ayrı sağlama katmanı gerektiren bir GroupDocs.Signature iş akışıdır: bağlamanın üzerine inşa edildiği .NET çalışma zamanı kütüphaneleri ve her metin imzasının render edilmesi için gereken yazı tipleri. Bu öğreticide her iki katman da oluşturuluyor, ardından bir yazı tipi ailesini çalışma zamanında çözen bir betik ekleniyor; böylece aynı kod hem konteynerde hem de yazdığınız makinede çalışıyor.
Neden Her İki Katman da Önemli
GroupDocs.Signature for Python bir .NET bağlamasıdır, bu yüzden libicu ve OpenSSL 1.1 uyumlu bir kütüphane, herhangi bir import işleminin başarılı olabilmesi için önceden mevcut olmalıdır. Bu birinci katmandır ve Running in Docker sayfasında iyi belgelenmiştir.
İki katmanın karıştırılmasının nedeni, her iki hatanın da import‑açık anlarda ortaya çıkması ve hiçbir hatanın nedenini belirtmemesidir. Eksik bir libssl1.1 size paylaşımlı nesneyle ilgili bir yükleyici hatası verir; eksik bir yazı tipi ise bir proxy istisnası içinde paketlenmiş bir imzalama hatası verir. Hiçbiri “temel imajınız çok küçük” demiyor; aslında ikisi de bunu ifade ediyor.
İkinci katman yazı tipleridir ve insanları en çok şaşırtandır. python:3.11-slim içinde hiç yazı tipi dosyası bulunmaz. GroupDocs.Signature eksik bir aileyi otomatik olarak ikame etmez – yüklü olmayan bir aileyi adlandırmak bir istisna fırlatır ve hiçbir şey yazılmaz – ve yazı tipini temizlemek de bir çözüm değildir, çünkü kütüphane kendi varsayılanını ister ve aynı şekilde başarısız olur. Yazı tipleri olmayan bir imajda metin imzası basitçe mümkün değildir.
Önkoşullar
Python 3.11 (tekerlekler CPython 3.14’ün altında) ve groupdocs-signature-net==26.1. Docker, iki hatayı da kasıtlı olarak görmek isterseniz, bu da yaklaşık on dakikalık bir süredir.
Kurulum
pip install groupdocs-signature-net==26.1
Adım 1 – .NET katmanını oluşturun
libssl1.1 bookworm deposunda bulunmadığından, sabitlenmiş bir Debian anlık görüntüsünden alınır:
ENV SNAPSHOT_DATE=20220328T000000Z
RUN echo "deb [trusted=yes] http://snapshot.debian.org/archive/debian/${SNAPSHOT_DATE} bullseye main" \
> /etc/apt/sources.list.d/debian-archive.list \
&& apt-get -o Acquire::Check-Valid-Until=false update \
&& apt-get install -y --no-install-recommends \
libicu67 \
libssl1.1 \
&& apt-get clean && rm -rf /var/lib/apt/lists/*
Temel noktalar:
- Bu katman yalnızca import işlemini çalışır hâle getirir; yazı tipleriyle ilgili hiçbir şey söylemez.
- Anlık görüntü tarihini sabitlemek, arşiv değiştiğinde derlemenin tekrarlanabilir kalmasını sağlar.
Adım 2 – Yazı tipi katmanını oluşturun
Dört paket, kendi katmanı olarak tutulur; böylece hatayı yeniden üretmek için yorum satırı haline getirilebilir:
RUN apt-get update && apt-get install -y --no-install-recommends \
fontconfig \
fonts-dejavu-core \
fonts-liberation \
fonts-noto-cjk \
&& fc-cache -f \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
fontconfig çözücüdür ve size fc-list komutunu sağlar. fonts-dejavu-core Latin, Yunan ve Kiril minimumunu içerir. fonts-liberation Arial veya Times New Roman gibi isimlerle referans verilen belgeleri kapsar. fonts-noto-cjk ise Çince, Japonca ve Koreceyi kapsar.
Adım 3 – Kütüphanenin hangi aileyi kullanabileceğini sorun
/usr/share/fonts içinde bir dosya adı aramak eşdeğer gibi görünebilir, ancak değildir: fonts-noto-cjk NotoSansCJK-Regular.ttc dosyasını kurar ve bu dosyanın aile adı Noto Sans CJK JP dir. Taşınabilir cevap, bir geçici dosyaya gerçek bir imza koyarak yapılan bir sondajdır; başarısızlık bir değer olarak döndürülür:
with signature.Signature(source_path) as sign:
options = TextSignOptions()
options.text = "probe"
options.left = 10
options.top = 10
options.width = 60
options.height = 20
font = SignatureFont()
font.family_name = family_name
font.size = 10.0
options.font = font
sign.sign(scratch, [options])
return None
font.size = 10.0 satırına dikkat edin. Bağlama, boyutu .NET floatına dönüştürür ve bir int değerini numeric argument expected, got 'int' hatasıyla reddeder. Bu sondaj içinde gerçekleştiği için, her aday aile başarısız olur ve çıktı tam anlamıyla yazı tipleri olmayan bir imaj gibi görünür. Ben de literalı fark etmeden önce zaten içinde bu üç paket bulunan bir imaja ek paketler eklemiştim.
Çözüm bir döngü ile yapılır:
for candidate in candidates:
if try_family(source_path, candidate) is None:
return candidate
return None
Adım 4 – Çözülen aileyle imzalayın, imzaladıklarınızı doğrulayın
Latin ailesi zorunludur, CJK ailesi isteğe bağlıdır:
with signature.Signature(source_path) as sign:
options = [build_text_options(LATIN_TEXT, latin_family, 50)]
if cjk_family:
options.append(build_text_options(CJK_TEXT, cjk_family, 120))
result = sign.sign(output_path, options)
return len(result.succeeded)
Ardından doğrulama yapılır; çünkü CJK boş kutular olarak render edildiğinde hiçbir istisna fırlatılmaz:
options = TextVerifyOptions()
options.text = expected_text
options.match_type = gsd.TextMatchType.CONTAINS
options.all_pages = True
result = sign.verify(options)
CONTAINS kasıtlıdır: değerlendirme modunda kütüphane sayfaya deneme metni ekler ve tam eşleşme, tamamen doğru bir belgeyi başarısız olarak raporlayabilir.
Python’un sınırlı Linux desteği olduğu söyleniyorsa ne?
Running in Docker sayfası Linux‑uyumlu Python paketlerini listeler ancak Signature’ı dışarıda bırakır. groupdocs-signature-net==26.1 ile bu örnek, python:3.11-slim içinde, CJK dahil, her iki katman da yüklü olduğunda imzalar ve doğrular. Listeyi bir engel olarak değil, güncel olmayan bir bilgi olarak değerlendirin ve dağıtıma geçmeden önce kendi sürümünüzle doğrulayın.
Gerçek Dünya Uygulamaları
Oluşturulan PDF’lere onay satırı ekleyen bir faturalama hizmeti tam olarak buna ihtiyaç duyar: .NET katmanı, bir Latin yazı tipi ve başlangıçta bir çözüm kontrolü. Bu kontrol, hatalı bir dağıtımı başlatılamayan bir konteyner haline getirir; tek tek sessizce başarısız olan fatura kuyruğu yerine. Müşteri adlarını herhangi bir alfabede kabul eden bir belge portalı ise CJK paketine ve doğrulama adımına da ihtiyaç duyar; çünkü bu adım, render edilen kutu ile imzalı isim arasındaki tek farkı ortadan kaldırır.
Çözüm Kontrolünün Nerede Bulunması Gerekiyor
İşlem başına bir kez çalışan bir yerde tutun: modül‑seviyesinde bir çağrı, FastAPI yaşam döngüsü işleyicisi, Django AppConfig.ready metodu veya bir işçi sürecinin ana satırları. Bu kontrol iki değer döndürür, Latin ailesi ve CJK ailesi, ve her ikisi de başlangıç logunda yazı tipi sayısının yanında yer almalıdır.
Bu yerleştirme sadece sondaj süresini kısaltmakla kalmaz; hatayı istek işleme aşamasından, bir müşterinin sorunu ve kimsenin okumadığı bir yığın izinden, başlatma aşamasına taşır; burada dağıtımın hiç başlamadığı ve birinin zaten izlediği bir durum olur. “Kullanılabilir bir yazı tipi ailesi yok, fonts-dejavu-core kurun” mesajı veren bir konteynerin hiç hata ayıklamaya ihtiyacı kalmaz.
Yaygın Sorunların Çözümü
import groupdocs.signature başarısız oluyor
.NET katmanı eksik ya da anlık görüntü deposu derleme sırasında erişilemez. Bu birinci katmandır ve yazı tipleriyle hiçbir ilgisi yoktur. İmza koduna dokunmadan önce apt adımının derleme günlüğünü kontrol edin; başarısız bir anlık görüntü çekimi imajın derlenmesini engellemez.
Tüm aday yazı tipleri başarısız, ama fc-list yazı tiplerini gösteriyor
font.size değerinin bir int olup olmadığını kontrol edin; daha fazla paket eklemeden önce bunu düzeltin.
İmza var ama CJK metni kutular halinde
fonts-noto-cjk eksik. İmza, o kod noktaları için glif içermeyen bir aileyle yazılmıştır; bu yüzden doğrulama adımı vardır: imzalama başarılı raporlansa bile, doğrulama bu durumu yakalar.
İki İmajın Gerçek Çıktısı
Her iki imajı da çalıştırın ve ilk dört satırı okuyun. Yazı tipleri olmayan imaj font files on disk: 0, her iki çözüm satırı (none), kasıtlı eksik‑yazı‑tipi hatasını ve ardından minimum düzeltme ile exit 3 verir. Sağlanan imaj ise sıfır olmayan bir yazı tipi sayısı, Latin için DejaVu Sans ve CJK için Noto Sans CJK JP, iki imza uygulanmış ve her iki metin de doğrulanmış olarak rapor verir.
Bu iki çıktıyı dağıtım notlarınıza yapıştırın; temel imajı değiştiren bir sonraki kişi, sağlıklı bir konteynerin nasıl göründüğüne dair bir referansa sahip olur, fontconfig’i anlamak zorunda kalmaz.
Sonuç
İki katman ve bir sondaj. .NET bağımlılıklarını kurun, en azından fontconfig ve DejaVu’yu kurun, aileyi varsaymak yerine sorarak çözün ve işi bitirmeden önce çıktıyı doğrulayın. Hepsi çok az kod ve hepsi geriye bakınca bariz, izleme sırasında ise görünmez bir şey. Örnek depolama, her iki Dockerfile’ı da içerir; çalışan bir imaj ile kırık bir imaj arasındaki fark sadece bir derleme farkıdır.