Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/thyrlian/AirPdfPrinter
Virtual PDF AirPrint printer
https://github.com/thyrlian/AirPdfPrinter
airprint docker pdf printer
Last synced: 3 months ago
JSON representation
Virtual PDF AirPrint printer
- Host: GitHub
- URL: https://github.com/thyrlian/AirPdfPrinter
- Owner: thyrlian
- License: apache-2.0
- Created: 2020-04-21T18:00:00.000Z (almost 5 years ago)
- Default Branch: master
- Last Pushed: 2023-01-12T00:46:21.000Z (about 2 years ago)
- Last Synced: 2024-10-28T10:30:05.399Z (3 months ago)
- Topics: airprint, docker, pdf, printer
- Language: Dockerfile
- Size: 948 KB
- Stars: 58
- Watchers: 3
- Forks: 9
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# AirPdfPrinter
![headline](assets/AirPdfPrinter.png)
[![Docker Hub](https://img.shields.io/badge/Docker%20Hub-info-blue.svg)](https://hub.docker.com/r/thyrlian/air-pdf-printer)
You wanna print or save something as PDF on your iOS device? Especially keeping those texts as they are, instead of being images. Well, Apple's iDevices don't come with such a feature by default, but don't worry, we provide you a neat solution here - a virtual PDF AirPrint printer!
## Philosophy
To enable [AirPrint](https://support.apple.com/en-us/HT201311) of a printer, below requirements must be fulfilled, as described [here](https://wiki.debian.org/CUPSAirPrint).
* The printer must be advertised with **Bonjour broadcasting**.
* The printer must communicate with the client using **IPP** (Internet Printing Protocol).
## HOWTO
* **Build**
Because `chmod` option is used for `ADD` instruction, which requires **BuildKit**, make sure it's enabled (please check [this](https://docs.docker.com/build/buildkit/#getting-started) to learn how to enable BuildKit).
```bash
# Assume you're in this project's root directory, where the Dockerfile is located
docker build -t air-pdf-printer .# Build with argument, set your own admin password instead of the default one
docker build --build-arg ADMIN_PASSWORD= -t air-pdf-printer .# Or directly pull the image from Docker Hub
docker pull thyrlian/air-pdf-printer
```The default admin username is `root`, and the default admin password is [here](https://github.com/thyrlian/AirPdfPrinter/blob/master/Dockerfile#L23).
* **Run**
```bash
# Run a container with interactive shell (you'll have to start CUPS print server on your own)
docker run --network=host -it -v $(pwd)/pdf:/root/PDF -v $(pwd)/cups-pdf:/var/spool/cups-pdf --name air-pdf-printer air-pdf-printer /bin/bash# Run a container in the background
docker run --network=host -d -v $(pwd)/pdf:/root/PDF -v $(pwd)/cups-pdf:/var/spool/cups-pdf --name air-pdf-printer air-pdf-printer
```* **Notes**
* **Multi-Arch**: This Docker container would also work on ARM-based computer, you just need to build the Docker image properly. Here I'm not gonna talk about Docker's experimental feature `buildx` for multiple architectures support, you can find more information [here](https://docs.docker.com/buildx/working-with-buildx/) and [here](https://docs.docker.com/docker-for-mac/multi-arch/) on your own. In order to build for the appropriate CPU architecture, we can simply use the right base image in the Dockerfile.
```bash
# Change base image to ARMv7 architecture
sed -i.bak "s/FROM ubuntu:/FROM arm32v7\/ubuntu:/" Dockerfile && rm Dockerfile.bak# Change base image to x86_64 architecture
sed -i.bak "s/FROM arm32v7\/ubuntu:/FROM ubuntu:/" Dockerfile && rm Dockerfile.bak
```* **Network**: With the option `--network=host` set, the container will use the Docker host network stack. When using host network mode, it would discard published ports, thus we don't need to publish any port with the `run` command (e.g.: `-p 631:631 -p 5353:5353/udp`). And in this way, we don't require [dbus](https://www.freedesktop.org/wiki/Software/dbus/) (a simple interprocess messaging system) package in the container. However, the `dbus` service is still needed on the host machine (to check its status, you can run for example `systemctl status dbus` on Ubuntu), and even it is deactivated, it would be automatically triggered to active when `avahi-daemon` starts running. For more information about Docker's network, please check [here](https://docs.docker.com/engine/reference/run/#network-settings) and [here](https://docs.docker.com/network/host/). Please be aware, the host networking driver only works on Linux hosts, and is not supported on Docker Desktop for Mac, Docker Desktop for Windows, as stated [here](https://docs.docker.com/network/network-tutorial-host/#prerequisites).
* **Port conflict**: in case any required port on the host machine is already in use, Docker will fail to bind the container port to the host port, when this happens, you'll find a line in `/var/log/cups/error_log`: `Unable to open listen socket for address 0.0.0.0:631 - Address already in use`. To debug and fix it:
```bash
# Check ports in use on the host machine
sudo lsof -i -P -n | grep LISTEN
# Check if a specific port is in use on the host machine (e.g. port 631)
sudo lsof -i:631
# If port 631 is in use, it's highly likely that the CUPS service is running, then check the service status
systemctl status cups
# Stop the CUPS service
systemctl stop cups
# Furthermore, you may want to disable the CUPS service
systemctl disable cups
# It may happen that the CUPS service will be activated again after reboot, because it's required by another service, to check this
systemctl --reverse list-dependencies cups.service
# To disable the CUPS service, disregard anything else
systemctl mask cups
```* **Port**: Apple is using UDP port 5353 to find capable services on your network via Bonjour automatically. Even though mDNS discovery uses the predefined port UDP 5353, application-specific traffic for services like AirPlay may use dynamically selected port numbers.
Port | TCP or UDP | Service or protocol name | RFC | Service name | Used by
--- | --- | --- | --- | --- | ---
5353 | UDP | Multicast DNS (MDNS) | 3927 | mdns | Bonjour, AirPlay, Home Sharing, Printer Discovery* **Output**
CUPS-PDF output directory are defined under **Path Settings** which is located at `/etc/cups/cups-pdf.conf`. And the default path usually is: `/var/spool/cups-pdf/${USER}`
* **Troubleshoot**
* CUPS logs directory: `/var/log/cups/`
* Start Avahi daemon with verbose debug level: `avahi-daemon --debug`
* **Commands**
```bash
# Run all init scripts, in alphabetical order, with the status command
service --status-all# List units that systemd currently has in memory, with specified type and state
systemctl list-units --type=service --state=active# Start CUPS service
service cups start# Start Avahi mDNS/DNS-SD daemon
service avahi-daemon start# Shows the server hostname and port.
lpstat -H# Shows whether the CUPS server is running.
lpstat -r# Shows all status information.
lpstat -t# Shows all available destinations on the local network.
lpstat -e# Shows the current default destination.
lpstat -d# Display network connections, you need to have net-tools package installed
netstat -ltup# Browse for all mDNS/DNS-SD services using the Avahi daemon and registered on the LAN
avahi-browse -a -t# Find internet printing protocol printers
ippfind
ippfind --remote
```* **Manage**
Web Interface: http://[*IpAddressOfYourContainer*]:631/
* **Add Printer**
* **macOS**: `System Preferences` -> `Printers & Scanners` -> `Add (+)` -> `IP`
* **Address**: [*IpAddressOfYourContainer*]
* **Protocol**: `Internet Printing Protocol - IPP`
* **Queue**: `printers/PDF` (find the info here: http://[*IpAddressOfYourContainer*]:631/printers/)
* **Name**: [*YourCall*]
* **Use**: `Generic PostScript Printer`* **iOS**
## License
Copyright (c) 2020-2023 Jing Li. It is released under the [Apache License](http://www.apache.org/licenses/). See the [LICENSE](https://raw.githubusercontent.com/thyrlian/AirPdfPrinter/master/LICENSE) file for details.
## Attribution
The [AirPrint-PDF.service](https://github.com/thyrlian/AirPdfPrinter/blob/master/AirPrint-PDF.service) static service XML file for Avahi is created via [airprint-generate](https://github.com/tjfontaine/airprint-generate) script.