Can you stop the OliveTin stack and then delete it?
Yes, it looks like it will let me do that.
Should I delete it and reinstall?
Yes. Generate a fresh Portainer token first, and store it in a safe place. Then create your OliveTin stack using the latest OliveTin compose from here:
The Healthcheck posts you made here show many of the values you'll need for the environment variables section.
I added everything and keep getting an error deploying the stack. It says EZ Start variable not set - defaulting to blank string. What is that? I entered all of the variables.
It sounds like you're misinterpreting the message you're seeing regarding why the stack isn't deploying. There will often be informational (or warning) messages along with an actual error.
When a stack doesn't deploy be sure to look at the entire message. More often than not, the reason for the failure is found at the end of the message, not at the beginning.
If it's not clear to you why the stack isn't deploying, see if you can capture the entire error message and post it here.
Here is the deployment error:
> failed to deploy a stack: time="2025-07-02T23:22:54Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-07-02T23:22:54Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-07-02T23:22:54Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-07-02T23:22:54Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." services.olivetin.volumes array items[4,7] must be unique.
Below are the variables:
> name
> TAG
>
> value
> latest
> name
> DOMAIN
>
> value
> 192.168.150.242
> name
> HOST_PORT
>
> value
> 1337
> name
> CHANNELS_DVR_HOST
>
> value
> 192.168.150.242
> name
> ALERT_SMTP_SERVER
>
> value
> smtp.gmail.com:587
> name
> ALERT_EMAIL_TO
>
> value
> @gmail.com
> name
> ALERT_EMAIL_FROM
>
> value
> @gmail.com
> name
> ALERT_EMAIL_PASS
>
> value
> XXXXXXX
> name
> CHANNELS_DVR_HOST
>
> value
> 192.168.150.242:8089
> name
> TZ
>
> value
> US/Central
> name
> UPDATE_YAMLS
>
> value
> true
> name
> UPDATE_SCRIPTS
>
> value
> true
> name
> CHANNELS_CLIENTS
>
> value
> 92.168.150.231 192.168.150.194 146.12.197.19 192.168.150.177
> name
> PORTAINER_TOKEN
>
> value
> ptr_CKemMBtE8e9GNUCbSCdkWiutGJMOG8oRI7THHIc+U54=
> name
> PORTAINER_PORT
>
> value
> 9443
> name
> PORTAINER_HOST
>
> value
> 192.168.150.242
> name
> HOST_DIR
>
> value
> /Users/jasontrippe
> name
> PERSISTENT_LOGS
>
> value
> false
> name
> PORTAINER_ENV
>
> value
> 2
> name
> HOST_SFS_PORT
>
> value
> 8080
> name
> CHANNELS_DVR2_HOST
>
> value
> e.g. bar
> name
> CHANNELS_DVR3_HOST
>
> value
> e.g. bar
> name
> CHANNELS_DVR2_PORT
>
> value
> e.g. bar
> name
> CHANNELS_DVR3_PORT
>
> value
> e.g. bar
> name
> DOMAIN
>
> value
> 192.168.150.242
> name
> DVR_SHARE
>
> value
> Volumes/External Drive/Channels DVR
> name
> LOGS_SHARE
>
> value
> Volumes/External Drive/Channels DVR
> name
> TUBEARCHIVIST_SHARE
>
> value
> Volumes/External Drive/Channels DVR
> name
> FOLDER
>
> value
> /web
> name
> DVR2_SHARE
>
> value
> e.g. bar
> name
> LOGS2_SHARE
>
> value
> e.g. bar
> name
> TUBEARCHIVIST2_SHARE
>
> value
> e.g. bar
> name
> DVR3_SHARE
>
> value
> e.g. bar
> name
> LOGS3_SHARE
>
> value
> e.g. bar
> name
> TUBEARCHIVIST3_SHARE
>
> value
> e.g. bar
> name
> CHANNELS_DVR_PORT
>
> value
> 8089
I'm not sure where you're getting this bizarre presentation of the env vars from. But, what you should be doing, is going into the Portainer-Stacks editor, selecting Advanced mode and then copy and paste the contents. Be sure to REDACT anything sensitive. Here's mine for example:
TAG=latest
DOMAIN=localdomain tailxxxxx.ts.net
HOST_PORT=1337
CHANNELS_DVR_HOST=media-server8
CHANNELS_DVR_PORT=8089
CHANNELS_DVR2_HOST=utheater-pc
CHANNELS_DVR2_PORT=8089
CHANNELS_DVR3_HOST=192.168.110.66
CHANNELS_DVR3_PORT=8089
CHANNELS_CLIENTS=appletv4k firestick-master
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
TZ=US/Mountain
HOST_DIR=/data
DVR_SHARE=/mnt/dvr
LOGS_SHARE=/mnt/channelsdvr
TUBEARCHIVIST_SHARE=/mnt/dvr
DVR2_SHARE=
LOGS2_SHARE=
TUBEARCHIVIST2_SHARE=
DVR3_SHARE=
LOGS3_SHARE=
TUBEARCHIVIST3_SHARE=
HOST_SFS_PORT=8081
FOLDER=/web
PORTAINER_TOKEN=[Redacted]
PORTAINER_HOST=htpc6
PORTAINER_PORT=9443
PORTAINER_ENV=2
PERSISTENT_LOGS=false
This is your actual error btw. See how everything else says level=warning. Info and warning messages, are just that, and are not actual errors.
Here are my variables from advanced mode:
> DOMAIN=192.168.150.242
> HOST_PORT=1337
> CHANNELS_DVR_HOST=192.168.150.242
> ALERT_SMTP_SERVER=smtp.gmail.com:587
> [email protected]
> [email protected]
> ALERT_EMAIL_PASS=redacted
> CHANNELS_DVR_HOST=192.168.150.242:8089
> TZ=US/Central
> UPDATE_YAMLS=true
> UPDATE_SCRIPTS=true
> CHANNELS_CLIENTS=192.168.150.231 192.168.150.194 146.12.197.19 192.168.150.177
> PORTAINER_TOKEN=redacted
> PORTAINER_PORT=9443
> PORTAINER_HOST=192.168.150.242
> HOST_DIR=/Users/jasontrippe
> PERSISTENT_LOGS=false
> PORTAINER_ENV=2
> HOST_SFS_PORT=8080
> CHANNELS_DVR2_HOST=
> CHANNELS_DVR3_HOST=
> CHANNELS_DVR2_PORT=
> CHANNELS_DVR3_PORT=
> DOMAIN=192.168.150.242
> DVR_SHARE=Volumes/External Drive/Channels DVR
> LOGS_SHARE=Volumes/External Drive/Channels DVR
> TUBEARCHIVIST_SHARE=Volumes/External Drive/Channels DVR
> FOLDER=/web
> DVR2_SHARE=
> LOGS2_SHARE=
> TUBEARCHIVIST2_SHARE=
> DVR3_SHARE=
> LOGS3_SHARE=
> TUBEARCHIVIST3_SHARE=
> CHANNELS_DVR_PORT=8089
'''
This is not correct. Your LAN's domain name can be left blank if you don't know it, don't have Tailscale installed, and are happy to use IP addresses for everything.
You've duplicated a number of entries, including this one, which is probably the cause for error.
Here's the list of sample variables from the post I linked for you:
TAG=latest
DOMAIN=localdomain tailxxxxx.ts.net
HOST_PORT=1337
CHANNELS_DVR_HOST=local-server
CHANNELS_DVR_PORT=8089
CHANNELS_DVR2_HOST=another-server
CHANNELS_DVR2_PORT=8089
CHANNELS_DVR3_HOST=a-third-server
CHANNELS_DVR3_PORT=8089
CHANNELS_CLIENTS=appletv4k firestick-master amazon-aftkrt
ALERT_SMTP_SERVER=smtp.gmail.com:587
[email protected]
ALERT_EMAIL_PASS=xxxxxxxxxxxxxxxx
[email protected]
UPDATE_YAMLS=true
UPDATE_SCRIPTS=true
TZ=US/Mountain
HOST_DIR=/data
DVR_SHARE=/mnt/dvr
LOGS_SHARE=/mnt/channelsdvr
TUBEARCHIVIST_SHARE=/mnt/dvr
DVR2_SHARE=
LOGS2_SHARE=
TUBEARCHIVIST2_SHARE=
DVR3_SHARE=
LOGS3_SHARE=
TUBEARCHIVIST3_SHARE=
HOST_SFS_PORT=8080
FOLDER=/web
PORTAINER_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PORTAINER_HOST=docker-host
PORTAINER_PORT=9443
PORTAINER_ENV=2
PERSISTENT_LOGS=false
You have several incorrect variables in what you posted, plus duplicates, plus missing variables. Please take another pass at this and post you're values here for me to look at.
Here are my new variables:
> DOMAIN=
> HOST_PORT=1337
> CHANNELS_DVR_HOST=192.168.150.242
> CHANNELS_DVR_PORT=8089
> CHANNELS_DVR2_HOST=
> CHANNELS_DVR2_PORT=
> CHANNELS_DVR3_HOST=
> CHANNELS_DVR3_PORT=
> CHANNELS_CLIENTS=192.168.150.231 192.168.150.194 146.12.197.19 192.168.150.177
> ALERT_SMTP_SERVER=smtp.gmail.com:587
> [email protected]
> ALERT_EMAIL_PASS=redacted
> [email protected]
> UPDATE_YAMLS=true
> UPDATE_SCRIPTS=true
> TZ=US/Central
> HOST_DIR=/Users/jasontrippe
> DVR_SHARE=Volumes/External Drive/Channels DVR
> LOGS_SHARE=Volumes/External Drive/Channels DVR
> TUBEARCHIVIST_SHARE=Volumes/External Drive/Channels DVR
> DVR2_SHARE=
> LOGS2_SHARE=
> TUBEARCHIVIST2_SHARE=
> DVR3_SHARE=
> LOGS3_SHARE=
> TUBEARCHIVIST3_SHARE=
> HOST_SFS_PORT=8080
> FOLDER=/web
> PORTAINER_TOKEN=redacted
> PORTAINER_HOST=docker-host
> PORTAINER_PORT=9443
> PORTAINER_ENV=2
> PERSISTENT_LOGS=false
Looking better, though I'm sure your CDVR programs are not stored here. But let's leave this one as-is for the moment.
I'm almost certain this is wrong, as it's the sample value. If you're running on a Mac (which it looks like you are), and you have CDVR and Docker/Portainer all on the same computer -- then this value would be 192.168.150.242 too.
This seems wrong as well, as your Channels clients should all be on the same subnet, i.e. 192.168.150.xxx. What's with the 146.12.197.19 value?
Ok, I changed the portainer host. That didn't work. The 146 domain is correct. It is my in-laws house. Do I have to list every single client, as there are a bunch for us?
The client IPs are mostly for sending messages to all clients, and you only need to list those on your local network. Remote systems could only be reached if you used Tailscale.
What do you mean by this? Are you seeing the exact same error message? If not, please post the new error.
I changed the Portainer host to my local domain. The error looks the same:
> failed to deploy a stack: time="2025-07-03T00:37:44Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-07-03T00:37:44Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-07-03T00:37:44Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." time="2025-07-03T00:37:44Z" level=warning msg="The \"EZ_START\" variable is not set. Defaulting to a blank string." services.olivetin.volumes array items[4,7] must be unique```
I see it now. As the error suggests the problem is with the above. Without a leading slash these paths are assumed to be volumes -- which is not what you're intending. Add the leading slashes to indicate directory paths, and you should be good.
Changed to the below and still the same error:
DVR_SHARE=/Volumes/External Drive/Channels DVR
LOGS_SHARE=/Volumes/External Drive/Channels DVR
TUBEARCHIVIST_SHARE=/Volumes/External Drive/Channels DVR
Could you post the Docker compose you're using for OliveTin please?
See below.
> 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.27
> # 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.03.26${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_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:-/unused}${HOST_DIR:+/olivetin:/config} # Add the parent directory on your Docker 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```