Thanks @bryceryan for pointing me in the right direction!
I got it all working, and wanted to briefly explain for the benefit of someone who might find this thread. I tried quite a few steps through trial and error, but I believe these are the general steps to follow.
Before anything else I installed ALSA on the host machine. I believe it would be impossible to do this inside a container.
Then I got shairport sync working using the knapoc/shairport-sync image. My USB devices didn’t show up under /dev/tty, so I determined that I would need to define their locations elsewhere. I loaded the shairport image using the -v "/opt/shairport/shairport-sync.conf:/usr/local/etc/shairport-sync.conf" \
option, and configured the shairport-sync.conf file to look for the appropriate output device. If you find yourself stuck at this point, utilize the documentation for the shairport-sync general package. I also had to set the --device=/dev/snd:/dev/snd \
option so the container had access to audio.
For reference, my shairport run command:
sudo docker run \ -d \ --name=shairport \ --restart=always \ --net=host \ --device=/dev/snd:/dev/snd \ -v "/opt/shairport/shairport-sync.conf:/usr/local/etc/shairport-sync.conf" \ knapoc/shairport-sync
I wanted a squeezebox and for openHAB to be able to independently make announcements. Since openHAB uses the audio settings of its host machine and configuring the openHAB image for audio output looked tedious, I decided instead to spin up two squeezebox players - one for general audio playback and one just for openHAB alerting. openHAB supports piping audio to a squeezebox player.
My two squeezebox instances:
sudo docker run \ -d \ --name=squeezelite1 \ --restart=always \ --device=/dev/snd/ \ -v /opt/squeezelite/i1:/config \ -e USER_ID=65534 \ -e GROUP_ID=100 \ -e UMASK=0002 \ -e PLAYER=squeezelite1 \ -e OUTPUT_DEVICE=front:CARD=Device,DEV=0 \ -e MAC_ADDRESS=redacted \ aschamberger/squeezelite
sudo docker run \ -d \ --name=squeezelite2 \ --restart=always \ --device=/dev/snd/ \ -v /opt/squeezelite/i2:/config \ -e USER_ID=65534 \ -e GROUP_ID=100 \ -e UMASK=0002 \ -e PLAYER=squeezelite2 \ -e OUTPUT_DEVICE=front:CARD=Intel,DEV=0 \ -e MAC_ADDRESS=redacted \ aschamberger/squeezelite
Again, I used the non-docker squeezelite documentation for hints on how to determine how to define the audio devices. I accessed the bash environment inside the containers using docker exec -ti containerID /bin/bash
then used the appropriate commands, as listed in the documentation for the software, to display the available audio devices.
I ended up using the built-in sound card and two USB audio dongles, and they work flawlessly! I paired them with a MonoPrice 6 zone amp, and hooked the audio outputs up to three discrete outputs.