Git Product home page Git Product logo

docker-cups-airprint's Introduction

Simple AirPrint bridge for your local printers

Docker image Build status license DockerHub pulls DockerHub stars GitHub stars Contributors Paypal GitHub Sponsor

Purpose

Run a container with CUPS and Avahi (mDNS/Bonjour) so that local printers on the network can be exposed via AirPrint to iOS/macOS devices.

Requirements

  • must run on a linux host (could not yet figure out a way to run macvlan on macOS: docker/for-mac#3447)
  • the container must (really, really should) have its own, dedicated IP so it does not interfere with other services listen on the ports required (macOS: already runs CUPS and mdns, Linux: mostly also already runs CUPS and/or Avahi)
  • you must have CUPS drivers available for your printer.
    • Please poke me when you know how to use the Windows drivers of a shared printer with CUPS as "proxy" (no CUPS drivers)

Hints

  • a shared Windows printer must be accessible by anonymous users (without login) or you must provide a username and password whithin its device URI (smb://user:pass@host/printer)

Play with it

-> NOT WORKING on macOS! (https://docs.docker.com/docker-for-mac/networking/#per-container-ip-addressing-is-not-possible)

docker run -d --rm -e CUPS_WEBINTERFACE="yes" -e CUPS_REMOTE_ADMIN="yes" --hostname mycups --name cups-setup drpsychick/airprint-bridge

# Important: administration will only be possible if hostname/ip match! (no portforwarding etc.)
# CUPS error if hostname mismatches: `Request from "172.17.42.1" using invalid Host: field "localhost:6310"`
echo "http://$(docker inspect --format '{{ .NetworkSettings.Networks.bridge.IPAddress }}' cups-setup):631"
# -> go to http://$IP:631/ and configure your printer(s)

# save printers.conf (to get the right device ID etc)
docker cp cups-setup:/etc/cups/printers.conf ./

Variables overview

Important! Docker environment variables only support single line without double quotes!

CUPS_ADMIN_USER=${CUPS_ADMIN_USER:-"admin"}
CUPS_ADMIN_PASSWORD=${CUPS_ADMIN_PASSWORD:-"secr3t"}
CUPS_WEBINTERFACE=${CUPS_WEBINTERFACE:-"yes"}
CUPS_SHARE_PRINTERS=${CUPS_SHARE_PRINTERS:-"yes"}
CUPS_REMOTE_ADMIN=${CUPS_REMOTE_ADMIN:-"yes"} # allow admin from non local source
CUPS_ACCESS_LOGLEVEL=${CUPS_ACCESS_LOGLEVEL:-"config"} # all, access, config, see `man cupsd.conf`
CUPS_LOGLEVEL=${CUPS_LOGLEVEL:-"warn"} # error, warn, info, debug, debug2 see `man cupsd.conf`
CUPS_ENV_DEBUG=${CUPS_ENV_DEBUG:-"no"} # debug startup script and activate CUPS debug logging
CUPS_IP=${CUPS_IP:-$(hostname -i)} # no need to set this usually
CUPS_HOSTNAME=${CUPS_HOSTNAME:-$(hostname -f)} # no need to set this usually -> allows accessing cups via name: https://cups.domain:631/
# pass the server cert/key via env in one line each, i.e. CUPS_SSL_CERT=---- BEGIN CERT ...\none\nline\nseparated\nby\nbackslash\nnewline
CUPS_SSL_CERT=${CUPS_SSL_CERT:-""}
CUPS_SSL_KEY=${CUPS_SSL_KEY:-""}
# avahi configuration options
AVAHI_INTERFACES=${AVAHI_INTERFACES:=""}
AVAHI_IPV6=${AVAHI_IPV6:="no"}
AVAHI_REFLECTOR=${AVAHI_REFLECTOR:="no"}
AVAHI_REFLECT_IPV=${AVAHI_REFLECT_IPV:="no"}

Add printer through ENV

Set any number of variables which start with CUPS_LPADMIN_PRINTER. These will be executed at startup to setup printers through lpadmin.

CUPS_LPADMIN_PRINTER1=lpadmin -p test -D 'Test printer' -m raw -v ipp://myhost/printer
CUPS_LPADMIN_PRINTER2=lpadmin -p second -D 'another' -m everywhere -v ipp://myhost/second
CUPS_LPADMIN_PRINTER3=lpadmin -p third -D 'samba printer' -m '..the right driver string...' -o PageSize=A4 -v smb://user:pass@host/printer
CUPS_LPADMIN_PRINTER3_ENABLE=cupsenable third

Configure AirPrint

Nothing to do, it will work out of the box (once you've added printers)

Configure Google Cloud Print

Update: This is no longer supported since end of 2020! https://github.com/google/cloud-print-connector Support has been removed from this image.

You're ready!

Now you have all you need to setup your airprint-bridge configured through ENV. How to setup a dedicated server in your local subnet is covered in the next section.

Prepare your dedicated AirPrint container

Create a virtual network bridge to your local network so that a docker container can have its own IP on your subnet AND be reachable from the host. As you want clients anywhere on the local network to discover printers, the container must have an IP on the local subnet.

You don't need the macvlan bridge if your host does not need to talk to the container!

on a Linux host

All of this only works on a linux docker host.

eth=<network interface> # eth0
mac=<network MAC> # AA:AA:AA:AA:AA
mac2=<fake MAC> # AA:AA:AA:AA:AB
# enable promicious mode (multiple MACs)
sudo ifconfig $eth promisc
sudo ip link set $eth address $mac2
sudo ip link add mac0 link $eth address $mac type macvlan mode bridge
# drop & flush DHCP lease on the interface
# start DHCP on new interface and restart resolver
sudo -- bash -c '(
dhclient -r $eth && ip addr flush dev $eth && ip neigh flush all
dhclient mac0 && service resolvconf restart || dhclient $eth
)'

Create a docker network for your local subnet. Parent interface is either mac0 if you followed the above or ethX if you decided you don't need to talk from the host to the container.

docker network create --driver macvlan --subnet 192.168.2.0/24 --gateway 192.168.2.1 -o parent=mac0 localnet

Now create your cups container with a specific IP on your local subnet

cups_ip=192.168.2.100
cups_name=cups.home
docker create --name cups-test --net=localnet --ip=$cups_ip --hostname=$cups_name \
  --memory=100M -p 137:137/udp -p 139:139/tcp -p 445:445/tcp -p 631:631/tcp -p 5353:5353/udp \
  -e CUPS_USER_ADMIN=admin -e CUPS_USER_PASSWORD=secr3t \
  drpsychick/airprint-bridge:latest

# start it
docker start cups-test

# open a shell
docker exec -it cups-test /bin/bash

Adding printers:

Hint: When you want to use a local USB printer, use --volume /dev/bus/usb:/dev/bus/usb to mount the USB device directly into the container. (see also #35)

Automated through command line

The preferred way to configure your container, but it has limitations.

# search for your printer
lpinfo --make-and-model "Epson Stylus Photo RX" -m
# I chose RX620 for my RX520 and it works fine...
lpadmin -p Epson-RX520 -D 'Epson Stylus Photo RX520' -m 'gutenprint.5.3://escp2-rx620/expert' -v smb://user:pass@host/Epson-RX520

Pass lpadmin command via environment

docker ... -e CUPS_LPADMIN_PRINTER1="lpadmin -p Epson-RX520 -D 'Epson Stylus Photo RX520' -m 'gutenprint.5.3://escp2-rx620/expert' -o PageSize=A4 -v smb://user:pass@host/Epson-RX520" ...

Find and set printer specific options

lpoptions -p Epson-RX520 -l
# -> lists all printer options you can pass to `lpadmin` like `-o PageSize=A4`

Enable the printer and accept jobs

CUPS_LPADMIN_PRINTER1_ENABLE=cupsenable Epson-RX520
CUPS_LPADMIN_PRINTER1_ACCEPT=cupsaccept Epson-RX520

Manually through web interface

Enable the interface through ENV: CUPS_WEBINTERFACE="yes" and CUPS_REMOTE_ADMIN="yes".

You may want to enable this only temporarily!

Enable it manually through config: cupds.conf:

Listen *:631
WebInterface Yes
<Location />
  Order allow,deny
  Allow from all
</Location>
<Location /admin>
  Order allow,deny
  Allow from all
</Location>

Then go to https://$cups_ip:631/admin or https://$cups_name:631, login and setup your printer(s).

Automated through files

This is easiest combined with the webinterface:

  1. setup your printer through the webinterface or lpadmin and test it
  2. take the printers.conf and .ppd files from the container and automate it
# get `printers.conf` and `.ppd` file from the container
docker cp cups-test:/etc/cups/printers.conf ~/mycups/
docker cp cups-test:/etc/cups/ppd/PrinterName.ppd ~/mycups/

Use your own docker image:

~/mycups/Dockerfile:

FROM drpsychick/airprint-bridge:latest

COPY printers.conf /etc/cups/
COPY PrinterName.ppd /etc/cups/ppd

And create the container using your own image:

docker build -t mycups:latest .
docker create --name cups-real [...] mycups:latest
docker start cups-real

Test it

  1. on any macOS device, add a new printer. You'll find your printer prefixed with AirPrint in the default tab
  2. on the web interface, select Print Test Page in the Maintenance dropdown
  3. on any iOS device, take any file and tap on share -> print -> select printer -> (select a printer from the list)

Share -> Print -> select printer Printer list Print Printer info

Issues:

https://github.com/SickHub/docker-cups-airprint/issues

Hints for QNAP

  • using macvlan is not possible, instead you should use qnet driver to create the docker network
docker network create --driver=qnet --ipam-driver=qnet --ipam-opt=iface=bond0 --subnet ...

Credits

this is based on awesome work of others

Contribute

  • I'm happy for any feedback! Create issues, dicussions, ... feel free and involve!
  • Send me a PR

docker-cups-airprint's People

Contributors

drpsychick avatar hammyhavoc avatar mundschenk-at avatar renovate[bot] avatar sjafferali avatar stefan-golinschi avatar theaninova avatar vajonam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

docker-cups-airprint's Issues

TLS errors

Find out why and how to fix this error from the cups/error_log:
Unable to encrypt connection: A TLS fatal alert has been received.

setup automated builds with travis

like docker-dnsmasq and others

  • setup dev branch
  • decide on base image (debian or ubuntu or alpine?)
    • define environment matrix (versions)
  • setup travis and make sure it works
    *.[ ] verify that new tags are built on docker hub

fix slow startup

it seems systemd is required and causes a timeout

method call time=1585598834.846481 sender=:1.1 -> destination=org.freedesktop.systemd1 serial=2 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=GetDynamicUsers
method call time=1585598834.851244 sender=:1.2 -> destination=org.freedesktop.systemd1 serial=2 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=GetDynamicUsers
method call time=1585598854.951282 sender=:1.4 -> destination=org.freedesktop.systemd1 serial=2 path=/org/freedesktop/systemd1; interface=org.freedesktop.systemd1.Manager; member=GetDynamicUsers
[...]
error time=1585598859.818583 sender=org.freedesktop.DBus -> destination=:1.1 error_name=org.freedesktop.DBus.Error.TimedOut reply_serial=2
   string "Failed to activate service 'org.freedesktop.systemd1': timed out (service_start_timeout=25000ms)"
error time=1585598859.818658 sender=org.freedesktop.DBus -> destination=:1.2 error_name=org.freedesktop.DBus.Error.TimedOut reply_serial=2
   string "Failed to activate service 'org.freedesktop.systemd1': timed out (service_start_timeout=25000ms)"
error time=1585598859.818695 sender=org.freedesktop.DBus -> destination=:1.4 error_name=org.freedesktop.DBus.Error.TimedOut reply_serial=2
   string "Failed to activate service 'org.freedesktop.systemd1': timed out (service_start_timeout=25000ms)"

Looking for MAINTAINERs

Background:

  • I started this project years ago to solve a problem for me: using an old USB printer with AirPrint.
  • I invested significant time to make this publicly available and reusable - and I got "nothing" out of it (apart from solving the problem for myself) but a few stars on GitHub and some anonymous users that seemed happy it exists.

Present:
I just bought a new printer that has AirPrint builtin. I will not keep my old printer and thus will no longer use this image or be able to test changes.

Consequence: We need to find a new maintainer for this project or it will die slowly.

Airprint print PDF

airprint ๏ผŒ
ios devices can only print images, but cannot print pdf, word, web pages, etc.
My printer is a black and white printer, I guess itโ€™s a cups-filter problem

setup CUPS browsed

  • check and define sane defaults
  • document what its good for and how its configured

"Bad Request" - Help configuring

Hi!

I'm trying to configure this for my printer, from what I read I need to first do cups-setup and configure everything, then copy the config, and create another container and copy the config to it, I'm still on the cups-setup, when I navigate to localhost:631 I get a "Bad Request" message, I read on a stackoverflow issue that I should change Listen to *:631 but when looking at the config its got Listen /run/cups/cup.sock so I'm not sure if I should change that.

The IP it shows in the console didn't work for me, and neither does the hostname.

I have not setup anything like this before so I'm very newbie (and its also printers, so its always a hassle)

Document USB printer setup

  • add a separate USB.md file to the repo, describing the process of attaching/setting up a USB printer
  • add screenshots/photos to docs/ (if applicable)
  • link the USB.md file in the README in a "Example Setups" (or similar) section

@HammyHavoc would you be willing to create a PR for this?

Usb printers power off and avahi-deamon

I'm using the docker with happiness until I turn off the USB printer (a Canon MP240 if useful) but not the server. Then I still spend hours trying to make it work (putting the printer properly on the network again).

I noticed that in logs if I restart the server, I find the following error:

Unable to communicate with avahi-daemon: Access denied

Am I doing something wrong? Should it be fine to power off the printer while the server is still running?

Add possibility to install additional drivers (or to run custom init scripts)

Hi to all maintainers!

I like your work! It is well thought through!๐Ÿ‘

I have a suggestion for an improvement though:
Some printers need extra drivers, f.i. a few from Canon. The package offered by the vendor is a .sh script which checks some dependencies, installs them, if needed (over apt), and then it installs the driver package (as .deb).
I tried to install this after the container was up and running. I mounted a volume with the extra files and then from inside, I started the script. The problem is that this .sh script will try to restart cups at some point, which doesn't go well and the container crashes. From there on, dpkg is in a not-done state and apt doesn't work either. Every time you would try to resume the dpkg reconfiguration, it would restart cups, which crashes again.....
The next thing I tried (also to make it more automated), was to add a further init-script as a command directive in my docker-compose.yaml file, but this will never be run, because the entrypoint script will run first, and this script will never get a chance to run. At least, this is what happens with my compose version.

Long story short, the dirty workaround was to:

  • copy your start-cups.sh and save it in a volume, externally
  • overwrite the default entrypoint with my script (by mounting a volume on that path). The script first installs the extra stuff, and finally starts the default start-cups.sh

This works now, but as I mentioned, this is a dirty workaround. Why ? It is a long term issue:
Now I'm stuck with the static start-cups.sh, which doesn't get updated as soon as this gets changes/improvements on github.

I was also thinking about your suggestions in the readme, to create my own Dockerfile and adapt the image as needed, but I'm not a fan of this approach either; for the same Reason: I try to make every docker service updatable. As soon as there are updates online, I want to be able to automatically update them, without any manual intervention on my part (in best case).

Does my train of thought make sense?

So my suggestion is to add to the image some points of customization.

  1. One easy solution would be to replace the ENTRYPOINT directive with the CMD directive. Thus, the startup command can be overwritten when starting the container, and we don't have to touch or save the default script from the repo somewhere else. The custom command can than call the default startup script afterwards.
  2. Another solution would be to add some ENV variables, that hold the path to the scripts. Those will be evaluated and exectuted in the entry point,. For instance a var named "PRE_INIT_SCRIPT"

BR

cleanup and create proper documentation/examples

Tasks:

  • cleanup code/repository
  • structured readme, link to separate examples
    • add badges
  • setup and test cloud print

Expected outcome:

  • I can try it (along the readme) within 10 minutes and it works

Work on homeassistant: portainer

Hello, I have a Rapsberry 3B and have a homeassistant OS installed on it with Portainer installed inside to run docker containers. I have successfully used the previous version of your product and have been printing to the printer via airprint. But after the last container update, I can no longer access the CUPS address. Can you help?

avahi stopping after sometime

I have an issue where the avahi-daemon stops after sometime. and restarting the container doesn't fix it. To fix it I have to shell into the box and restart avahi-daemon. Have you seen this behavior? or maybe add a automatic re starter for avahi?

Feature: support AirSane

I have a big need for the scanner functionality in my Brother DCP-7055W. Unfortunately Brother is either dragging it's feet, or will abandon my model for MacOS 11. I found this wonderfull project https://github.com/SimulPiscator/AirSane

Any way we could roll in libsane and airsane into this somehow?
(I'd be willing to do PR's, but i've never worked with sane before)

Also, is cups-dbus-avahi IPC dead in the water? Looks like we're doing this by hand now, since cups can't talk to avahi at all :/

Printers are not created on initial start/container setup, only on subsequent restarts

I'd like to use the ENV method to create my printers. Unfortunately, the script does not seem to evaluate the ENV variables correctly on initialization of a container, but it does on subsequent restarts. I'm not sure why from reading the startup script, but there seems to be an issue with one of the cupsctl calls, which probably breaks the subshell.

...
.--> CUPS ready
cupsctl: Unable to connect to server: Bad file descriptor
E [01/Nov/2022:05:22:08 +0000] Unable to communicate with avahi-daemon: Daemon not running
===========================================================
The dockerized CUPS instance is now ready for use! The web
interface is available here:
...

whereas on restart the relevant part of the log looks like this:

.--> CUPS ready
localhost - - [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - root [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 201 4614 - -
E [01/Nov/2022:19:42:43 +0000] Unable to communicate with avahi-daemon: Daemon not running
localhost - - [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - root [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 201 4614 - -
E [01/Nov/2022:19:42:43 +0000] Unable to communicate with avahi-daemon: Daemon not running
localhost - - [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - root [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 201 4614 - -
E [01/Nov/2022:19:42:43 +0000] Unable to communicate with avahi-daemon: Daemon not running
localhost - - [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - root [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 201 4614 - -
E [01/Nov/2022:19:42:43 +0000] Unable to communicate with avahi-daemon: Daemon not running
localhost - - [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - root [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 201 4640 - -
E [01/Nov/2022:19:42:43 +0000] Unable to communicate with avahi-daemon: Daemon not running
localhost - - [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - root [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 201 4640 - -
E [01/Nov/2022:19:42:43 +0000] Unable to communicate with avahi-daemon: Daemon not running
localhost - - [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
localhost - root [01/Nov/2022:19:42:43 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 201 4662 - -
--> adding printers
E [01/Nov/2022:19:42:43 +0000] Unable to communicate with avahi-daemon: Daemon not running
CUPS_LPADMIN_PRINTER1 = lpadmin ...
===========================================================
The dockerized CUPS instance is now ready for use! The web
interface is available here:

The time difference is because the container got recreated by Portainer this morning and I did a manual restart just now.

lpinfo: success timeout on lpinfo -m

i've runned the container on a slow host, and it was failing to setup the printer as the list of driver was not shown..

with more debugging i've found that the lpinfo -m command was returning (after a while of loading...) just lpinfo: success deleting some folder from /usr/lib/cups/driver/ (no matther what folder) allowed me to fix the lpinfo -m command, so basically was a timeout problem listing all installed drivers, stripping out some folder allow you to success... you probably should consider finding a way to enlarge this timeout (i assume the default is 30sec)

Docker publish version tags for pinning

I would like to pin a specific image, and update more deliberately, however the current tagging of the docker images makes this not possible since previous images are removed.

Is there any chance of adding version number tags to the docker images are published? Since this is built regularly, perhaps we could add a date tag that is also added to the current image, so that older images are also available for pinning purposes?

Documentation Clarity

I say all this with a great desire to use the project, and a decent amount of confusion to get it up and running, with the greatest amount of respect! I ultimately passed on using the project due to running out of time to troubleshoot, but I'd love to use it and a few small documentation improvements I believe would really help.

I think the readme would greatly benefit from focusing on the golden path first: how do you expect the users to use this project 99% of the time?

I would then suggest moving the separate troubleshooting steps either all to the end of the readme or to another markdown file.

An example of this is the macvlan portion;

You don't need the macvlan bridge if your host does not need to talk to the container!

Okay, so what do I do if I don't care about host access? The only instructions are for using macvlan. Is macvlan the expected way to use it? Or is this a sidebar for those who do need it, but other are supposed to just skip over some portion of the doc?

Also, even with following the instructions, there appears to be an issue with the provided example bash sub shell script:

sudo -- bash -c '(
dhclient -r $eth && ip addr flush dev $eth && ip neigh flush all
dhclient mac0 && service resolvconf restart || dhclient $eth
)'

It references $eth, but $eth is not accessible to this subshell. For example:

eth="foo"
sudo -- bash -c '(
echo $eth - this is the value
)'
# echos " - this is the value"

It would work if you did

eth="foo"
sudo -- bash -c "echo \"$eth - this is the value\" && secondCommandForExample"
# outputs:
# foo - this is the value
# second command output

It also took me a while to realize these were bash commands. Maybe it would be best to put this all in a script that the user can run called something like demo_example.sh or something?

Also, it still didn't see my Brother USB printer even though I used that volume trick mentioned (which I fully admit may have been pebkac as I got it to work in a personally built container before I found this project, so I might have just set it up wrong with all the iterated attempts).

I feel bad requesting these changes and not just making a PR, but I don't feel comfortable making a PR unless I can at LEAST get it to work myself.

Ultimately, I don't know how helpful my suggestions are since I wasn't able to get it to work, but I ultimately felt like I was jumping all over the readme instead of generally starting at the top and moving down as I progressed.

Again, I feel really bad just complaining! I hope this is received as constructive feedback and not just whining. :) Maybe I might be able to make a couple real contributions if I can get it to work eventually :D

Multi-arch build and images

  • rewrite travis-ci to build for multiple arch
  • push images to docker hub, don't build on docker hub -> faster

Set cups hostname

To allow accessing cups web interface on the local network via name cups.host:631

cupsctl ServerName=cups.host

or figure out why automatic discovery does not work

Idle - "File "/usr/lib/cups/filter/brlpdwrapperdcpj315w" not available: No such file or directory" error

Hello.

I think your idea is super cool to provide automated way to share drivers with AirPrint. I have running well Brother DPC-J315W connected to several end users (Windows 10, Linux). I finally want to enable my users to use iOS AirPrint.

I installed your Docker Image and I try configure my printer with following steps.
image

then

image

I add PPD file - source from Brother drivers. https://pastebin.com/Ryc7sc7y

image

I have an error Idle - "File "/usr/lib/cups/filter/brlpdwrapperdcpj315w" not available: No such file or directory"

image
How can I fix it?

persistent configuration via volume creation

Hi,
I think it would be easier to make the printers.conf and other custom config persistent using a specific volume
I did
docker volume create cups
then I added a (-v /cups:/etc/cups) in the docker run command
I have already saved the printers.conf in the hst as you mentioned so I have just copy it
cp printers.conf /var/lib/docker/volumes/cups/_data/
restarted the container and the printers remains

Thanks

Update Ubuntu Version.

Looking at the DockerFile it seems it uses Eoan otherwise known as Ubuntu 19.10. This version has been end of life since July 2020.
Could the Ubuntu version be updated to a version that is supported.

arm64 support

docker-cups-airprint does work fine on arm64 ๐Ÿ’ฏ

I only disabled IPv6 and limited to eth0 for avahi.
I'm running it on kubernetes with host networking and without limiting to eth0 it would announce way to many interfaces.

sed -i 's/^.*allow-interfaces=.*/allow-interfaces=eth0/' /etc/avahi/avahi-daemon.conf
sed -i 's/^.*use-ipv6=.*/use-ipv6=no/' /etc/avahi/avahi-daemon.conf
#sed -i 's/^.*enable\-reflector=.*/enable\-reflector\=yes/' /etc/avahi/avahi-daemon.conf
#sed -i 's/^.*reflect\-ipv=.*/reflect\-ipv\=yes/' /etc/avahi/avahi-daemon.conf
sed -i 's/^.publish-aaaa-on-ipv4=.*/publish-aaaa-on-ipv4=no/' /etc/avahi/avahi-daemon.conf

My image can be found here https://hub.docker.com/repository/docker/vchrisb/airprint-bridge/general

Regarding #45 - color-supported not avaible breaks airprint-generate.py

@vajonam

Hi, i am coming from this commit
In the past i had removed the gpc stuff on a local checkout myself. And your very nice container worked fine for months
ATM i am migrating my docker host and tried to go with upstream again
But it seems pull #45 killed it for me

output:

cups-airprint  | The dockerized CUPS instance is now ready for use! The web
cups-airprint  | interface is available here:
cups-airprint  | URL:       http://192.168.1.253:631/ or http://futros740:631/
cups-airprint  | Username:  admin
cups-airprint  | Password:  admin
cups-airprint  |
cups-airprint  | ===========================================================
cups-airprint  | Traceback (most recent call last):
cups-airprint  |   File "/opt/airprint/airprint-generate.py", line 299, in <module>
cups-airprint  |     apg.generate()
cups-airprint  |   File "/opt/airprint/airprint-generate.py", line 179, in generate
cups-airprint  |     if attrs['color-supported']:
cups-airprint  | KeyError: 'color-supported'

printer creation:

- CUPS_LPADMIN_PRINTER1=lpadmin -D "HP laserJet M2727 MFP" -p LaserJet123 -v lpd://10.0.0.29/queue -L LivingRoom -o HPOption_Duplexer=true -o Resolution=1200dpi -o PageSize=A4 -o Duplex=DuplexNoTumble -o MediaType=Plain -o Smoothing=off -o HPEconoMode=false -o HPServicesWeb=ProductManuals -o printer-error-policy=abort-job -o cupsIPPSupplies=true
- CUPS_LPADMIN_PRINTER1_ENABLE=cupsenable LaserJet123
- CUPS_LPADMIN_PRINTER1_ACCEPT=cupsaccept LaserJet123

the attrs array parsed in python script (this is from manual adding via cups interface and trying hplip address for more information so ignore device uri)
arry parsed in pythonscript.txt

Adding the color-supported to CUPS_LPADMIN_PRINTER1 was not sufficient

(Only) after removing the color-supported option from airprint-generate.py creating an avahi service was successful
Commenting out wasn't ideal, so i did some research. Seems to me like the value checked for color isn't ideal and/or needs a fallback:

Sadly my python skills s**** and my printer is not supporting that much, so i leave the additional information here and maybe get back to it

the quick fix for me is to just comment out the commit mentioned above

Greetings

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

This repository currently has no open or pending branches.

Detected dependencies

dockerfile
Dockerfile
  • ubuntu noble
  • ubuntu noble
  • ubuntu noble
  • ubuntu noble
regex
.circleci/config.yml
  • docker/buildx v0.14.0

  • Check this box to trigger a request for Renovate to run again on this repository

Slow to collect information about printer and a lot more after reboot.

Hi,
I'm using docker on Synology NAS with OS names DSM based on busybox.

Looks like there is some issue in my log :
image

The default configuration of my printer :
image

it takes a will to collect it collect the wrong things :
IMG_0327
IMG_0326
Enveloppe <> A4

I don't understand what is going on, but I'm trying to find a solution.
I will update if I have any more information.

config through ENV

Tasks

  • support ENV configuration
    • webinterface yes/no
    • ssl config
    • per printer: name, location, description, device URI, URL for PPD or model
      • lpadmin command (without .ppd)?
  • support binary file through ENV (.ppd) - how?
    • background: it would be great if I did not have to create my own image just to configure my printer...
    • Options:
      • mount directory -> requires users to setup persistent storage... not great
      • install printer on every startup with lpadmin -> nice idea! (and/or maybe download the .ppd?)
      • through ENV (one line, BASE64 encoded?) -> veeery ugly

Decisions/Outcome:

broken pipe - cannot assign requested address

I'm trying to deploy the image in portainer swarm environment. I've configured a macvlan network and it should be getting a valid address.

However, when running the service, I get this log with a bunch of errors due to it being unable to start the HTTP server:

D [30/Sep/2023:19:09:26 +0000] [Client 33] PUT /admin/conf/cupsd.conf HTTP/1.1
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Active clients and dirty files", busy="Active clients and dirty files"
D [30/Sep/2023:19:09:26 +0000] [Client 33] Read: status=200, state=9
D [30/Sep/2023:19:09:26 +0000] [Client 33] No authentication data provided.
D [30/Sep/2023:19:09:26 +0000] cupsdIsAuthorized: username=""
localhost - - [30/Sep/2023:19:09:26 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 401 0 - -
D [30/Sep/2023:19:09:26 +0000] [Client 33] cupsdSendHeader: code=401, type="text/html", auth_type=0
D [30/Sep/2023:19:09:26 +0000] [Client 33] WWW-Authenticate: Basic realm=\"CUPS\", PeerCred, Local trc=\"y\"
D [30/Sep/2023:19:09:26 +0000] [Client 33] Closing connection.
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Active clients and dirty files"
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Active clients and dirty files", busy="Dirty files"
D [30/Sep/2023:19:09:26 +0000] [Client 34] Server address is "/run/cups/cups.sock".
D [30/Sep/2023:19:09:26 +0000] [Client 34] Accepted from localhost (Domain)
D [30/Sep/2023:19:09:26 +0000] [Client 34] Waiting for request.
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Active clients and dirty files", busy="Active clients and dirty files"
D [30/Sep/2023:19:09:26 +0000] [Client 35] Server address is "/run/cups/cups.sock".
D [30/Sep/2023:19:09:26 +0000] [Client 35] Accepted from localhost (Domain)
D [30/Sep/2023:19:09:26 +0000] [Client 35] Waiting for request.
D [30/Sep/2023:19:09:26 +0000] [Client 34] HTTP_STATE_WAITING Closing for error 32 (Broken pipe)
D [30/Sep/2023:19:09:26 +0000] [Client 34] Closing connection.
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Active clients and dirty files"
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Active clients and dirty files", busy="Dirty files"
D [30/Sep/2023:19:09:26 +0000] [Client 36] Server address is "/run/cups/cups.sock".
D [30/Sep/2023:19:09:26 +0000] [Client 36] Accepted from localhost (Domain)
D [30/Sep/2023:19:09:26 +0000] [Client 36] Waiting for request.
D [30/Sep/2023:19:09:26 +0000] [Client 35] HTTP_STATE_WAITING Closing for error 32 (Broken pipe)
D [30/Sep/2023:19:09:26 +0000] [Client 35] Closing connection.
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Active clients and dirty files"
D [30/Sep/2023:19:09:26 +0000] [Client 36] PUT /admin/conf/cupsd.conf HTTP/1.1
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Active clients and dirty files", busy="Dirty files"
D [30/Sep/2023:19:09:26 +0000] [Client 36] Read: status=200, state=9
D [30/Sep/2023:19:09:26 +0000] [Client 36] Authorized as root using PeerCred.
D [30/Sep/2023:19:09:26 +0000] cupsdIsAuthorized: username="root"
D [30/Sep/2023:19:09:26 +0000] [Client 36] AppArmor not in use.
D [30/Sep/2023:19:09:26 +0000] [Client 36] Read: status=100, state=9
I [30/Sep/2023:19:09:26 +0000] [Client 36] Installing config file "/etc/cups/cupsd.conf"...
localhost - root [30/Sep/2023:19:09:26 +0000] "PUT /admin/conf/cupsd.conf HTTP/1.1" 201 4726 - -
D [30/Sep/2023:19:09:26 +0000] [Client 36] cupsdSendHeader: code=201, type="(null)", auth_type=0
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Active clients and dirty files"
D [30/Sep/2023:19:09:26 +0000] [Client 36] Closing connection.
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Dirty files"
I [30/Sep/2023:19:09:26 +0000] Generating printcap /run/cups/printcap...
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Not busy", busy="Dirty files"
I [30/Sep/2023:19:09:26 +0000] Listening to [v1.::1]:631 (IPv6)
I [30/Sep/2023:19:09:26 +0000] Listening to 127.0.0.1:631 (IPv4)
I [30/Sep/2023:19:09:26 +0000] Listening to /run/cups/cups.sock (Domain)
I [30/Sep/2023:19:09:26 +0000] Remote access is disabled.
D [30/Sep/2023:19:09:26 +0000] Added auto ServerAlias airprint-bridge
I [30/Sep/2023:19:09:26 +0000] Loaded configuration file "/etc/cups/cupsd.conf"
D [30/Sep/2023:19:09:26 +0000] Using keychain "/etc/cups/ssl" for server name "airprint-bridge".
I [30/Sep/2023:19:09:26 +0000] Configured for up to 100 clients.
I [30/Sep/2023:19:09:26 +0000] Allowing up to 100 client connections per host.
I [30/Sep/2023:19:09:26 +0000] Using policy "default" as the default.
D [30/Sep/2023:19:09:26 +0000] cupsdMarkDirty(--p--)
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Not busy"
I [30/Sep/2023:19:09:26 +0000] Partial reload complete.
E [30/Sep/2023:19:09:26 +0000] Unable to open listen socket for address [v1.::1]:631 - Cannot assign requested address.
I [30/Sep/2023:19:09:26 +0000] Listening to 127.0.0.1:631 on fd 4...
I [30/Sep/2023:19:09:26 +0000] Listening to /run/cups/cups.sock on fd 5...
I [30/Sep/2023:19:09:26 +0000] Resuming new connection processing...
D [30/Sep/2023:19:09:26 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Dirty files"
D [30/Sep/2023:19:09:26 +0000] Discarding unused server-restarted event...
--> adding printers
CUPS_LPADMIN_PRINTER1 = 
--> CUPS configured
===========================================================
The dockerized CUPS instance is now ready for use! The web
interface is available here:
URL:       http://10.1.0.224:631/ or http://airprint-bridge:631/
Username:  "admin"
Password:  41rpr1nt
===========================================================
D [30/Sep/2023:19:09:34 +0000] cupsdSetBusyState: newbusy="Active clients and dirty files", busy="Dirty files"
D [30/Sep/2023:19:09:34 +0000] [Client 37] Server address is "127.0.0.1".
D [30/Sep/2023:19:09:34 +0000] [Client 37] Accepted from localhost:43158 (IPv4)
D [30/Sep/2023:19:09:34 +0000] [Client 37] Waiting for request.
D [30/Sep/2023:19:09:34 +0000] cupsdAddCert: Adding certificate for PID 0
D [30/Sep/2023:19:09:34 +0000] [Client 37] Connection now encrypted.
D [30/Sep/2023:19:09:34 +0000] [Client 37] HEAD /printers/ HTTP/1.1
D [30/Sep/2023:19:09:34 +0000] cupsdSetBusyState: newbusy="Active clients and dirty files", busy="Active clients and dirty files"
D [30/Sep/2023:19:09:34 +0000] [Client 37] Read: status=200, state=4
D [30/Sep/2023:19:09:34 +0000] [Client 37] No authentication data provided.
D [30/Sep/2023:19:09:34 +0000] [Client 37] cupsdSendHeader: code=200, type="(null)", auth_type=0
localhost - - [30/Sep/2023:19:09:34 +0000] "HEAD /printers/ HTTP/1.1" 200 0 - -
D [30/Sep/2023:19:09:34 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Active clients and dirty files"
D [30/Sep/2023:19:09:34 +0000] [Client 37] HTTP_STATE_WAITING Closing for error 32 (Broken pipe)
D [30/Sep/2023:19:09:34 +0000] [Client 37] Closing connection.
D [30/Sep/2023:19:09:34 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Dirty files"
D [30/Sep/2023:19:09:34 +0000] [Client 37] Waiting for socket close.
D [30/Sep/2023:19:09:34 +0000] [Client 37] Closing on EOF.
D [30/Sep/2023:19:09:34 +0000] [Client 37] Closing connection.
D [30/Sep/2023:19:09:34 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Dirty files"
D [30/Sep/2023:19:09:34 +0000] cupsdSetBusyState: newbusy="Active clients and dirty files", busy="Dirty files"
D [30/Sep/2023:19:09:34 +0000] [Client 38] Server address is "/run/cups/cups.sock".
D [30/Sep/2023:19:09:34 +0000] [Client 38] Accepted from localhost (Domain)
D [30/Sep/2023:19:09:34 +0000] [Client 38] Waiting for request.
D [30/Sep/2023:19:09:34 +0000] [Client 38] HTTP_STATE_WAITING Closing for error 32 (Broken pipe)
D [30/Sep/2023:19:09:34 +0000] [Client 38] Closing connection.
D [30/Sep/2023:19:09:34 +0000] cupsdSetBusyState: newbusy="Dirty files", busy="Active clients and dirty files"

This is my compose file:

version: '3.0'

networks:
  home_macvlan_machine-city:                         # Name of macvlan network
    external: true

services:
  airprint-bridge:
    container_name: airprint-bridge
    image: drpsychick/airprint-bridge
    hostname: ${HOSTNAME}
    #cap_add:
    #- NET_ADMIN
    networks:
      home_macvlan_machine-city:
        ipv4_address: ${CUPS_IP}
    #ports:
    #  - "137:137/udp"
    #  - "139:139/tcp"
    #  - "445:445/tcp"
    #  - "631:631/tcp"
    #  - "5353:5353/udp"
    environment:
      - CUPS_ADMIN_USER=${CUPS_ADMIN_USER:-"admin"}
      - CUPS_ADMIN_PASSWORD=${CUPS_ADMIN_PASSWORD:-"secr3t"}
      - CUPS_WEBINTERFACE=${CUPS_WEBINTERFACE:-"yes"}
      - CUPS_SHARE_PRINTERS=${CUPS_SHARE_PRINTERS:-"yes"}
      - CUPS_REMOTE_ADMIN=${CUPS_REMOTE_ADMIN:-"yes"} # allow admin from non local source
      - CUPS_ACCESS_LOGLEVEL=${CUPS_ACCESS_LOGLEVEL:-"all"} # all, access, config, see `man cupsd.conf`
      - CUPS_LOGLEVEL=${CUPS_LOGLEVEL:-"debug"} # error, warn, info, debug, debug2 see `man cupsd.conf`
      - CUPS_ENV_DEBUG=${CUPS_ENV_DEBUG:-"no"} # debug startup script and activate CUPS debug logging
      #- CUPS_IP=${CUPS_IP:-$(hostname -i)} # no need to set this usually
      #- CUPS_HOSTNAME=${CUPS_HOSTNAME:-$(hostname -f)} # no need to set this usually -> allows accessing cups via name: https://cups.domain:631/
      # pass the server cert/key via env in one line each, i.e. CUPS_SSL_CERT=---- BEGIN CERT ...\none\nline\nseparated\nby\nbackslash\nnewline
      #- CUPS_SSL_CERT=${CUPS_SSL_CERT:-""}
      #- CUPS_SSL_KEY=${CUPS_SSL_KEY:-""}
      # avahi configuration options
      - AVAHI_INTERFACES=${AVAHI_INTERFACES:-"eth0"}
      - AVAHI_IPV6=${AVAHI_IPV6:-"no"}
      - AVAHI_REFLECTOR=${AVAHI_REFLECTOR:-"no"}
      - AVAHI_REFLECT_IPV=${AVAHI_REFLECT_IPV:-"no"}
    ipc: shareable
    restart: unless-stopped
    deploy:
      placement:
        constraints: [node.hostname == machine-city]

Can anyone help with this?

How can I add a printer shared through an Airport Express?

Hi,

I try to make my Brother printer available via AirPrint. It's plugged via USB to an Airport Express which makes it appear on my network.
On my Macbook cups web ui, I can see the following information about it:

Description: | Brother HL-1110 series
Location: AirPort
Driver: Brother HL-1110 series CUPS (grayscale)
Connection: dnssd://Brother%20HL-1110%20series._riousbprint._tcp.local./Brother%20HL-1110%20series%20H3N343080
Defaults: job-sheets=none, none media=na_letter_8.5x11in sides=one-sided

But I can't figure out how I can add it to my cups AirPrint server. I already tried using the IP address of the Airport Express with lpadmin -p myprinter -E -v "ipp://192.168.1.146/ipp/print" (not sure how I can customize the /ipp/print at the end) and also using the dnssd uri from the previous description without success.
If you have any idea about that, I'll be happy to test it.
Thank you very much.

Container is crashing(realtime clock)

Hello, my container is crashing.

I have done created an docker compose file:
version: '2' services: cups: image: drpsychick/airprint-bridge:latest container_name: cups network_mode: host restart: unless-stopped volumes: - /home/pi/cups/config:/config - /home/pi/cups/services:/services environment: - CUPS_ADMIN_USER=admin - CUPS_ADMIN_PASSWORD=airprint_2846 - CUPS_WEBINTERFACE=yes - CUPS_REMOTE_ADMIN=yes

and when I execute docker-compose up on an raspberry pi I get the following error:
sleep: cannot read realtime clock: Operation not permitted

Does anyone know what I am doing wrong?

update avahi service file for Location field

couple of updates.

I think will be nice to drop the "Airpint %s @ host" to just %s

                name = tree.find('name')
                name.text = '%s' % (v['printer-info'])

This uses the printer-info which is a human friendly descriptions which is specified in the -d for cups. Maybe we can make this configureable if you want to use name.text = '%s' % (v['printer-info']) or name.text = 'Airprint %s' @ %%h' % (v['printer-info'])

As well as use the correct location field for the note which is shown as location on most devices.

                desc = Element('txt-record')
                desc.text = 'note=%s' % (v['printer-location'])

"AirPrint" Prefix: Customization Options (enable/disable/change)

I was wondering if it's possible to customize the "AirPrint" prefix for shared printers.

If possible at all, It would be useful to determine a custom prefix or to be able to enable/disable the prefix at all.

Thanks in advance for any hint on the matter.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.