Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SANE issues inside container #129

Closed
MrksHfmn opened this issue Feb 17, 2021 · 33 comments
Closed

SANE issues inside container #129

MrksHfmn opened this issue Feb 17, 2021 · 33 comments

Comments

@MrksHfmn
Copy link

I use the docker container without --privileged and direct my scanner via /dev/bus/usb into the container. It is also found in the container, but I cannot run scanimage -L. Outside the container (on my server) everything works.

root@HOME-SERVER:[scanservjs]> docker exec -u root -it scanservjs /bin/bash


root@fd1c40a0443d:/app# sane-find-scanner

  # sane-find-scanner will now attempt to detect your scanner. If the
  # result is different from what you expected, first make sure your
  # scanner is powered up and properly connected to your computer.

  # No SCSI scanners found. If you expected something different, make sure that
  # you have loaded a kernel SCSI driver for your SCSI adapter.
  # Also you need support for SCSI Generic (sg) in your operating system.
  # If using Linux, try "modprobe sg".

could not open USB device 0x1d6b/0x0003 at 002:001: No such device (it may have been disconnected)
could not open USB device 0x1cf1/0x0030 at 001:028: No such device (it may have been disconnected)
found USB scanner (vendor=0x04a9 [Canon], product=0x1913 [LiDE 300]) at libusb:001:031
could not open USB device 0x1d6b/0x0002 at 001:001: No such device (it may have been disconnected)
  # Your USB scanner was (probably) detected. It may or may not be supported by
  # SANE. Try scanimage -L and read the backend's manpage.

  # Not checking for parallel port scanners.

  # Most Scanners connected to the parallel port or other proprietary ports
  # can't be detected by this program.


root@ce4356d6687d:/app# scanimage -L

No scanners were identified. If you were expecting something different,
check that the scanner is plugged in, turned on and detected by the
sane-find-scanner tool (if appropriate). Please read the documentation
which came with this software (README, FAQ, manpages).

docker-compose.yaml

version: '3.7'

services:
  docker-scanservjs:
    restart: unless-stopped
    container_name: scanservjs
    image: "sbs20/scanservjs:latest"
    devices:
      - /dev/bus/usb/001/031:/dev/bus/usb/001/031
    volumes:
      - /mnt/storage/docker/scans:/app/data/output
    networks:
      - scanservjs
    ports:
      - "8383:8080"


networks:
  scanservjs:
    external: true
@sbs20
Copy link
Owner

sbs20 commented Feb 17, 2021

Hi. Just a few diagnostics questions:

  • Does it work if you use --privileged?
  • What is the result of running scanimage -L on the docker host (i.e. outside the container)?
  • Can you use the device name inside the container? e.g. (you will need to get your own device, I've guessed) scanimage -d 'plustek:libusb:001:031' -A?

@sbs20 sbs20 changed the title Scanimage not working with --device SANE issues inside container Feb 17, 2021
@RafaelSchridi
Copy link

I've got the same issue with a LiDE 400 running on Arch.

sudo docker run -d -p 8070:8080 -v /var/run/dbus:/var/run/dbus --privileged --name scanservjs sbs20/scanservjs:latest

on host

scanimage -L
device `pixma:04A91912_455B2F' is a CANON CanoScan LiDE 400 multi-function peripheral

on docker

[2021-03-15T22:08:49.090Z] DEBUG (Http): request:  { method: 'POST', path: '/preview' }
[2021-03-15T22:08:49.091Z] DEBUG (Devices): devices.json contains no devices. Reloading
[2021-03-15T22:08:49.091Z] DEBUG (Devices): Config.devices:  []
[2021-03-15T22:08:49.091Z] DEBUG (CmdBuilder): build() /usr/bin/scanimage -L
[2021-03-15T22:08:57.671Z] DEBUG (Devices): Device list:  
No scanners were identified. If you were expecting something different,
check that the scanner is plugged in, turned on and detected by the
sane-find-scanner tool (if appropriate). Please read the documentation
which came with this software (README, FAQ, manpages).

[2021-03-15T22:08:57.672Z] ERROR (Http): TypeError: Cannot read property 'features' of undefined
    at Function.readPreview (/app/server/api.js:90:34)
    at processTicksAndRejections (node:internal/process/task_queues:94:5)
    at async /app/server/configure.js:109:22

@RafaelSchridi
Copy link

Turns out i forgot to install and start ipp-usb
But now I get this

[2021-03-15T22:29:11.023Z] DEBUG (CmdBuilder): build() /usr/bin/scanimage -L
[2021-03-15T22:29:19.438Z] DEBUG (Devices): Device list:  device `airscan:e0:Canon LiDE 400 (USB)' is a eSCL Canon LiDE 400 (USB) ip=127.0.0.1

[2021-03-15T22:29:19.439Z] DEBUG (CmdBuilder): build() /usr/bin/scanimage -d 'airscan:e0:Canon LiDE 400 (USB)' -A
[2021-03-15T22:29:20.465Z] ERROR (Http): Error: Command failed: /usr/bin/scanimage -d 'airscan:e0:Canon LiDE 400 (USB)' -A
scanimage: open of device airscan:e0:Canon LiDE 400 (USB) failed: Error during device I/O

    at ChildProcess.exithandler (node:child_process:327:12)
    at ChildProcess.emit (node:events:378:20)
    at maybeClose (node:internal/child_process:1067:16)
    at Process.ChildProcess._handle.onexit (node:internal/child_process:301:5) {
  killed: false,
  code: 1,
  signal: null,
  cmd: "/usr/bin/scanimage -d 'airscan:e0:Canon LiDE 400 (USB)' -A",
  stdout: '',
  stderr: 'scanimage: open of device airscan:e0:Canon LiDE 400 (USB) failed: Error during device I/O\n'
  }

@sbs20
Copy link
Owner

sbs20 commented Mar 15, 2021

What happens if you run

/usr/bin/scanimage -d 'airscan:e0:Canon LiDE 400 (USB)' -A

On the host?

@RafaelSchridi
Copy link

[rafael ~] $/usr/bin/scanimage -d 'airscan:e0:Canon LiDE 400 (USB)' -A
Output format is not set, using pnm as a default.

All options specific to device `airscan:e0:Canon LiDE 400 (USB)':
  Standard:
    --resolution 75|100|150|200|300|600|1200|2400|4800dpi [300]
        Sets the resolution of the scanned image.
    --mode Color|Gray [Color]
        Selects the scan mode (e.g., lineart, monochrome, or color).
    --source Flatbed [Flatbed]
        Selects the scan source (such as a document-feeder).
  Geometry:
    -l 0..215.9mm [0]
        Top-left x position of scan area.
    -t 0..297.011mm [0]
        Top-left y position of scan area.
    -x 0..215.9mm [215.9]
        Width of scan-area.
    -y 0..297.011mm [297.011]
        Height of scan-area.
  Enhancement:
    --brightness -100..100% (in steps of 1) [0]
        Controls the brightness of the acquired image.
    --contrast -100..100% (in steps of 1) [0]
        Controls the contrast of the acquired image.
    --shadow 0..100% (in steps of 1) [0]
        Selects what radiance level should be considered "black".
    --highlight 0..100% (in steps of 1) [100]
        Selects what radiance level should be considered "white".
    --analog-gamma 0.0999908..4 [1]
        Analog gamma-correction
    --negative[=(yes|no)] [no]
        Swap black and white

@sbs20
Copy link
Owner

sbs20 commented Mar 15, 2021

Thanks for that. So we know it's something about running that command inside docker which isn't working. The bad news is it's at the outer limits of what I know about docker and Arch. I have had intermittent issues with airscan and IO errors but it usually works again with a second try. And it's presumably not a permissions problem since it can see the scanner and you're running privileged. Can you think of any other tests to find the cause?

@RafaelSchridi
Copy link

So I gave up on trying to passtrough USB and just set up SaneOverNetwork and it's working great now!

@sbs20
Copy link
Owner

sbs20 commented Mar 16, 2021

Interesting - and thank you for coming back. Just so that I can try and understand (and document it) - what was the configuration you were trying? e.g.

Scanner connected by USB to the host, but you were using IPP over USB to connect to the Scanner? Did it not work as a native USB connection with udev?

@MrksHfmn
Copy link
Author

sorry, had no time to report back ... unfortunately it's not working (even with privileged). Here is my compose file and some container logs.

The printer is connected via usb:

lsusb
Bus 001 Device 004: ID 04a9:1913 Canon, Inc. LiDE 300
scanserverjs         | node ./server/server.js
scanserverjs         | + node ./server/server.js
scanserverjs         | [2021-03-16T12:07:38.961Z] INFO (server): Started
scanserverjs         | [2021-03-16T12:09:57.439Z] DEBUG (Http): request:  { method: 'GET', path: '/files' }
scanserverjs         | [2021-03-16T12:09:57.442Z] DEBUG (Api): fileList()
scanserverjs         | [2021-03-16T12:09:59.285Z] DEBUG (Http): request:  { method: 'GET', path: '/context', params: { force: undefined } }
scanserverjs         | [2021-03-16T12:09:59.285Z] DEBUG (Devices): devices.json does not exist. Reloading
scanserverjs         | [2021-03-16T12:09:59.286Z] DEBUG (Devices): Config.devices:  []
scanserverjs         | [2021-03-16T12:09:59.286Z] DEBUG (CmdBuilder): build() /usr/bin/scanimage -L
scanserverjs         | [2021-03-16T12:10:07.218Z] DEBUG (Devices): Device list:  device `airscan:e0:Canon LiDE 300 (USB)' is a eSCL Canon LiDE 300 (USB) ip=127.0.0.1
scanserverjs         |
scanserverjs         | [2021-03-16T12:10:07.219Z] DEBUG (CmdBuilder): build() /usr/bin/scanimage -d 'airscan:e0:Canon LiDE 300 (USB)' -A
scanserverjs         | [2021-03-16T12:10:08.290Z] ERROR (Http): Error: Command failed: /usr/bin/scanimage -d 'airscan:e0:Canon LiDE 300 (USB)' -A
scanserverjs         | scanimage: open of device airscan:e0:Canon LiDE 300 (USB) failed: Error during device I/O
scanserverjs         |
scanserverjs         |     at ChildProcess.exithandler (node:child_process:327:12)
scanserverjs         |     at ChildProcess.emit (node:events:378:20)
scanserverjs         |     at maybeClose (node:internal/child_process:1067:16)
scanserverjs         |     at Process.ChildProcess._handle.onexit (node:internal/child_process:301:5) {
scanserverjs         |   killed: false,
scanserverjs         |   code: 1,
scanserverjs         |   signal: null,
scanserverjs         |   cmd: "/usr/bin/scanimage -d 'airscan:e0:Canon LiDE 300 (USB)' -A",
scanserverjs         |   stdout: '',
scanserverjs         |   stderr: 'scanimage: open of device airscan:e0:Canon LiDE 300 (USB) failed: Error during device I/O\n'
cat docker-compose.yaml
---
version: '3.8'

services:
  docker-scanservjs:
    restart: unless-stopped
    container_name: scanserverjs
    image: sbs20/scanservjs:latest
    privileged: true
    volumes:
      - /var/run/dbus:/var/run/dbus
      - /mnt/storage/docker/scans:/app/data/output
    networks:
      - scanservjs
    ports:
      - 8822:8080


networks:
  scanservjs:
    external: true

1 similar comment
@MrksHfmn
Copy link
Author

sorry, had no time to report back ... unfortunately it's not working (even with privileged). Here is my compose file and some container logs.

The printer is connected via usb:

lsusb
Bus 001 Device 004: ID 04a9:1913 Canon, Inc. LiDE 300
scanserverjs         | node ./server/server.js
scanserverjs         | + node ./server/server.js
scanserverjs         | [2021-03-16T12:07:38.961Z] INFO (server): Started
scanserverjs         | [2021-03-16T12:09:57.439Z] DEBUG (Http): request:  { method: 'GET', path: '/files' }
scanserverjs         | [2021-03-16T12:09:57.442Z] DEBUG (Api): fileList()
scanserverjs         | [2021-03-16T12:09:59.285Z] DEBUG (Http): request:  { method: 'GET', path: '/context', params: { force: undefined } }
scanserverjs         | [2021-03-16T12:09:59.285Z] DEBUG (Devices): devices.json does not exist. Reloading
scanserverjs         | [2021-03-16T12:09:59.286Z] DEBUG (Devices): Config.devices:  []
scanserverjs         | [2021-03-16T12:09:59.286Z] DEBUG (CmdBuilder): build() /usr/bin/scanimage -L
scanserverjs         | [2021-03-16T12:10:07.218Z] DEBUG (Devices): Device list:  device `airscan:e0:Canon LiDE 300 (USB)' is a eSCL Canon LiDE 300 (USB) ip=127.0.0.1
scanserverjs         |
scanserverjs         | [2021-03-16T12:10:07.219Z] DEBUG (CmdBuilder): build() /usr/bin/scanimage -d 'airscan:e0:Canon LiDE 300 (USB)' -A
scanserverjs         | [2021-03-16T12:10:08.290Z] ERROR (Http): Error: Command failed: /usr/bin/scanimage -d 'airscan:e0:Canon LiDE 300 (USB)' -A
scanserverjs         | scanimage: open of device airscan:e0:Canon LiDE 300 (USB) failed: Error during device I/O
scanserverjs         |
scanserverjs         |     at ChildProcess.exithandler (node:child_process:327:12)
scanserverjs         |     at ChildProcess.emit (node:events:378:20)
scanserverjs         |     at maybeClose (node:internal/child_process:1067:16)
scanserverjs         |     at Process.ChildProcess._handle.onexit (node:internal/child_process:301:5) {
scanserverjs         |   killed: false,
scanserverjs         |   code: 1,
scanserverjs         |   signal: null,
scanserverjs         |   cmd: "/usr/bin/scanimage -d 'airscan:e0:Canon LiDE 300 (USB)' -A",
scanserverjs         |   stdout: '',
scanserverjs         |   stderr: 'scanimage: open of device airscan:e0:Canon LiDE 300 (USB) failed: Error during device I/O\n'
cat docker-compose.yaml
---
version: '3.8'

services:
  docker-scanservjs:
    restart: unless-stopped
    container_name: scanserverjs
    image: sbs20/scanservjs:latest
    privileged: true
    volumes:
      - /var/run/dbus:/var/run/dbus
      - /mnt/storage/docker/scans:/app/data/output
    networks:
      - scanservjs
    ports:
      - 8822:8080


networks:
  scanservjs:
    external: true

@MrksHfmn
Copy link
Author

So I gave up on trying to passtrough USB and just set up SaneOverNetwork and it's working great now!

Can you give a short description how to set it up?

@RafaelSchridi
Copy link

Interesting - and thank you for coming back. Just so that I can try and understand (and document it) - what was the configuration you were trying? e.g.

Scanner connected by USB to the host, but you were using IPP over USB to connect to the Scanner? Did it not work as a native USB connection with udev?

My config was just very simply

sudo docker run -d -p 8070:8080 -v /var/run/dbus:/var/run/dbus --privileged --name scanservjs sbs20/scanservjs:latest

The reason for installing ipp-usb was because the arch wiki mentioned it being required on some printers, don't know if that was the issue that fixed my first problem, but that was the last thing I did.

@sbs20
Copy link
Owner

sbs20 commented Mar 16, 2021

That's odd. I don't understand why a USB device is being reported as airscan - not that I don't believe it's happening, obviously, just that I don't observe that behaviour.

I suspect that this is a matter of sharing the scanner on the host and using the network to connect from the docker container. This might help where server = host and client = docker. Although the comment above from @RafaelSchridi suggests maybe not.

@RafaelSchridi
Copy link

So I gave up on trying to passtrough USB and just set up SaneOverNetwork and it's working great now!

Can you give a short description how to set it up?

version: '3.3'
services:
    scanservjs:
        ports:
            - '8070:8080'
        environment:
            - SANED_NET_HOSTS=10.0.2.100
        volumes:
            - 'mydir:/app/data/output'
            - 'mydir2:/app/config'
        container_name: scanservjs
        image: sbs20/scanservjs:latest

In /etc/sane.d/saned.conf add your subnets to the Access list (also had to add 172.16.0.0/12 which docker uses internally)

Start & enable saned.socket and you're all good

@RafaelSchridi
Copy link

That's odd. I don't understand why a USB device is being reported as airscan - not that I don't believe it's happening, obviously, just that I don't observe that behaviour.

I suspect that this is a matter of sharing the scanner on the host and using the network to connect from the docker container. This might help where server = host and client = docker. Although the comment above from @RafaelSchridi suggests maybe not.

Airscan Is just a scanner working in driverless mode right? from the arch wiki:

Install the sane-airscan package if the scanner is known to work in driverless mode. If your scanner is using USB connection, make sure to also install the ipp-usb package and start/enable ipp-usb.service to allow using IPP protocol over USB connection.

@sbs20
Copy link
Owner

sbs20 commented Mar 16, 2021

Airscan Is just a scanner working in driverless mode right? from the arch wiki

Ahh, thank you. I've only used it to connect to a scanner wirelessly - that makes sense. The current container has its own install of sane-airscan - I wonder if that's conflicting in some way. Or perhaps something additional needs to be shared from host to container in this configuration (with USB). I don't have a way of testing this at the moment, which doesn't help.

@RafaelSchridi
Copy link

Honestly I'm way more conformable with my current setup with scanservjs just being a client and not having to run in privileged mode.

@MrksHfmn
Copy link
Author

Working now over network, thank you!
This guide was also helpful: https://feeding.cloud.geek.nz/posts/setting-up-a-network-scanner-using-sane/
the usb device (/dev/bus/usb/1/4) and the saned user need to be in the scanner group.

@MrksHfmn
Copy link
Author

So I gave up on trying to passtrough USB and just set up SaneOverNetwork and it's working great now!

Can you give a short description how to set it up?

version: '3.3'
services:
    scanservjs:
        ports:
            - '8070:8080'
        environment:
            - SANED_NET_HOSTS=10.0.2.100
        volumes:
            - 'mydir:/app/data/output'
            - 'mydir2:/app/config'
        container_name: scanservjs
        image: sbs20/scanservjs:latest

In /etc/sane.d/saned.conf add your subnets to the Access list (also had to add 172.16.0.0/12 which docker uses internally)

Start & enable saned.socket and you're all good

Thank you! A bit off topic, but can you use the scanner from other machines? Windows or mobile devices? if so, which drivers do i need?

@sbs20
Copy link
Owner

sbs20 commented Mar 17, 2021

Thank you! A bit off topic, but can you use the scanner from other machines? Windows or mobile devices? if so, which drivers do i need?

Do you mean use SANE directly from Windows or Mobile? If so then you could have a look at sane-frontends - I think the options are limited. But unless I'm missing something, the point of this project is to allow sharing on the network from any web browser - can't you just use this?

@sbs20
Copy link
Owner

sbs20 commented Apr 12, 2021

I've updated the documentation around this. And further have come to the conclusion that the docker container should focus on the app itself rather than the SANE backends. The solution outlined above (using the host as the backend and connecting over the network) is now the recommended approach.

@AlexKalopsia
Copy link

AlexKalopsia commented Sep 20, 2021

Has anyone managed to set AirScan up on Synology NAS?

I have installed the SANE Backends package, I check the package log (which is located in /var/packages/sane-backends/target/var nano sane-find-scanner.log and it correctly detects my scanner:

device `epson2:net:192.168.1.300' is a Epson PID 110C flatbed scanner

I also edited the config file (located in /var/packages/sane-backends/target/etc/sane.d/saned.conf and in the ##Access list i included

192.168.1.300 # Scanner IP
172.31.0.1 # Container Gateway
172.31.0.2 # Container IP
192.168.16.0/20 # Container Network IPV4 Subnet
# I am literally trying everything

In the docker-compose I also set - SANED_NET_HOSTS="192.168.1.300" (but I also tried putting the IP of my NAS which is running the SANE Backends)

Still, I keep getting Device not found

@sbs20
Copy link
Owner

sbs20 commented Sep 21, 2021

Hi. It's difficult to tell what you're trying to do. But I'll take a guess.

But first, in epson2:net:192.168.1.300, 192.168.1.300 is not a valid IP address - but maybe you changed that just for reporting. Let's assume that the real value is: epson2:net:192.168.1.30.

The best way to use docker is using a net backend. That means you have:

The scanner (epson) <--> SANE backend (synology) <--> scanner client (SANE front end / scanservjs).

Your backend can talk to your scanner, which is good. Now you need to say which clients are allowed to access your server. This will be your docker container. 172.31.0.0/16 should do the trick but if you want to allow EVERYTHING (purely for testing) then try 0.0.0.0/0. This needs to go into saned.conf. You also need to ensure saned is enabled and running:

sudo systemctl enable saned.socket
sudo systemctl start saned.socket

Then, in your client (scanservjs) you need to point it at your synology. I don't know what the IP is of your synology but it won't be the same as your scanner. This is specified in SANED_NET_HOSTS but ends up in net.conf.

That way, scanservjs will request a scan from the synology, which will forward the request to the epson.

@AlexKalopsia
Copy link

AlexKalopsia commented Sep 29, 2021

Thanks for the detailed information, this is pretty much what I thought was the overall setup.

It seems like on Synology you don't have access to the systemctl command, is there any other way I could make sure saned is enabled and running (other than seeing that the SANE Backends package seems to be running)?


to clarify:

  • NAS: 192.168.1.30
  • Scanner: 192.168.1.20
  • Container: 192.168.32.1
  • Checking the logs: device epson2:net:192.168.1.20 is a Epson PID 110C flatbed scanner
  • Container env: SANED_NET_HOSTS="192.168.1.30"
  • net.conf: 192.168.1.30
  • saned.conf: 192.168.32.0/16

I still get Device not found

@sbs20
Copy link
Owner

sbs20 commented Sep 29, 2021

Sorry - I'm afraid my knowledge of how everything hangs together on a Synology is too limited. It may be worth investigating saned synology on synology forums to see how others do it. It may require install dbus with ipkg or something. Sorry not to be more help.

@AlexKalopsia
Copy link

Ok, i'll investigate further, thanks. Still, from the official docs, I read

 environment:
      # ----- specify network scanners here; see above for more possibilities -----
      - SANED_NET_HOSTS="10.0.100.30"

This seems to suggest that I should put the scanner IP here?

@sbs20
Copy link
Owner

sbs20 commented Sep 29, 2021

Yes, the guide presupposes that the host system has saned running.

@AlexKalopsia
Copy link

This is where I get confused. From what I understand

scanservjs => Scanner <=> NAS

  • The scanservjs container needs to connect to the Scanner
  • To expose the scanner, I run SANE on the NAS
  • NAS detects network scanner
  • scanservjs talks to the scanner via the NAS

If this is the case, then the scanservjs container should point (as you originally suggested) to the NAS, but the docs suggest that it should point directly to the scanner?

I realize I have a lot of questions, thanks for the help so far ^^

@sbs20
Copy link
Owner

sbs20 commented Sep 29, 2021

You're essentially correct but I would change it to

scanservjs => scanimage => sane-backend (NAS) => Scanner

Note that I am not a SANE expert. I am going to remove any mention of scanservjs in favour of scanimage - as scanservjs is just a web wrapper for scanimage.

  • scanimage is a sane front end
  • sane back ends take requests from sane front ends and translate the input requests and output responses into something the scanner itself can understand.
  • You can create a "pretend" sane backend which just proxies requests over a network to the "real" backend - these go in net.conf. The "real" backend is just another backend which is listening over a socket.
  • Now imagine Scanner A, which is an old USB scanner connected to a server running SANE as a backend. The scanner itself has no IP address - it's not a network entity. It's a device attached to a server - Server A.
  • Server A can (and in all likelihood will, since it's 2021) have a network connection.
  • Now imagine Scanner B, which is a more modern MFD which has its own network address - an IP address - either wireless or wired. In this case, Scanner B is a network device.
  • scanimage makes a request to its backend. The backend routes the request according to the device specified.
  • If we run scanimage on Server A then the backend just communicates directly with the device.
  • But we could run scanimage on Server X (another device) and point it at Server A which has the USB Scanner A attached. We have turned the crufty old USB scanner into a network scanner.
  • Or we can run scanimage on Server X and point it directly at Scanner B - this typically uses "driverless" mode and requires airscan which installs itself as another backend.

When the docs say:

# ----- specify network scanners here; see above for more possibilities -----

it's referring to Server A - a SANE backend with a scanner behind it. And that's referred to - perhaps ambiguously - as a "Network Scanner". It should perhaps say "Specify SANE backends here".

It is possible to connect DIRECT to actual network scanners (like Scanner B) using Airscan. But docker complicates everything because it's all running at a fairly low hardware level which requires mapping all sorts of additional things. So my usual recommendation is to keep the docker part light and just use a network connection out to another SANE backend outside the container.

Does that help?

@whysthatso
Copy link

one more little tip to add here for future reference:
pin the subnet of your container's network config, as these tend to change and it might go out of sync with your saned.conf

i.e. in your compose file, make networks explicit like so:

networks:
  scanservjs:
    ipam:
      driver: default
      config:
        - subnet: 192.168.128.0/20
          gateway: 192.168.128.1

services:
  app
    image: sbs20/scanservjs
    environment:
      - SANED_NET_HOSTS=<your scanner's host ip>
    networks:
      - scanservjs

and on your hosts saned.conf

192.168.128.0/20

@robertozanasi
Copy link

Hello, I'm trying to use scanservjs with my Canon Pixma MX920 printer/scanner.

On the host system, scanimage -L reports this:

device `pixma:MX920_192.168.1.5' is a CANON Canon PIXMA MX920 Series multi-function peripheral
device `airscan:w0:Canon MX920 series' is a WSD Canon MX920 series ip=192.168.1.5

And airscan-discover this:

[devices]
  Canon MX920 series = http://192.168.1.5:80/wsd/scanservice.cgi, WSD
  Canon MX920 series = http://[fe80::fa0d:60ff:feca:b636%252]:80/wsd/scanservice.cgi, WSD

I have tried with the following docker-compose.yml file:

version: "3"
services:
  scanservjs:
    build:
      context: .
      args:
        # ----- enter UID and GID here -----
        # UID: 1034
        GID: 1000
        # target: scanservjs-user2001
    container_name: scanservjs
    image: sbs20/scanservjs:latest
    environment:
      # ----- specify network scanners here; see above for more possibilities -----
      - SANED_NET_HOSTS="192.168.1.20"
      #- DEVICES="pixma:MX920_192.168.1.5"
      #- DEVICES="airscan:w0:Canon MX920 series"
      #- AIRSCAN_DEVICES='Canon MX920 series = http://192.168.1.5:80/wsd/scanservice.cgi'
    volumes:
      # ---- enter your target location for scans before the ':' character -----
      - ./scans:/app/data/output
      - ./config:/app/config
      - /var/run/dbus:/var/run/dbus

    ports:
      - 8090:8080
    restart: unless-stopped

I have also tried all the now commented out lines, but scanservjs is not able to find the scanner.

In /etc/sane.d/sane.conf I have two addresses:

192.168.1.0/24
172.21.0.0/16

and I have enabled and started saned.socket, but with no succes.

What should I do?

Thanks in advance.

@remus-selea
Copy link

remus-selea commented Jul 15, 2023

Previous attempts I tried to get this working as a Docker containers inside an Unpriviledged LXC on a Proxmox Host.

Approach 1

I tried the approach with the network that users such as whysthatso mentioned.

Inside the unpriviledged LXC:
Step 1: Install sane-utils

Open a terminal and run the following command to install the necessary SANE utilities:

sudo apt-get install sane-utils

Step 2: Navigate to the scanner driver directory

Change to the directory where you have saved the scanner driver package. In this example, the path is "/mnt/host-data/data/software/drivers/Brother DCP-1610W/Scanner driver 64bit/". You can use the cd command to navigate to the directory. Here's an example:

cd "/mnt/host-data/data/software/drivers/Brother DCP-1610W/Scanner driver 64bit/"

Step 3: Install the scanner driver

Install the scanner driver package using the dpkg command. Run the following command:

sudo dpkg -i brscan4-0.4.11-1.amd64.deb

Step 4: Configure the scanner

Configure the scanner by running the following command. Replace "Scanner" with the desired name, "DCP-1610W" with the correct model, and set the IP address according to your scanner:

sudo brsaneconfig4 -a name=Scanner model=DCP-1610W ip=192.168.30.10

Step 5: Verify the scanner

To check if the scanner is detected, run the following command:

sudo scanimage -L

This command will scan for connected scanners and display the detected scanners. If the scanner is detected without any errors, the installation was successful.

Modified sane.conf: 172.29.0.0/16 and added 0.0.0.0/0 just to test if I can connect to it.

sudo systemctl status saned.socket
* saned.socket - saned incoming socket
     Loaded: loaded (/lib/systemd/system/saned.socket; enabled; vendor preset: enabled)
     Active: active (listening) since Sat 2023-07-15 18:48:31 EEST; 5min ago
     Listen: [::]:6566 (Stream)
   Accepted: 0; Connected: 0;
     CGroup: /system.slice/saned.socket

saned.socket seemed to be working, But saned wasn't working. I tried rebooting, stopping ,enabling, starting numerous times. Tried ChatGTP approaches, without any success.

sudo systemctl status saned
* saned.service
     Loaded: masked (Reason: Unit saned.service is masked.)
     Active: inactive (dead)

Even so I was able to scan inside the unpviviledged LXC. scanimage -L output on LXC: device 'brother4:net1;dev0' is a Brother Scanner DCP-1610W

But I wasn't able to get the docker container to connect to the on LXC, likely because it depends on saned?
I was getting No scanners were identified in the docker container.

The docker compose:

version: "3"
services:
  scanservjs:
    image: 'sbs20/scanservjs:latest'
    container_name: scanservjs
    environment:
      # ----- specify network scanners here; see above for more possibilities -----
      - SANED_NET_HOSTS="192.168.10.12" # LXC IP address
      #- 'AIRSCAN_DEVICES="Brother DCP-1610W" = "http://192.168.30.10/eSCL";"Brother DCP-1610W" = "http://192.168.30.10/wsd/scanservice.cgi"' # this didn't work either btw, probably the printer doesn't support this
    volumes:
      - /srv/compose/syncthing/syncthing/data/documents/paperless-consume:/app/data/output
      - ./config:/app/config
    ports:
      - 8080:8080
    restart: unless-stopped
    networks:
      - proxy-network
      - scanservjs


networks:
  scanservjs:
    name: scanservjs
    ipam:
      config:
        - subnet: 172.29.0.0/16
  proxy-network:
    external: true

I suspect it doesn't work on unpriviledged LXCs for some reason but I don't know why.

Approach 2

As the documentation specifies in https://github.com/sbs20/scanservjs/blob/master/docs/docker.md#hosting-it-on-a-synology-nas-using-docker

I tried to build the docker image inside my unpriviledged LXC but I was getting an error when running

[+] Running 0/1
 ⠿ Container scanservjs  Starting                                                                                                                                0.7s
Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/app/bin/scanservjs": stat /app/bin/scanservjs: no such file or directory: unknown
version: "3"
services:
  scanservjs:
    build:
      context: .
      args:
        # ----- enter UID and GID here -----
        UID: 1000
        GID: 1000
      target: scanservjs-user2001
    container_name: scanservjs
    environment:
      # ----- specify network scanners here; see above for more possibilities -----
      - SANED_NET_HOSTS="192.168.30.10"
    volumes:
      - /srv/compose/syncthing/syncthing/data/documents/paperless-consume:/app/data/output
      - ./config:/app/config
    ports:
      - 8080:8080
    restart: unless-stopped
    networks:
      - proxy-network
    
networks:
  proxy-network:
    external: true

After a while I gave up in this approach as well...

Approach 3

I decided to try cloning the project, master branch and to build the image, without any modifications.

But I was getting this error in the container logs when running it, and also red toast notifications in the UI with this error:

node ./server/server.js
+ node ./server/server.js
[2023-07-15T19:18:03.671Z] INFO (server): scanservjs started listening: https://:::8080
[2023-07-15T19:18:26.740Z] INFO (Http): { method: 'GET', path: '/context' }
[2023-07-15T19:18:26.742Z] INFO (Application): devices.json does not exist. Reloading
[2023-07-15T19:18:26.742Z] INFO (Process): { execute: '/usr/bin/scanimage -L' }
[2023-07-15T19:18:26.956Z] ERROR (Http): Error: Command failed: /usr/bin/scanimage -L
dbus[23]: arguments to dbus_connection_send() were incorrect, assertion "connection != NULL" failed in file ../../../dbus/dbus-connection.c line 3307.
This is normally a bug in some application using the D-Bus library.
  D-Bus not built with -rdynamic so unable to print a backtrace
Aborted (core dumped)
    at ChildProcess.exithandler (node:child_process:402:12)
    at ChildProcess.emit (node:events:513:28)
    at maybeClose (node:internal/child_process:1100:16)
    at Socket.<anonymous> (node:internal/child_process:458:11)
    at Socket.emit (node:events:513:28)
    at Pipe.<anonymous> (node:net:301:12) {
 
  code: 134,
  killed: false,
  signal: null,
  cmd: '/usr/bin/scanimage -L',
  stdout: '',
  stderr: 'dbus[23]: arguments to dbus_connection_send() were incorrect, assertion "connection != NULL" failed in file ../../../dbus/dbus-connection.c line 3307.\n' +
    'This is normally a bug in some application using the D-Bus library.\n' +
    '\n' +
    '  D-Bus not built with -rdynamic so unable to print a backtrace\n' +
    'Aborted (core dumped)\n'
}
[2023-07-15T19:18:26.965Z] INFO (Http): { method: 'GET', path: '/preview' }
[2023-07-15T19:18:26.967Z] INFO (Application): devices.json does not exist. Reloading
[2023-07-15T19:18:26.967Z] INFO (Process): { execute: '/usr/bin/scanimage -L' }

I thought maybe it's some update in the latest version, so I checked out the v2.27.0 and built the image again, but got the same error as above. The official image doesn't give me this error for some reason. image: 'sbs20/scanservjs:latest', but there I just cannot install the brother drivers,

I was hoping to build it, have it working and then afterwards add this at the end of the Dockerfile to add support for my printer.

# CUSTOM DRIVER INSTALL

#COPY ./brscan4-0.4.11-1.amd64.deb "$APP_DIR/brscan4-0.4.11-1.amd64.deb"
#RUN apt-get update && apt-get install -y "$APP_DIR/brscan4-0.4.11-1.amd64.deb" 
#RUN brsaneconfig4 -a name=Scanner model=DCP-1610W ip=192.168.30.10

If this worked then I hoped that scanimage in the Docker container could connect directly to the printer, without having to use anything from the LXC, because it's not possible to get it running there (masked (Reason: Unit saned.service is masked. see approach 1)

At this point I just gave up completely. If anyone knows how to get this running in Docker which runs in an Unpriviledged LXC, on a Proxmox host, I'd be happy to hear about it. I refuse to install scanservjs on the LXC itself or in a VM, as I want everything possible to run as a docker (or podman) container.

I managed to get it working by building it locally from the tag v2.27.0.

version: "3"
services:
  scanservjs:
    build:
      context: ./scanservjs
      args:
        # ----- enter UID and GID here -----
        UID: 1000
        GID: 1000
      target: scanservjs-user2001
    container_name: scanservjs
    #environment:
      # ----- specify network scanners here; see above for more possibilities -----
      # - SANED_NET_HOSTS="192.168.30.10"
    volumes:
      - /srv/compose/syncthing/syncthing/data/documents/paperless-consume:/app/data/output
      - ./config:/app/config
    #ports:
      #- 8080:8080
    restart: unless-stopped
    networks:
      - proxy-network

networks:
  proxy-network:
    external: true

I modified the Dockerfile and added 3 lines.

RUN groupadd -g $GID -o $UNAME \
  && useradd -o -u $UID -g $GID -m -s /bin/bash $UNAME \
  && chown -R $UID:$GID /run.sh "$APP_DIR" /etc/sane.d/net.conf /etc/sane.d/airscan.conf

# newly added
COPY ./brscan4-0.4.11-1.amd64.deb "$APP_DIR/brscan4-0.4.11-1.amd64.deb" 
RUN apt-get update && apt-get install -y "$APP_DIR/brscan4-0.4.11-1.amd64.deb"
RUN brsaneconfig4 -a name=Scanner model=DCP-1610W ip=192.168.30.10

@Robin-Sch
Copy link

Robin-Sch commented Oct 26, 2023

Scanner IP: x.x.x.1
Host system IP: x.x.x.2

Host system: scanimage -L => device 'airscan:...ip:x.x.x.1'
Docker container: scanimage -L => no device found
I also put 0.0.0.0 in the /etc/sane.d/saned.conf file

version: "3"
services:
    scanservjs:
        image: sbs20/scanservjs:latest
        volumes:
            - ./config:/app/config
            - ./output:/app/data/output
        environment:
            - SANED_NET_HOSTS=172.28.0.1
        <... reverse proxy/ports things...>

Where 172.28.0.1 is the gateway of the docker network.

I also tried setting 172.28.0.1 to both x.x.x.1 and x.x.x.2 which gave the same result.
What am I doing wrong here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants