Docker is a lot less complicated than it was made out to be.
Docker is a way of taking a service (something like Plex) and making it work in a sort of “slice” cut out of the real machine’s resources (CPU, RAM and disk space). These slices are called containers.
There are several benefits:
docker-compose up -d
: run this into the same dir as a magical yaml file to create a container for the first time.docker stop cups
, docker start cups
, docker restart cups
will stop/start/restart the cups container.docker container list
shows all containers you’ve created.docker rm cups
removes the cups container (if it’s not running).docker image list
shows the software images that the containers are using.docker rmi olbat/cupsd
will remove the olbat/cupsd image, but only if the cups container that is based on it has been removed (and stopped).docker exec cups ls /etc/cups
will execute a command inside the container. You can execute /bin/sh
or /bin/bash
to explore inside the container machine.ctop
is a nice tool that will show you all containers and let you start/stop/restart them.There are a couple of things you need to add to a fresh Debian install in order to use Docker:
docker.io
.ctop
is a nice CLI tool that shows your containers and lets you do stuff with them (stop, start, restart, enter shell, view logs etc.) It’s basically a simple CLI version of Portainer (which I never bothered installing after all).The following tools are indirectly related to services inside docker containers:
vainfo
will verify that GPU-accelerated video encoding/decoding is working for AMD and Intel GPUs. This will be useful for many media streaming containers. See the Arch wiki for more.avahi
(which is avahi-daemon
on Debian) and avahi-dnsconfd
will help autodiscover some services on LAN between Linux machines. Only applicable if you have more than one Linux machine on your LAN, of course, and it’s only relevant to some services (eg. CUPS).Should you use Docker or Podman? If you’re a beginner just use Docker. It’s a lot simpler. Yes, there are good reasons to use Podman but you don’t need the extra headache when you’re starting out. You will be able to transition into Podman easier later.
Use restart: "always"
in your compose yaml’s and save yourself unnecessary trouble. Some people try to micromanage their containers and end up writing sysctl scripts for each of them and so on and so forth. With this restart policy your containers will stay stopped if stopped manually, but will start each time the docker daemon [re]starts, which most likely means at boot, which is probably all you want right now.
The one docker issue that will give you the most trouble is mapping users from the real machine to the container machine and back. You want the service in the container to run as a certain user, and maybe you want to give it access to some files or devices on the real machine too. But some docker images were made by people who apparently don’t understand how Linux permissions work. A good docker image will let you specify what users and groups it needs to work with (emby/embyserver
is a very good example). A bad image will make up some UID and GID that’s completely unrelated to anything on your machine and give you no way to change them; for such images you can try to force them to use root (UID and GID 0) but that negates some of the benefits a container was supposed to give you. So when looking for images see if they have a description, and if it mentions any UID and GID mapping. Otherwise you will probably have a bad time.
How do you find (good) docker images? On hub.docker.com, just search for what you need (eg. “cups”). I suggest sorting images by most recently updated, and have a look at how many downloads and stars it has, too. It’s also very helpful if they have a description and instructions.
One last thing before we get to the good stuff. I made a dir on my RAID array, /mnt/array/docker
where I make one subdir for each service (eg. /mnt/array/docker/cups
), where I keep the magical yaml (compose.yaml) for each service, and sometimes I map config files from the container, so they persist even if the container is deleted. I also use git
in those dirs to keep track of the changes to the yaml files.
Emby is a media server that you use to index movies and series and watch them remotely on TV or your phone and tablet. Some other popular alternatives are Plex, Jellyfin and Serviio. See this comparison chart.
Here’s the docker-compose.yaml
, explanations below:
version: "2.3"
services:
emby:
image: emby/embyserver
container_name: emby
#runtime: nvidia # for NVIDIA GPUs
#network_mode: host # if you need DLNA or Wake-on-Lan
environment:
- UID=1000 # The UID to run emby as
- GID=100 # The GID to run emby as
- GIDLIST=100,44,105 # extra groups for /dev/dri/* devices
volumes:
- "./data:/config" # emby data dir (note the dot at the start)
- "/mnt/nas/array/multimedia:/mnt/nas/array/multimedia"
ports:
- "8096:8096/tcp" # HTTP port
- "8920:8920/tcp" # HTTPS port
devices:
- "/dev/dri:/dev/dri" # VAAPI/NVDEC/NVENC render nodes
restart: always
/dev
devices that are owned by 3rd party users like video
and render
. Very nice.Let’s look at another nicely made Docker image. Deluge is a BitTorrent client, what we put in the Docker container is actually just the server part. The server can deal with the uploads/downloads but needs an UI app to manage it. The UI apps can be installed on your phone for example (I like Transdroid) but the Deluge server also includes a web interface on port 8112.
version: "2.1"
services:
deluge:
image: lscr.io/linuxserver/deluge:latest
container_name: deluge
environment:
- PUID=1000
- PGID=1000
- DELUGE_LOGLEVEL=error
volumes:
- "./config:/config" # mind the dot at the start
- "/mnt/nas/array/deluge:/downloads"
ports:
- "8112:8112/tcp" # web UI
- "60000:60000/tcp" # BT transfers
- "60000:60000/udp" # BT transfers
- "58846:58846/tcp" # daemon remote control (for Transdroid)
restart: always
Most of this is covered above with Emby so I won’t repeat everything, just the important distinctions:
Navidrome is a music indexer and streaming server (sort of like your own Spotify). It’s follows the Subsonic spec so any client app that works with Subsonic will work with Navidrome (I like Substreamer). It also includes a web UI.
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navidrome
environment:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_BASEURL: ""
ND_PORT: 4533
ND_DATAFOLDER: /data
ND_MUSICFOLDER: /music
volumes:
- "./data:/data"
- "/mnt/nas/array/music:/music:ro"
ports:
- "4533:4533/tcp"
restart: "always"
Again, mostly self-explanatory:
This server can do some interesting things. Its bread and butter is DLNA. It has a companion Android app called, you guessed it, BubbleUPnP, which acts as a DLNA controller. The server part here can do local transcoding so the Android phone doesn’t have to (subject to some caveats, for example the phone, the DLNA source and the Bubble server need to be on the same LAN; and it can only transcode one stream at a time).
It can also identify media providers (like Emby or Plex) on the LAN and media renderers (like Chromecast or Home Mini speaker) and DLNA-enables them so they appear in the Bubble app as well as on other DLNA-aware devices.
version: "3.3"
services:
deluge:
image: bubblesoftapps/bubbleupnpserver-openj9-leap
container_name: bubbleupnpserver
network_mode: "host"
user: "0:0"
devices:
- "/dev/dri:/dev/dri:rw"
volumes:
- "./data/configuration.xml:/opt/bubbleupnpserver/configuration.xml:rw"
restart: "always"
/dev/dri
which are restricted to video
and render
groups to access GPU-accelerated transcoding. So using root is the only solution here (short of looking for a nicer image).Normally I’d install samba on the host machine but Debian wanted me to install like 30 packages for it so I think that’s a valid reason to use a container.
version: "2.3"
services:
samba:
image: twistify/anonymous-samba
container_name: samba
volumes:
- "./etc/samba:/etc/samba:ro"
- "/mnt/nas/array:/mnt/nas/array"
ports:
- "445:445/tcp" # SMB
- "139:139/tcp" # NetBIOS
restart: "always"
Normally this should be a simple enough setup, and it is simple as far as docker is concerned. Map some ports, map the config files, map the array so you can give out shares, done. But the image doesn’t offer UID customization and just runs as root.
For reference I give the /etc/samba/smb.conf
here too because I know it’s tricky. This one only offers anonymous read-only shares, which mainly worked out of the box (hence why I stuck to this image in spite of the root thing).
[global]
workgroup = WORKGROUP
log file = /dev/stdout
security = user
map to guest = Bad User
log level = 2
browseable = yes
read only = yes
create mask = 666
directory mask = 555
guest ok = yes
guest only = yes
force user = root
[iso]
path=/mnt/nas/multimedia/iso
You can add your own shares aside from [iso], as long as the paths are mapped in the yaml.
Notice the ugly use of root in the Samba config too.
CUPS is a printer server, which I need because my printer is connected via USB to the server and I want to be able to print from my desktop machine.
version: "2.3"
services:
cups:
image: aguslr/cups:latest
container_name: cups
privileged: "yes"
environment:
- CUPS_USER=admin
- CUPS_PASS=admin
volumes:
- "/dev/bus/usb:/dev/bus/usb" # keep this under volumes, not devices
- "/run/dbus:/run/dbus"
ports:
- "631:631/tcp" # CUPS
restart: "always"
The docker setup is not terribly complicated if you overlook things like /dev/bus/usb
needing to be a volume mapping not a device mapping, or the privileged mode.
CUPS is complicated because it’s a complex beast, so I’ll try to add some pointers below (mostly unrelated to docker):
lpstat -p
inside the host to check if CUPS know about your printer, and /usr/lib/cups/backend/usb
to check if it knows about the USB printer in particular.See you next time with more docker recipes! As usual any and all comments and suggestions are welcome, including “omg you’re so dumb, that thing could be done easier like this”.
A place to share alternatives to popular online services that can be self-hosted without giving up privacy or locking you into a service you don’t control.
Rules:
Be civil: we’re here to support and learn from one another. Insults won’t be tolerated. Flame wars are frowned upon.
No spam posting.
Posts have to be centered around self-hosting. There are other communities for discussing hardware or home computing. If it’s not obvious why your post topic revolves around selfhosting, please include details to make it clear.
Don’t duplicate the full text of your blog or github here. Just post the link for folks to click.
Submission headline should match the article title (don’t cherry-pick information from the title to fit your agenda).
No trolling.
Resources:
Any issues on the community? Report it using the report flag.
Questions? DM the mods!
Thanks for sharing, I didn’t know about ctop.
I installed Debian on a laptop to use as a server, and planned to use it for Firefly III among other things, but got nervous hearing how tough it was/is to lock down a server.