{"id":13580831,"url":"https://github.com/thyrlian/AirPdfPrinter","last_synced_at":"2025-04-06T06:32:03.499Z","repository":{"id":141702460,"uuid":"257674237","full_name":"thyrlian/AirPdfPrinter","owner":"thyrlian","description":"Virtual PDF AirPrint printer","archived":false,"fork":false,"pushed_at":"2023-01-12T00:46:21.000Z","size":971,"stargazers_count":61,"open_issues_count":1,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-03T19:45:14.589Z","etag":null,"topics":["airprint","docker","pdf","printer"],"latest_commit_sha":null,"homepage":null,"language":"Dockerfile","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thyrlian.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2020-04-21T18:00:00.000Z","updated_at":"2025-02-23T22:18:52.000Z","dependencies_parsed_at":"2024-01-16T20:30:08.627Z","dependency_job_id":"9c968e7b-0ac6-4015-af5e-a2b8ec30bf04","html_url":"https://github.com/thyrlian/AirPdfPrinter","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thyrlian%2FAirPdfPrinter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thyrlian%2FAirPdfPrinter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thyrlian%2FAirPdfPrinter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thyrlian%2FAirPdfPrinter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thyrlian","download_url":"https://codeload.github.com/thyrlian/AirPdfPrinter/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247445649,"owners_count":20939952,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["airprint","docker","pdf","printer"],"created_at":"2024-08-01T15:01:55.501Z","updated_at":"2025-04-06T06:32:03.179Z","avatar_url":"https://github.com/thyrlian.png","language":"Dockerfile","funding_links":[],"categories":["Dockerfile"],"sub_categories":[],"readme":"# AirPdfPrinter\n\n![headline](assets/AirPdfPrinter.png)\n\n[![Docker Hub](https://img.shields.io/badge/Docker%20Hub-info-blue.svg)](https://hub.docker.com/r/thyrlian/air-pdf-printer)\n\nYou 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!\n\n## Philosophy\n\nTo 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).\n\n  * The printer must be advertised with **Bonjour broadcasting**.\n\n  * The printer must communicate with the client using **IPP** (Internet Printing Protocol).\n\n## HOWTO\n\n* **Build**\n\n  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).\n\n  ```bash\n  # Assume you're in this project's root directory, where the Dockerfile is located\n  docker build -t air-pdf-printer .\n\n  # Build with argument, set your own admin password instead of the default one\n  docker build --build-arg ADMIN_PASSWORD=\u003cYourPassword\u003e -t air-pdf-printer .\n\n  # Or directly pull the image from Docker Hub\n  docker pull thyrlian/air-pdf-printer\n  ```\n\n  The default admin username is `root`, and the default admin password is [here](https://github.com/thyrlian/AirPdfPrinter/blob/master/Dockerfile#L23).\n\n* **Run**\n\n  ```bash\n  # Run a container with interactive shell (you'll have to start CUPS print server on your own)\n  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\n\n  # Run a container in the background\n  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\n  ```\n\n* **Notes**\n\n  * **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.\n\n    ```bash\n    # Change base image to ARMv7 architecture\n    sed -i.bak \"s/FROM ubuntu:/FROM arm32v7\\/ubuntu:/\" Dockerfile \u0026\u0026 rm Dockerfile.bak\n\n    # Change base image to x86_64 architecture\n    sed -i.bak \"s/FROM arm32v7\\/ubuntu:/FROM ubuntu:/\" Dockerfile \u0026\u0026 rm Dockerfile.bak\n    ```\n\n  * **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).\n\n      * **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:\n\n        ```bash\n        # Check ports in use on the host machine\n        sudo lsof -i -P -n | grep LISTEN\n        # Check if a specific port is in use on the host machine (e.g. port 631)\n        sudo lsof -i:631\n        \n        # If port 631 is in use, it's highly likely that the CUPS service is running, then check the service status\n        systemctl status cups\n        # Stop the CUPS service\n        systemctl stop cups\n        # Furthermore, you may want to disable the CUPS service\n        systemctl disable cups\n        # It may happen that the CUPS service will be activated again after reboot, because it's required by another service, to check this\n        systemctl --reverse list-dependencies cups.service\n        # To disable the CUPS service, disregard anything else\n        systemctl mask cups\n        ```\n\n  * **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.\n\n    Port | TCP or UDP | Service or protocol name | RFC | Service name | Used by\n    --- | --- | --- | --- | --- | ---\n    5353 | UDP | Multicast DNS (MDNS) | 3927 | mdns | Bonjour, AirPlay, Home Sharing, Printer Discovery\n\n* **Output**\n\n  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}`\n\n* **Troubleshoot**\n\n  * CUPS logs directory: `/var/log/cups/`\n\n  * Start Avahi daemon with verbose debug level: `avahi-daemon --debug`\n\n* **Commands**\n\n  ```bash\n  # Run all init scripts, in alphabetical order, with the status command\n  service --status-all\n\n  # List units that systemd currently has in memory, with specified type and state\n  systemctl list-units --type=service --state=active\n\n  # Start CUPS service\n  service cups start\n\n  # Start Avahi mDNS/DNS-SD daemon\n  service avahi-daemon start\n\n  # Shows the server hostname and port.\n  lpstat -H\n\n  # Shows whether the CUPS server is running.\n  lpstat -r\n\n  # Shows all status information.\n  lpstat -t\n\n  # Shows all available destinations on the local network.\n  lpstat -e\n\n  # Shows the current default destination.\n  lpstat -d\n\n  # Display network connections, you need to have net-tools package installed\n  netstat -ltup\n\n  # Browse for all mDNS/DNS-SD services using the Avahi daemon and registered on the LAN\n  avahi-browse -a -t\n\n  # Find internet printing protocol printers\n  ippfind\n  ippfind --remote\n  ```\n\n* **Manage**\n\n  Web Interface: http://[*IpAddressOfYourContainer*]:631/\n\n* **Add Printer**\n\n  * **macOS**: `System Preferences` -\u003e `Printers \u0026 Scanners` -\u003e `Add (+)` -\u003e `IP`\n\n    * **Address**: [*IpAddressOfYourContainer*]\n    * **Protocol**: `Internet Printing Protocol - IPP`\n    * **Queue**: `printers/PDF` (find the info here: http://[*IpAddressOfYourContainer*]:631/printers/)\n    * **Name**: [*YourCall*]\n    * **Use**: `Generic PostScript Printer`\n\n    \u003ca href=\"https://github.com/thyrlian/AirPdfPrinter/blob/master/assets/Add%20Printer%20-%20macOS.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AirPdfPrinter/blob/master/assets/Add%20Printer%20-%20macOS.png\" width=\"600\"\u003e\u003c/a\u003e\n\n  * **iOS**\n\n    \u003ca href=\"https://github.com/thyrlian/AirPdfPrinter/blob/master/assets/Add%20Printer%20-%20iOS%20-%201.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AirPdfPrinter/blob/master/assets/Add%20Printer%20-%20iOS%20-%201.png\" width=\"250\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/thyrlian/AirPdfPrinter/blob/master/assets/Add%20Printer%20-%20iOS%20-%202.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AirPdfPrinter/blob/master/assets/Add%20Printer%20-%20iOS%20-%202.png\" width=\"250\"\u003e\u003c/a\u003e\n    \u003ca href=\"https://github.com/thyrlian/AirPdfPrinter/blob/master/assets/Add%20Printer%20-%20iOS%20-%203.png\" target=\"_blank\"\u003e\u003cimg src=\"https://github.com/thyrlian/AirPdfPrinter/blob/master/assets/Add%20Printer%20-%20iOS%20-%203.png\" width=\"250\"\u003e\u003c/a\u003e\n\n## License\n\nCopyright (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.\n\n## Attribution\n\nThe [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.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthyrlian%2FAirPdfPrinter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthyrlian%2FAirPdfPrinter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthyrlian%2FAirPdfPrinter/lists"}