jbh-cloud/spotify_sync

Docker support?

mikedhanson opened this issue ยท 9 comments

Any thoughts on running this from docker?

I am an avid unraid user and think that having this run via docker would make sense. Dockerfile could look something like this?

requirements.txt

spot_sync

dockerfile

#https://docs.docker.com/language/python/build-images/ 

#base image
FROM python:3.8-slim-buster

#Set Environment Vars for docker
ENV ConfigPath = **None** \
	DownloadPath = **None** \
	arl = **None** \
	SpotID = **None** \ 
	SpotSecret = **None** \ 
	SpotRedirect = **None** \ 
	DiscordBotToken = **None** \ 
	CHANNEL = **None** 

WORKDIR /usr/src/app
COPY requirements.txt ./

# install spot_sync from requirements 
RUN pip3 install --no-cache-dir --upgrade pip && pip install --no-cache-dir -r requirements.txt

COPY . .

# cmd to run container at start
CMD [ "python3", "./SpotifyRemix.py" ]

Wow this would be great to see in this package! Any thoughts @jbh-cloud?

@danielcharrua the main reason I've held off on this is that currently spotify_sync stores all of its state in user data. This includes which songs have been matched, downloaded etc. Adding docker to the mix would warrant the need to do bind volume mounting to ensure it still access to this from the host which kinda negates the transience of docker. Adding configuration into the mix (as a bind volume) and potentially supporting profiles would also add complexity to this.

It's possible to refactor the code base to support this configuration via environment variables etc. but would require another way to validate parameters (currently using json schema).

I'm not opposed to adding docker support but I'm not sure I understand the requirements / use case (apart from specifically running on a NAS).

Happy for anyone with an idea of how they would expect to use it to chime in :)

use cases:
running on singleboard computer (Pi)
fast easy deploying
fits well with "set and forget"
codebase for future projects
:)

Yes, also doing a daily/weekly backup of your library on a NAS running docker would be a great one.
I use docker for many other backups on services, really easy, plug & play and forget.

I have a working Dockerfile
last question - for what do you need ? -or better question where to set them?
DiscordBotToken = None \
CHANNEL = None

#21

testet on ubuntu

@erstert3st first of all, thanks for you work on this! I guess it kind of brings me back to my original usecase question. Are we wanting to replicate the exact functionality of it but just allow it to be run via docker or do we want to extend it?

Your implementation is designed to run in docker as a continuous process (while True loop) against a specific config file that is built into the image. As it stands spotify_sync is designed to be a one-shot application as opposed to long running instance. I think I would prefer a more bare-bones setup where spotify_sync is the docker entrypoint allowing power users more flexibity if they chose.

E.g

Cache spotify oauth token once (could even do this from any other machine and put the file in the right directory instead)

docker run \
   -it \ # so that we can provide oauth authorization
   --rm \ # we dont want this hanging around
   -v /mnt/local/downloads:/downloads \ # can map this to whatever you want, needs to be consistent with config.json
   -v /mnt/local/spotify_sync_pd:/root/.config/spotify_sync \ # This could even be left out if you didn't care about losing which songs had been processed..
   -v /mnt/local/spotify_sync_configs:/configs \ # One or more configs to pass through to container for use with `--config` or `--profile`
   --name spotify_sync \
   spotify_sync:latest \
   utils authorize-spotify --config /configs/user1.json   

The run it..

docker run \
   --rm \ 
   ...
   spotify_sync:latest \
   run auto --config /configs/user1.json   

If people are fine with this, it means no code change (apart from a Dockerfile and no needing to maintain a separate docker script / runtime etc. This would also mean you could schedule it just as before using cron.

first the loop thing,
yea i understand that point, I need to run it in a loop for my project but your solution is better because if somebody needs to run in a loop he can loop the container anyway

The other thing, I'm fine with this but it's not the Docker way, to depend on an external file that is needed to work.
Normally you would set the envVars in Dockerfile/Composer... and that's it, maybe load them into config or into configCreatingProcess(like mine commit) or use your normal config creating thing and then replace the Values with Python or shell script but I don't know how the authentification thing work so yea other short question:
How much work do you think is it to download each playlist into their separate Folder- same structure as yours except that the root has the playlist name/
Big Thanks for your project :D
btw hope you understand my English ๐Ÿ˜…

Sorry I have been really busy and haven't had much time. First of all, I completely agree that volume bind mounts pretty much go against the whole point of docker. I would love to support completely argument parsed configuration. However this is currently hindered by:

  • Complex data structures as environment variables, how would we pass our list of excluded playlists to the app via var without doing something gross like a json string
  • Oauth, it would be super easy to do this if we didn't need to authenicate to Spotify with a user grant. In order for spotify_sync to access your private songs and playlists it must fetch and store this token. Without it, you would need to 'reauthorize' the app every run (which isn't automatic in it's current state).

I have some thoughts about how this may work going forward but would be a significant rewrite to faciliate.

In the interim, here is a fully working example running it via volume mounts. It also allows you to access all of the subcommands (as these are just passed in as paramters to the entrypoint...

FROM python:3.10-slim-buster

ARG VERSION

WORKDIR /app

RUN pip3 install --no-cache-dir --upgrade pip && pip install spot_sync==${VERSION} --no-cache-dir

ENTRYPOINT ["spotify_sync"]

# Suuuper basic scratch dockerfile workaround for people wanting to test docker functionality
# This allows you to run with volume binds without losing access to (primarily) OAuth token

# Build image with:
# docker build --build-arg VERSION=1.1.1 --pull --rm -f Dockerfile -t spotify-sync:1.1.1 . --no-cache

# Run

# Assumes the following:
# $(pwd)/cfgs exists and contains a config.json with a download path of /downloads
# $(pwd)/dl exists and is empty
# $(pwd)/pd exists and is empty

# Cache oauth token..
# docker run -it -v $(pwd)/cfgs:/configs -v :/downloads -v $(pwd)/pd:/root/.local/share/spotify_sync/ spotify-sync:1.1.1 utils authorize-spotify --config /configs/config.json
# You will see that we have some important data in $(pwd)/pd
# Run in auto
# docker run -it -v $(pwd)/cfgs:/configs -v $(pwd)/dl:/downloads -v $(pwd)/pd:/root/.local/share/spotify_sync/ spotify-sync:1.1.1 run auto --config /configs/config.json