OliveTin EZ-Start: A New Way to Deploy OliveTin-for-Channels Using Just Two Environment Variables to Get Started!

EDIT 2025.03.29 - If you're looking for an easier way to install OliveTin-for-Channels, and you already have Portainer installed, this is the place. If you don't have Portainer installed either, there's an even easier way ot get Portainer and OliveTin-for-Channels up-and-running:

Given the kind of download numbers OliveTin-for-Channels has enjoyed (pushing towards 25K), it's clear that most users have been able to spin-it-up without assistance.

Having said that, there's also clearly another group of users that would like to have it in their toolkit, but have found the environment variables required challenging. Well, this project is for you! We're going to use the power of OliveTin to create the set of env vars you'll need to be able to take full advantage of that power.

I'm rolling out stage one now: which requires CDVR Server, Docker and Portainer to be installed first. Future stages will whittle that down to only requiring Docker, where you'll be able to install OliveTin from the command line, followed by Portainer and CDVR (Docker version) using OliveTin's Project One-Click!

Here's how to use it (with Docker and Portainer up-and-running). Also, be aware this EZ-Start process assumes you have CDVR Server and Docker/Portainer installed on the same system. I'll list a couple of optional env vars for those with Docker/Portainer on a separate system, and for those that are using a non-standard port for Channels, at the end of this write-up:

In Portainer-Stacks, create a new stack called olivetin. Go into the Stacks-Editor, and paste in this Docker Compose:

services:
  olivetin: # This docker-compose typically requires no editing. Use the Environment variables section of Portainer to set your values.
    # 2025.08.25
    # GitHub home for this project: https://github.com/bnhf/OliveTin.
    # Docker container home for this project with setup instructions: https://hub.docker.com/r/bnhf/olivetin.
    image: bnhf/olivetin:${TAG:-latest} # Add the tag like latest or test to the environment variables below.
    container_name: ${OLIVETIN_NAME:-olivetin}${EZ_START}
    hostname: ${OLIVETIN_NAME:-olivetin}${EZ_START}
    dns_search: ${DOMAIN:+${DOMAIN}} # For Tailscale users using Magic DNS, add your Tailnet (tailxxxxx.ts.net) to use hostnames for remote nodes, otherwise use your local domain name.
    ports:
      - ${HOST_PORT:-1337}:1337
    environment:
      - OLIVETIN_COMPOSE=2025.08.25${EZ_START} # Do not change this value.
      - CHANNELS_DVR=${CHANNELS_DVR_HOST}:${CHANNELS_DVR_PORT:-8089} # Add your Channels DVR server in the form CHANNELS_DVR_HOST=<hostname or ip> and CHANNELS_DVR_PORT=<port>.
      - CHANNELS_DVR_ALTERNATES=${CHANNELS_DVR2_HOST:+${CHANNELS_DVR2_HOST}:${CHANNELS_DVR2_PORT}}${CHANNELS_DVR3_HOST:+ ${CHANNELS_DVR3_HOST}:${CHANNELS_DVR3_PORT}} # Space separated list of alternate Channels DVR servers to choose from in the form hostname:port or ip:port.
      - CHANNELS_CLIENTS=${CHANNELS_CLIENTS} # Space separated list of Channels DVR clients you'd like notifications sent to in the form hostname or IP.
      - ALERT_SMTP_SERVER=${ALERT_SMTP_SERVER} # SMTP server to use for sending alert e-mails. smtp.gmail.com:587 for example.
      - ALERT_EMAIL_FROM=${ALERT_EMAIL_FROM} # Sender address for alert e-mails.
      - ALERT_EMAIL_PASS=${ALERT_EMAIL_PASS} # SMTP "app" password established through GMail or Yahoo Mail. Do not use your everyday e-mail address.
      - ALERT_EMAIL_TO=${ALERT_EMAIL_TO} # Recipient address for alert e-mails.
      - UPDATE_YAMLS=${UPDATE_YAMLS:-true} # Set this to true to update config.yaml.
      - UPDATE_SCRIPTS=${UPDATE_SCRIPTS:-true} # Set this to true to update all included scripts.
      - TZ=${TZ} # Add your local timezone in standard linux format. E.G. US/Eastern, US/Central, US/Mountain, US/Pacific, etc.
      - PORTAINER_TOKEN=${PORTAINER_TOKEN} # Generate via <username> dropdown (upper right of WebUI), "My account", API tokens.
      - PORTAINER_HOST=${PORTAINER_HOST:-$CHANNELS_DVR_HOST} # Hostname or IP of the Docker host you're running Portainer on.
      - PORTAINER_PORT=${PORTAINER_PORT:-9443} # https port you're running Portainer on. 9443 is the default.
      - PORTAINER_ENV=${PORTAINER_ENV:-2} # Set this is if you're using an alternate Portainer Environment for some reason. 2 is the default.
      - PERSISTENT_LOGS=${PERSISTENT_LOGS:-false} # For supported Actions, log files are retained on an ongoing basis. false is the default.
    volumes:
      - ${HOST_DIR:-/unused}${HOST_DIR:+/olivetin:/config} # Add the parent directory on your Docker host you'd like to use.
      - ${DVR_SHARE:-/unused}${DVR_SHARE:+:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT}} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR network share.
      - ${LOGS_SHARE:-/unused}${LOGS_SHARE:+:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT}_logs} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR logs network share.
      - ${TUBEARCHIVIST_SHARE:-/unused}${TUBEARCHIVIST_SHARE:+:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT}_ta} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your TubeArchivist videos network share.
      - ${DVR2_SHARE:-/unused}${DVR2_SHARE:+:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT}} # Note that these volume mounts should always be to /mnt/hostname-port or /mnt/ip-port (dash rather than a colon between).
      - ${LOGS2_SHARE:-/unused}${LOGS2_SHARE:+:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT}_logs} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR logs network share.
      - ${TUBEARCHIVIST2_SHARE:-/unused}${TUBEARCHIVIST2_SHARE:+:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT}_ta} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your TubeArchivist videos network share.
      - ${DVR3_SHARE:-/unused}${DVR3_SHARE:+:/mnt/${CHANNELS_DVR3_HOST}-${CHANNELS_DVR3_PORT}} # Note that these volume mounts should always be to /mnt/hostname-port or /mnt/ip-port (dash rather than a colon between).
      - ${LOGS3_SHARE:-/unused}${LOGS3_SHARE:+:/mnt/${CHANNELS_DVR3_HOST}-${CHANNELS_DVR3_PORT}_logs} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR logs network share.
      - ${TUBEARCHIVIST3_SHARE:-/unused}${TUBEARCHIVIST3_SHARE:+:/mnt/${CHANNELS_DVR3_HOST}-${CHANNELS_DVR3_PORT}_ta} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your TubeArchivist videos network share.
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

  static-file-server:
    image: halverneus/static-file-server:latest
    container_name: ${SFS_NAME:-static-file-server}${EZ_START}
    dns_search: ${DOMAIN}
    ports:
      - ${HOST_SFS_PORT:-0}:8080
    environment:
      - FOLDER=${FOLDER:-/web}
    volumes:
      - ${HOST_DIR:-/unused}${HOST_DIR:+/olivetin/data:${FOLDER:-/web}}
    restart: unless-stopped

#0#volumes: # Remove the #x# to enable. Use this section if you've setup a docker volume named channels-dvr, with CIFS or NFS, to bind to /mnt/dvr inside the container. Set ${DVR_SHARE} to channels-dvr (DVR_SHARE=channels_dvr) in that example.
  #1#channels-dvr:
    #1#external: true
  #2#channels-dvr-logs:
    #2#external: true
  #3#tubearchivist:
    #3#external: true
  #4#channels-dvr2:
    #4#external: true
  #5#channels-dvr2-logs:
    #5#external: true
  #6#tubearchivist2:
    #6#external: true
  #7#channels-dvr3:
    #7#external: true
  #8#channels-dvr3-logs:
    #8#external: true
  #9#tubearchivist3:
    #9#external: true

You will not need to make any changes to the Docker Compose itself. However, you will need to add two environment variables:

EZ_START=-ezstart
CHANNELS_DVR_HOST=ip.address.of.your.cdvr.server

Two things to note. First the value of EZ_START is -ezstart (begins with a dash and is lowercase). Second, use the IP address of your CDVR server only without the port number (no 8089) for CHANNELS_DVR_HOST.

Next click the Update the stack button, followed by selecting the Re-pull and Redeploy slider. Once the success message is seen, you should be able to find the OliveTin-for-Channels WebUI at http://ip.address.of.your.cdvr.server:1337

Now, select the new OliveTin Environment Variables Generator/Tester Action, and you'll be able to step through the process of adding the values, particularly those that are required. Once you click Start you'll get a new list of env vars ready to be pasted into Portainer!

Armed with this list, you can stop the olivetin stack you created and paste the new list into the Environment variables section of the Stack-Editor. You'll want to replace the values from earlier, as those are no longer required! Click Update the stack, and you'll be up-and-running.

TAG=latest
DOMAIN=localdomain tailxxxxx.ts.net
HOST_PORT=1337
CHANNELS_DVR_HOST=media-server8
CHANNELS_DVR_PORT=8089
ALERT_SMTP_SERVER=smtp.gmail.com:587
ALERT_EMAIL_FROM=[Redacted]
ALERT_EMAIL_PASS=[Redacted]
ALERT_EMAIL_TO=[Redacted]
UPDATE_YAMLS=true
UPDATE_SCRIPTS=true
TZ=US/Mountain
HOST_DIR=/data
DVR_SHARE=/mnt/dvr
LOGS_SHARE=/mnt/channelsdvr
TUBEARCHIVIST_SHARE=/mnt/dvr
HOST_SFS_PORT=8080
FOLDER=/web
PORTAINER_TOKEN=[Redacted]
PORTAINER_HOST=htpc6
PORTAINER_PORT=9443
PORTAINER_ENV=2
PERSISTENT_LOGS=false

This new Action is designed to allow you to add values later, which is why most of the fields contain environment variables by default (those cryptic looking things that start with a $). Any values you've supplied in the past do not need to be added again, simply input whatever new ones you know, and generate a new list to paste into the stack.

Finally, you can run the OliveTin Post-Install Healthcheck to verify all of the basics are covered.

Checking your OliveTin-for-Channels installation...
(extended_check=false)

Version 2025.03.17

----------------------------------------

Checking that your selected Channels DVR server (media-server8:8089) is reachable by URL:
HTTP Status: 200 indicates success...

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1276  100  1276    0     0   178k      0 --:--:-- --:--:-- --:--:--  178k
HTTP Status: 200
Effective URL: http://media-server8:8089/

----------------------------------------

Checking that your selected Channels DVR server's data files (/mnt/media-server8-8089) are accessible:
Folders with the names Database, Images, Imports, Logs, Movies, Streaming and TV should be visible...

total 8
drwxr-xr-x 2 1000 1000 4096 Jan 20 01:44 .
drwxr-xr-x 1 root root 4096 Mar 17 16:09 ..
drwxr-xr-x 2 1000 1000    0 Mar 17 12:18 Database
drwxr-xr-x 2 1000 1000    0 Mar 16 22:22 Images
drwxr-xr-x 2 1000 1000    0 Sep 25 08:43 Imports
drwxr-xr-x 2 1000 1000    0 Sep 25 08:43 Logs
drwxr-xr-x 2 1000 1000    0 Mar 15 10:30 Movies
drwxr-xr-x 2 1000 1000    0 Nov 18 06:35 PlayOn
drwxr-xr-x 2 1000 1000    0 Mar 16 23:29 Streaming
drwxr-xr-x 2 1000 1000    0 Mar  5 22:10 TV
drwxr-xr-x 2 1000 1000    0 Jan 20 01:44 tubearchivist

If the listed folders are NOT visible, AND you have your Channels DVR and Docker on the same system:

Channels reports this path as...
G:\dvr

When using a Windows path in Portainer, change the backslashes to slashes like this...
G:/dvr

When using WSL with a Linux distro and Docker Desktop, it's also possible to use...
/mnt/g/dvr

----------------------------------------

Checking that your selected Channels DVR server's log files (/mnt/media-server8-8089_logs) are accessible:
Folders with the names data and latest should be visible...

total 12
drwxr-xr-x 2 1000 1000 4096 Feb 19 12:31 .
drwxr-xr-x 1 root root 4096 Mar 17 16:09 ..
drwxr-xr-x 2 1000 1000    0 Sep 21 02:23 2024.09.10.2115
drwxr-xr-x 2 1000 1000    0 Dec  5 19:40 2024.12.05.1913
drwxr-xr-x 2 1000 1000    0 Dec  7 13:40 2024.12.07.0453
drwxr-xr-x 2 1000 1000    0 Dec  9 19:40 2024.12.10.0055
drwxr-xr-x 2 1000 1000    0 Dec 28 02:37 2024.12.27.0121
drwxr-xr-x 2 1000 1000    0 Jan 21 16:30 2025.01.18.0528
-rwxr-xr-x 1 1000 1000  829 Feb 19 12:31 Channels DVR Server.lnk
drwxr-xr-x 2 1000 1000    0 Mar 17 17:33 data
drwxr-xr-x 2 1000 1000    0 Feb 19 12:31 latest

If the listed folders are NOT visible, AND you have your Channels DVR and Docker on the same system:

Channels reports this path as...
C:\ProgramData\ChannelsDVR

When using a Windows path in Portainer, change the backslashes to slashes like this...
C:/ProgramData/ChannelsDVR

When using WSL with a Linux distro and Docker Desktop, it's also possible to use...
/mnt/c/ProgramData/ChannelsDVR

----------------------------------------

Checking if your Portainer token is working on ports 9000 and/or 9443:

Portainer http response on port 9000 reports version 2.27.0
Portainer Environment ID for local is 2
Portainer https response on port 9443 reports version 2.27.0
Portainer Environment ID for local is 2

----------------------------------------

Here's a list of your current OliveTin-related settings:

HOSTNAME=olivetin
CHANNELS_DVR=media-server8:8089
CHANNELS_DVR_ALTERNATES=utheater-pc:8089
CHANNELS_CLIENTS=appletv4k firestick-master amazon-aftkrt
ALERT_SMTP_SERVER=smtp.gmail.com:587
ALERT_EMAIL_FROM=[Redacted]@gmail.com
ALERT_EMAIL_PASS=[Redacted]
ALERT_EMAIL_TO=[Redacted]@gmail.com
UPDATE_YAMLS=false
UPDATE_SCRIPTS=false
PORTAINER_TOKEN=[Redacted]
PORTAINER_HOST=htpc6
PORTAINER_PORT=9443
PORTAINER_ENV=2

----------------------------------------

Here's the contents of /etc/resolv.conf from inside the container:

# Generated by Docker Engine.
# This file can be edited; Docker Engine will not make further changes once it
# has been modified.

nameserver 127.0.0.11
search localdomain tail[Redacted].ts.net
options ndots:0

# Based on host file: '/etc/resolv.conf' (internal resolver)
# ExtServers: [100.100.100.100]
# Overrides: [search]
# Option ndots from: internal

----------------------------------------

Here's the contents of /etc/hosts from inside the container:

127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.26.0.3	olivetin

For those of you with Docker/Portainer on a separate system, or are using a non-standard port for CDVR, here are a couple of other env vars you could use in OliveTin EZ-Start:

CHANNELS_DVR_PORT=
PORTAINER_HOST=
1 Like

So I think I did this right but don't think the check looks correct.

Checking your OliveTin-for-Channels installation...
(extended_check=false)

Version 2025.03.17

----------------------------------------

Checking that your selected Channels DVR server (192.168.50.219:8089) is reachable by URL:
HTTP Status: 200 indicates success...

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1276  100  1276    0     0   415k      0 --:--:-- --:--:-- --:--:--  415k
HTTP Status: 200
Effective URL: http://192.168.50.219:8089/

----------------------------------------

Checking that your selected Channels DVR server's data files (/mnt/192.168.50.219-8089) are accessible:
Folders with the names Database, Images, Imports, Logs, Movies, Streaming and TV should be visible...

total 8
drwxr-xr-x 2 root root 4096 Mar 18 00:40 .
drwxr-xr-x 1 root root 4096 Mar 18 00:40 ..

If the listed folders are NOT visible, AND you have your Channels DVR and Docker on the same system:

Channels reports this path as...
/mnt/md0/DVR-storage/DVR

----------------------------------------

Checking that your selected Channels DVR server's log files (/mnt/192.168.50.219-8089_logs) are accessible:
Folders with the names data and latest should be visible...

total 4
drwxr-xr-x 2 root root   40 Mar 18 00:40 .
drwxr-xr-x 1 root root 4096 Mar 18 00:40 ..

If the listed folders are NOT visible, AND you have your Channels DVR and Docker on the same system:

Channels reports this path as...
/home/terry/channels-dvr

----------------------------------------

Checking if your Portainer token is working on ports 9000 and/or 9443:

Portainer http response on port 9000 reports version 2.21.1
Portainer Environment ID for local is 
Portainer https response on port 9000 reports version 
Portainer Environment ID for local is 

----------------------------------------

Here's a list of your current OliveTin-related settings:

HOSTNAME=olivetin
CHANNELS_DVR=192.168.50.219:8089
CHANNELS_DVR_ALTERNATES=
CHANNELS_CLIENTS=
ALERT_SMTP_SERVER=
ALERT_EMAIL_FROM=[Redacted]@
ALERT_EMAIL_PASS=[Redacted]
ALERT_EMAIL_TO=[Redacted]@
UPDATE_YAMLS=true
UPDATE_SCRIPTS=true
PORTAINER_HOST=192.168.50.149
PORTAINER_PORT=9000
PORTAINER_ENV=2

----------------------------------------

Here's the contents of /etc/resolv.conf from inside the container:

# Generated by Docker Engine.
# This file can be edited; Docker Engine will not make further changes once it
# has been modified.

nameserver 127.0.0.11
search 
options ndots:0

# Based on host file: '/etc/resolv.conf' (internal resolver)
# ExtServers: [host(192.168.65.7)]
# Overrides: [search]
# Option ndots from: internal

----------------------------------------

Here's the contents of /etc/hosts from inside the container:

127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::	ip6-localnet
ff00::	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.20.0.3	olivetin

Just above is what Channels says is the path to your recordings. Is that what your env var list showed?

And, above is where Channels DVR says your CDVR logs are stored. How does that compare with the env var list?

yes that is what Env Var shows.

TAG=latest
DOMAIN=
HOST_PORT=1337
CHANNELS_DVR_HOST=192.168.50.219
CHANNELS_DVR_PORT=8089
ALERT_EMAIL_SERVER=
ALERT_EMAIL_FROM=
ALERT_EMAIL_PASS=
ALERT_EMAIL_TO=
UPDATE_YAMLS=true
UPDATE_SCRIPTS=true
TZ=
HOST_DIR=/data
DVR_SHARE=/mnt/md0/DVR-storage/DVR
LOGS_SHARE=/home/terry/channels-dvr
TUBEARCHIVIST_SHARE=/mnt/md0/DVR-storage/DVR
HOST_SFS_PORT=8080
FOLDER=/web
PORTAINER_TOKEN=
PORTAINER_HOST=192.168.50.149
PORTAINER_PORT=9000
PORTAINER_ENV=2
PERSISTENT_LOGS=false

I only have the DVR-storage and channels-dvr folders shared via SMB if that makes any difference.

OK, so I see your CDVR server and Docker/Portainer host are on different systems. Are both of those paths mounted on the Docker/Portainer host via SMB, or are you sharing them to the CDVR host via SMB?

As a side note, the PORTAINER_PORT setting is only for https, 9000 is used for http -- and that port is fixed at 9000. So, you'd want to leave that value empty or set to 9443. 9000 is used first via http.

1 Like

both can be seen and browsed. I was using 9000 so as to avoid any insecure site warnings.

On the Docker/Portainer host? And if so, on what paths? If I'm understanding what you're doing, the paths that Channels is reporting, are likely not the same paths as you're using as mount points on the Docker/Portainer host -- and those are the paths we need.

So you're using http:// and port 9000, that's not a problem. But you don't want to set the the https:// port to 9000 too. PORTAINER_PORT is only for changing https://. http:// is automatically at 9000.

Given that neither of the paths reported by your CDVR server are the correct paths on your Docker host, and given your statement just above, I'm going to guess that the SMB shares are not mounted to the file system on the Docker host.

If they can be seen and browsed on the Docker host only as SMB shares, they need to be added to Portainer as Docker Volumes. Then those Docker Volumes are used as values for DVR_SHARE and LOGS_SHARE.

This is done using Portainer-Volumes. Add a volume, name it (I recommend channels-dvr for your recordings and channels-dvr-logs for the executables) and select CIFS. Then you need to specify the SMB server and SMB share names with the username and password for accessing them:

A couple of last things to do, which is to use those names, and assuming you used my recommended names, you'll be changing these two values by stopping and editing the Portainer-Stack:

DVR_SHARE=channels-dvr
LOGS_SHARE=channels-dvr-logs

And, in the compose itself, you have to uncomment (remove the #) these lines:

  #channels-dvr:
    #external: true
  #channels-dvr-logs:
    #external: true

Let me know if I'm on track here please!

You Sir are awesome! That was it.

Checking your OliveTin-for-Channels installation...
(extended_check=false)

Version 2025.03.17

----------------------------------------

Checking that your selected Channels DVR server (192.168.50.219:8089) is reachable by URL:
HTTP Status: 200 indicates success...

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1276  100  1276    0     0   415k      0 --:--:-- --:--:-- --:--:--  623k
HTTP Status: 200
Effective URL: http://192.168.50.219:8089/

----------------------------------------

Checking that your selected Channels DVR server's data files (/mnt/192.168.50.219-8089) are accessible:
Folders with the names Database, Images, Imports, Logs, Movies, Streaming and TV should be visible...

total 4
drwxr-xr-x 2 root root    0 Mar 18 00:10 .
drwxr-xr-x 1 root root 4096 Mar 18 10:00 ..
drwxr-xr-x 2 root root    0 Mar 17 17:31 Database
drwxr-xr-x 2 root root    0 Mar 16 23:00 Images
drwxr-xr-x 2 root root    0 Feb 10  2024 Imports
drwxr-xr-x 2 root root    0 Feb  7  2024 Logs
drwxr-xr-x 2 root root    0 Mar 18 00:10 Movies
drwxr-xr-x 2 root root    0 Feb 10  2024 PlayOn
drwxr-xr-x 2 root root    0 Mar 18 00:10 TV

If the listed folders are NOT visible, AND you have your Channels DVR and Docker on the same system:

Channels reports this path as...
/mnt/md0/DVR-storage/DVR

----------------------------------------

Checking that your selected Channels DVR server's log files (/mnt/192.168.50.219-8089_logs) are accessible:
Folders with the names data and latest should be visible...

total 12
drwxr-xr-x 2 root root    0 Mar  6 16:02 .
drwxr-xr-x 1 root root 4096 Mar 18 10:00 ..
drwxr-xr-x 2 root root    0 Feb 24 02:04 2025.02.24.0656
drwxr-xr-x 2 root root    0 Feb 25 02:59 2025.02.25.0015
drwxr-xr-x 2 root root    0 Feb 27 02:11 2025.02.27.0156
drwxr-xr-x 2 root root    0 Mar  1 15:24 2025.03.01.2019
drwxr-xr-x 2 root root    0 Mar  2 16:33 2025.03.02.2319
drwxr-xr-x 2 root root    0 Mar  6 16:02 2025.03.06.2119
drwxr-xr-x 2 root root    0 Mar 18 00:45 Streaming
drwxr-xr-x 2 root root    0 Mar 18 09:49 data
-rwxr-xr-x 1 root root 3903 Feb 16 14:47 install.sh
drwxr-xr-x 2 root root    0 Mar  6 16:02 latest
-rwxr-xr-x 1 root root 1192 Feb 16 14:47 uninstall.sh

If the listed folders are NOT visible, AND you have your Channels DVR and Docker on the same system:

Channels reports this path as...
/home/terry/channels-dvr

----------------------------------------

Checking if your Portainer token is working on ports 9000 and/or 9443:

Portainer http response on port 9000 reports version 2.21.1
Portainer Environment ID for local is 
Portainer https response on port 9443 reports version 2.21.1
Portainer Environment ID for local is 

----------------------------------------

Here's a list of your current OliveTin-related settings:

HOSTNAME=olivetin
CHANNELS_DVR=192.168.50.219:8089
CHANNELS_DVR_ALTERNATES=
CHANNELS_CLIENTS=
ALERT_SMTP_SERVER=
ALERT_EMAIL_FROM=[Redacted]@
ALERT_EMAIL_PASS=[Redacted]
ALERT_EMAIL_TO=[Redacted]@
UPDATE_YAMLS=true
UPDATE_SCRIPTS=true
PORTAINER_HOST=192.168.50.149
PORTAINER_PORT=9443
PORTAINER_ENV=2

----------------------------------------

Here's the contents of /etc/resolv.conf from inside the container:

# Generated by Docker Engine.
# This file can be edited; Docker Engine will not make further changes once it
# has been modified.

nameserver 127.0.0.11
search local
options ndots:0

# Based on host file: '/etc/resolv.conf' (internal resolver)
# ExtServers: [host(192.168.65.7)]
# Overrides: [search]
# Option ndots from: internal

----------------------------------------

Here's the contents of /etc/hosts from inside the container:

127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::	ip6-localnet
ff00::	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.20.0.3	olivetin
1 Like

Sweet!

The only other thing I'd suggest, is for you to create your Portainer token, and add it to OliveTin. This will open up all of the Project One-Click stuff.

That's done by going into My account by clicking on the username dropdown in the upper right corner:

Then scroll down to the Access tokens area, and add a token named olivetin:

Copy-and-paste to a secure location (in case you need it again), and then update your OliveTin Portainer-Stack env var (in Advanced mode) with your new token:

PORTAINER_TOKEN=
1 Like

I could not find 'your' account; so I used my own and that seemed to work :wink:
This really is EZ-Start to get OliveTin up and running. It was just me figuring "It's already SMB shared, what's the problem?"
I know EZ-Start is early development but any way to add Alternate DVRs coming?

I'm working on adding support to EZ-Start for a second DVR. Beyond that has required editing of the Docker Compose -- and I'm inclined to keep it that way. Adding additional DVRs is pretty easy, following the same layout used for DVR2.

Out of curiosity, how many are you running?

Currently 3

OS
linux debian
bookworm/sid (kernel: 6.8.0-52-generic)
CPU
4 cores / AMD FX(tm)-4100 Quad-Core Processor
load averages:  0.13  0.27  0.14
16 GB Ram
OS
HC Technology.,Ltd. HCAR5000-MI2
windows Microsoft Windows 11 Pro
10.0.26100.3476 Build 26100.3476 (kernel: 10.0.26100.3476 Build 26100.3476)
CPU
16 cores / AMD Ryzen 7 5700U with Radeon Graphics
load averages:  0.00  0.00  0.00
64 GB Ram
OS
Micro-Star International MS-7C35
windows Microsoft Windows 11 Pro
10.0.22631.5039 Build 22631.5039 (kernel: 10.0.22631.5039 Build 22631.5039)
CPU
16 cores / AMD Ryzen 7 3700X 8-Core Processor
load averages:  0.00  0.00  0.00
32 GB Ram

The first one is getting kind of long in the tooth. OliveTin running here. RDP into PC.

The second is a mini PC which is actually slower processing comskip than the old AMD 4100. (Side note I get errors trying to deploy OliveTin on this PC. Want OliveTin running here, maybe volume issues causing it.) RDP into PC.

The last one which is my Main PC is setup to test out USB HDMI capture. This is running WSL Docker Desktop. (Channels is not running in Docker.)

You've inspired me -- I'm working on supporting 3 before customizing the compose is required. :slight_smile:

Alrighty then! New bnhf/olivetin:latest (aka bnhf/olivetin:2025.03.19) pushed with OliveTin EZ-Start support for up to 3 DVRs. @TerryD, when you have a chance to test this (be sure to use the newly updated 2025.03.18 compose in post #1 -- which will be there in a few moments), let me know how it works for you. Once confirmed, I can add support for more DVRs if anyone wants more.

getting errors trying to deploy stack.

Failed to deploy a stack: time="2025-03-19T10:47:02Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"CHANNELS_DVR2_PORT\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"CHANNELS_DVR3_HOST\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"CHANNELS_CLIENTS\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"ALERT_SMTP_SERVER\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"DVR2_SHARE\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"CHANNELS_DVR2_PORT\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"LOGS2_SHARE\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"CHANNELS_DVR2_PORT\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"TUBEARCHIVIST2_SHARE\" variable is not set. Defaulting to a blank string." time="2025-03-19T10:47:02Z" level=warning msg="The \"CHANNELS_DVR2_PORT\" variable is not set. Defaulting to a blank string." invalid spec: :/mnt/192.168.50.32:8089-: empty section between colons

This is with the 2025.03.18 compose, and your existing env vars? Or was this using a new set of env vars?

found a typo This was not causing the deploy errors but was just giving text after IP / not showing port number

I do have this working kind of, will post my compose and var.

version: '3.9'
services:
  olivetin: # This docker-compose typically requires no editing. Use the Environment variables section of Portainer to set your values.
    # 2025.03.18
    # GitHub home for this project: https://github.com/bnhf/OliveTin.
    # Docker container home for this project with setup instructions: https://hub.docker.com/repository/docker/bnhf/olivetin.
    image: bnhf/olivetin:${TAG:-latest} # Add the tag like latest or test to the environment variables below.
    container_name: ${OLIVETIN_NAME:-olivetin}${EZ_START}
    hostname: ${OLIVETIN_NAME:-olivetin}${EZ_START}
    dns_search: ${DOMAIN:+${DOMAIN}} # For Tailscale users using Magic DNS, add your Tailnet (tailxxxxx.ts.net) to use hostnames for remote nodes, otherwise use your local domain name.
    ports:
      - ${HOST_PORT:-1337}:1337
    environment:
      - CHANNELS_DVR=${CHANNELS_DVR_HOST}:${CHANNELS_DVR_PORT:-8089} # Add your Channels DVR server in the form CHANNELS_DVR_HOST=<hostname or ip> and CHANNELS_DVR_PORT=<port>.
      - ${CHANNELS_DVR2_HOST:+CHANNELS_DVR_ALTERNATES=${CHANNELS_DVR2_HOST}:${CHANNELS_DVR2_PORT}} ${CHANNELS_DVR3_HOST:+${CHANNELS_DVR3_HOST}:${CHANNELS_DVR3_PORT}} # Space separated list of alternate Channels DVR servers to choose from in the form hostname:port or ip:port.
      - CHANNELS_CLIENTS=${CHANNELS_CLIENTS} # Space separated list of Channels DVR clients you'd like notifications sent to in the form hostname or IP.
      - ALERT_SMTP_SERVER=${ALERT_SMTP_SERVER} # SMTP server to use for sending alert e-mails. smtp.gmail.com:587 for example.
      - ALERT_EMAIL_FROM=${ALERT_EMAIL_FROM} # Sender address for alert e-mails.
      - ALERT_EMAIL_PASS=${ALERT_EMAIL_PASS} # SMTP "app" password established through GMail or Yahoo Mail. Do not use your everyday e-mail address.
      - ALERT_EMAIL_TO=${ALERT_EMAIL_TO} # Recipient address for alert e-mails.
      - UPDATE_YAMLS=${UPDATE_YAMLS:-true} # Set this to true to update config.yaml.
      - UPDATE_SCRIPTS=${UPDATE_SCRIPTS:-true} # Set this to true to update all included scripts.
      - TZ=${TZ} # Add your local timezone in standard linux format. E.G. US/Eastern, US/Central, US/Mountain, US/Pacific, etc.
      - PORTAINER_TOKEN=${PORTAINER_TOKEN} # Generate via <username> dropdown (upper right of WebUI), "My account", API tokens.
      - PORTAINER_HOST=${PORTAINER_HOST:-$CHANNELS_DVR_HOST} # Hostname or IP of the Docker host you're running Portainer on.
      - PORTAINER_PORT=${PORTAINER_PORT:-9443} # https port you're running Portainer on. 9443 is the default.
      - PORTAINER_ENV=${PORTAINER_ENV:-2} # Set this is if you're using an alternate Portainer Environment for some reason. 2 is the default.
      - PERSISTENT_LOGS=${PERSISTENT_LOGS:-false} # For supported Actions, log files are retained on an ongoing basis. false is the default.
    volumes:
      - ${HOST_DIR:-olivetin}${EZ_START:-/olivetin}:/config # Add the parent directory on your Docker you'd like to use.
      - ${DVR_SHARE:-olivetin}${EZ_START}:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR network share.
      - ${LOGS_SHARE:-olivetin}${EZ_START}:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT}_logs # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR logs network share.
      - ${TUBEARCHIVIST_SHARE:+${TUBEARCHIVIST_SHARE}:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT}_ta} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your TubeArchivist videos network share.
      #- ${DVR2_SHARE}:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT} # Note that these volume mounts should always be to /mnt/hostname-port or /mnt/ip-port (dash rather than a colon between).
      #- ${LOGS2_SHARE}:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT}_logs # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR logs network share.
      #- ${TUBEARCHIVIST2_SHARE}:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT}_ta # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your TubeArchivist videos network share.
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

  static-file-server:
    image: halverneus/static-file-server:latest
    container_name: ${SFS_NAME:-static-file-server}${EZ_START}
    dns_search: ${DOMAIN}
    ports:
      - ${HOST_SFS_PORT:-8080}:8080
    environment:
      - FOLDER=${FOLDER:-/web}
    volumes:
      - ${HOST_DIR}/olivetin/data:${FOLDER:-/web}
    restart: unless-stopped

volumes: # use this section if you've setup a docker volume named channels-dvr, with CIFS or NFS, to bind to /mnt/dvr inside the container. Set ${DVR_SHARE} to channels-dvr (DVR_SHARE=channels_dvr) in that example.
  olivetin-ezstart:
    name: olivetin-ezstart
  channels-dvr:
    external: true
  channels-dvr-logs:
    external: true
  tubearchivist:
    external: true
  channels-dvr2:
    external: true
  channels-dvr-logs2:
    external: true
  tubearchivist2: 
    external: true
TAG=latest
DOMAIN=local
HOST_PORT=1337
CHANNELS_DVR_HOST=192.168.50.219 # will list folders
CHANNELS_DVR_PORT=8089
CHANNELS_DVR2_HOST=192.168.50.32 # no folders maybe volume issue using DrivePool
CHANNELS_DVR2_PORT=8089
CHANNELS_DVR3_HOST=192.168.50.149 # no folders local host
CHANNELS_DVR3_PORT=8089
ALERT_EMAIL_SERVER=
ALERT_EMAIL_FROM=
ALERT_EMAIL_PASS=
ALERT_EMAIL_TO=
UPDATE_YAMLS=true
UPDATE_SCRIPTS=true
TZ=US/Pacific
HOST_DIR=/data
DVR_SHARE=channels-dvr
LOGS_SHARE=channels-dvr-logs
TUBEARCHIVIST_SHARE=channels-dvr
HOST_SFS_PORT=8080
FOLDER=/web
PORTAINER_TOKEN=ptr_6Mcrj/12VVkIRmiJ1GRTEjC81+eGyLoOy6SylBOn6Xs=
PORTAINER_HOST=192.168.50.149
PORTAINER_PORT=9443
PORTAINER_ENV=2
PERSISTENT_LOGS=false

Typo fixed in post #1, including a closing right curly bracket for that same conditional. Thanks for identifying it.

I'm working on some sort of conditional deployment of the volumes, for DVR2 and DVR3...

Ok I have this working on all 3. DVR2 gave me the most problem but I think iot's because I use DrivePool and OliveTin seemed to be having touble locating it has drive G:\ when trying to connect.
Here is what I have that is working.

version: '3.9'
services:
  olivetin: # This docker-compose typically requires no editing. Use the Environment variables section of Portainer to set your values.
    # 2025.03.18
    # GitHub home for this project: https://github.com/bnhf/OliveTin.
    # Docker container home for this project with setup instructions: https://hub.docker.com/repository/docker/bnhf/olivetin.
    image: bnhf/olivetin:${TAG:-latest} # Add the tag like latest or test to the environment variables below.
    container_name: ${OLIVETIN_NAME:-olivetin}${EZ_START}
    hostname: ${OLIVETIN_NAME:-olivetin}${EZ_START}
    dns_search: ${DOMAIN:+${DOMAIN}} # For Tailscale users using Magic DNS, add your Tailnet (tailxxxxx.ts.net) to use hostnames for remote nodes, otherwise use your local domain name.
    ports:
      - ${HOST_PORT:-1337}:1337
    environment:
      - CHANNELS_DVR=${CHANNELS_DVR_HOST}:${CHANNELS_DVR_PORT:-8089} # Add your Channels DVR server in the form CHANNELS_DVR_HOST=<hostname or ip> and CHANNELS_DVR_PORT=<port>.
      - ${CHANNELS_DVR2_HOST:+CHANNELS_DVR_ALTERNATES=${CHANNELS_DVR2_HOST}:${CHANNELS_DVR2_PORT}} ${CHANNELS_DVR3_HOST:+${CHANNELS_DVR3_HOST}:${CHANNELS_DVR3_PORT}} # Space separated list of alternate Channels DVR servers to choose from in the form hostname:port or ip:port.
      - CHANNELS_CLIENTS=${CHANNELS_CLIENTS} # Space separated list of Channels DVR clients you'd like notifications sent to in the form hostname or IP.
      - ALERT_SMTP_SERVER=${ALERT_SMTP_SERVER} # SMTP server to use for sending alert e-mails. smtp.gmail.com:587 for example.
      - ALERT_EMAIL_FROM=${ALERT_EMAIL_FROM} # Sender address for alert e-mails.
      - ALERT_EMAIL_PASS=${ALERT_EMAIL_PASS} # SMTP "app" password established through GMail or Yahoo Mail. Do not use your everyday e-mail address.
      - ALERT_EMAIL_TO=${ALERT_EMAIL_TO} # Recipient address for alert e-mails.
      - UPDATE_YAMLS=${UPDATE_YAMLS:-true} # Set this to true to update config.yaml.
      - UPDATE_SCRIPTS=${UPDATE_SCRIPTS:-true} # Set this to true to update all included scripts.
      - TZ=${TZ} # Add your local timezone in standard linux format. E.G. US/Eastern, US/Central, US/Mountain, US/Pacific, etc.
      - PORTAINER_TOKEN=${PORTAINER_TOKEN} # Generate via <username> dropdown (upper right of WebUI), "My account", API tokens.
      - PORTAINER_HOST=${PORTAINER_HOST:-$CHANNELS_DVR_HOST} # Hostname or IP of the Docker host you're running Portainer on.
      - PORTAINER_PORT=${PORTAINER_PORT:-9443} # https port you're running Portainer on. 9443 is the default.
      - PORTAINER_ENV=${PORTAINER_ENV:-2} # Set this is if you're using an alternate Portainer Environment for some reason. 2 is the default.
      - PERSISTENT_LOGS=${PERSISTENT_LOGS:-false} # For supported Actions, log files are retained on an ongoing basis. false is the default.
    volumes:
      - ${HOST_DIR:-olivetin}${EZ_START:-/olivetin}:/config # Add the parent directory on your Docker you'd like to use.
      - ${DVR_SHARE:-olivetin}${EZ_START}:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR network share.
      - ${LOGS_SHARE:-olivetin}${EZ_START}:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT}_logs # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR logs network share.
      - ${TUBEARCHIVIST_SHARE:+${TUBEARCHIVIST_SHARE}:/mnt/${CHANNELS_DVR_HOST}-${CHANNELS_DVR_PORT}_ta} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your TubeArchivist videos network share.
      - ${DVR2_SHARE}:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT} # Note that these volume mounts should always be to /mnt/hostname-port or /mnt/ip-port (dash rather than a colon between).
      - ${LOGS2_SHARE}:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT}_logs # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR logs network share.
      - ${TUBEARCHIVIST2_SHARE}:/mnt/${CHANNELS_DVR2_HOST}-${CHANNELS_DVR2_PORT}_ta} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your TubeArchivist videos network share.     
      - ${DVR3_SHARE}:/mnt/${CHANNELS_DVR3_HOST}-${CHANNELS_DVR3_PORT} # Note that these volume mounts should always be to /mnt/hostname-port or /mnt/ip-port (dash rather than a colon between).
      - ${LOGS3_SHARE}:/mnt/${CHANNELS_DVR3_HOST}-${CHANNELS_DVR3_PORT}_logs # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your Channels DVR logs network share.
      - ${TUBEARCHIVIST3_SHARE}:/mnt/${CHANNELS_DVR3_HOST}-${CHANNELS_DVR3_PORT}_ta} # This can either be a Docker volume or a host directory that's connected via Samba or NFS to your TubeArchivist videos network share.
      - /var/run/docker.sock:/var/run/docker.sock
    restart: unless-stopped

  static-file-server:
    image: halverneus/static-file-server:latest
    container_name: ${SFS_NAME:-static-file-server}${EZ_START}
    dns_search: ${DOMAIN}
    ports:
      - ${HOST_SFS_PORT:-8080}:8080
    environment:
      - FOLDER=${FOLDER:-/web}
    volumes:
      - ${HOST_DIR}/olivetin/data:${FOLDER:-/web}
    restart: unless-stopped

volumes: # use this section if you've setup a docker volume named channels-dvr, with CIFS or NFS, to bind to /mnt/dvr inside the container. Set ${DVR_SHARE} to channels-dvr (DVR_SHARE=channels_dvr) in that example.
  olivetin-ezstart:
    name: olivetin-ezstart
  channels-dvr:
    external: true
  channels-dvr-logs:
    external: true
  tubearchivist:
    external: true
  channels-dvr2:
    external: true
  channels-dvr-logs2:
    external: true
  tubearchivist2: 
    external: true

If you notice anything I may have messed up please let me know.

TAG=latest
DOMAIN=local
HOST_PORT=1337
CHANNELS_DVR_HOST=192.168.50.219
CHANNELS_DVR_PORT=8089
CHANNELS_DVR2_HOST=192.168.50.32
CHANNELS_DVR2_PORT=8089
CHANNELS_DVR3_HOST=192.168.50.149
CHANNELS_DVR3_PORT=8089
ALERT_EMAIL_SERVER=
ALERT_EMAIL_FROM=
ALERT_EMAIL_PASS=
ALERT_EMAIL_TO=
UPDATE_YAMLS=true
UPDATE_SCRIPTS=true
TZ=US/Pacific
HOST_DIR=/data
DVR_SHARE=channels-dvr
LOGS_SHARE=channels-dvr-logs
TUBEARCHIVIST_SHARE=channels-dvr
DVR2_SHARE=channels-dvr2
LOGS2_SHARE=C:/ProgramData/ChannelsDVR
TUBEARCHIVIST2_SHARE=channels-dvr2
DVR3_SHARE=F:/DVR-storage/DVR
LOGS3_SHARE=C:/ProgramData/ChannelsDVR
TUBEARCHIVIST3_SHARE=F:/DVR-storage/DVR
HOST_SFS_PORT=8080
FOLDER=/web
PORTAINER_TOKEN=ptr_6Mcrj/12VVkIRmiJ1GRTEjC81+eGyLoOy6SylBOn6Xs=
PORTAINER_HOST=192.168.50.149
PORTAINER_PORT=9443
PORTAINER_ENV=2
PERSISTENT_LOGS=false