srichter / asksonic

An Alexa skill to play music from Subsonic API compatible music servers
MIT License
60 stars 17 forks source link

REQUEST: Docker install #5

Open ghost opened 3 years ago

ghost commented 3 years ago

Would a docker install option be out of the question for a self-hosted server?

srichter commented 3 years ago

It's not something I'd have a use for myself, but if someone built an image I'd accept a PR.

alxrdn commented 3 years ago

hi !

I personally wrote this Dockerfile which I use as a daily :

FROM python:3.9-alpine

ADD ./asksonic /app
ADD ./.env /app

WORKDIR /app
RUN apk add --update gcc libc-dev libffi-dev openssl-dev git nodejs npm
RUN pip3 install --upgrade pip
RUN pip3 install -r ./requirements.txt
RUN npm install -g foreman

ENV PYTHONPATH=/usr/local/lib/python3.5/site-packages
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8

CMD ["nf", "start"]
tam481 commented 2 years ago

I'm not a docker expert but I would love to use a docker version so I'm adding my +1 to the original request :-)

tam481 commented 2 years ago

@alxrdn I'm trying to use the code above in a Dockerfile but I keep getting "Step 2/12 : ADD /.asksonic /app ADD failed: file not found in build context or excluded by .dockerignore: stat asksonic: file does not exist"

Where do I get /.asksonic from?

alxrdn commented 2 years ago

@alxrdn I'm trying to use the code above in a Dockerfile but I keep getting "Step 2/12 : ADD /.asksonic /app ADD failed: file not found in build context or excluded by .dockerignore: stat asksonic: file does not exist"

Where do I get /.asksonic from?

you have to clone the repo in order to be able to build a docker image based on it

you should have a tree such as this :

$ ls
asksonic  docker-compose.yml  Dockerfile

$ ls asksonic/
app.json  asksonic  interactionModel.json  LICENSE  Procfile  Procfile.dev  Procfile.PROD  README.md  requirements.txt  runtime.txt  server.py  setup.cfg
tam481 commented 2 years ago

That's exactly what I have minus the docker-compose.yml file

/image # ls -l total 8 drwxr-xr-x 5 root root 4096 Dec 5 20:58 asksonic -rw-r--r-- 1 root root 355 Dec 5 20:55 Dockerfile

/image # ls -lah asksonic/ total 76K drwxr-xr-x 5 root root 4.0K Dec 5 20:58 . drwxr-xr-x 3 root root 4.0K Dec 5 20:58 .. -rw-r--r-- 1 root root 1.6K Dec 5 20:58 app.json drwxr-xr-x 5 root root 4.0K Dec 5 20:58 asksonic -rw-r--r-- 1 root root 358 Dec 5 20:58 .env.example drwxr-xr-x 8 root root 4.0K Dec 5 20:58 .git drwxr-xr-x 3 root root 4.0K Dec 5 20:58 .github -rw-r--r-- 1 root root 1.8K Dec 5 20:58 .gitignore -rw-r--r-- 1 root root 7.8K Dec 5 20:58 interactionModel.json -rw-r--r-- 1 root root 1.1K Dec 5 20:58 LICENSE -rw-r--r-- 1 root root 90 Dec 5 20:58 Procfile -rw-r--r-- 1 root root 44 Dec 5 20:58 Procfile.dev -rw-r--r-- 1 root root 6.2K Dec 5 20:58 README.md -rw-r--r-- 1 root root 115 Dec 5 20:58 requirements.txt -rw-r--r-- 1 root root 13 Dec 5 20:58 runtime.txt -rw-r--r-- 1 root root 194 Dec 5 20:58 server.py -rw-r--r-- 1 root root 33 Dec 5 20:58 setup.cfg

This is the command I'm using to build the image: docker build - < Dockerfile

tam481 commented 2 years ago

Ignore that. I managed to do it with "docker build -t asksonic ."

alxrdn commented 2 years ago

That's exactly what I have minus the docker-compose.yml file

/image # ls -l total 8 drwxr-xr-x 5 root root 4096 Dec 5 20:58 asksonic -rw-r--r-- 1 root root 355 Dec 5 20:55 Dockerfile

/image # ls -lah asksonic/ total 76K drwxr-xr-x 5 root root 4.0K Dec 5 20:58 . drwxr-xr-x 3 root root 4.0K Dec 5 20:58 .. -rw-r--r-- 1 root root 1.6K Dec 5 20:58 app.json drwxr-xr-x 5 root root 4.0K Dec 5 20:58 asksonic -rw-r--r-- 1 root root 358 Dec 5 20:58 .env.example drwxr-xr-x 8 root root 4.0K Dec 5 20:58 .git drwxr-xr-x 3 root root 4.0K Dec 5 20:58 .github -rw-r--r-- 1 root root 1.8K Dec 5 20:58 .gitignore -rw-r--r-- 1 root root 7.8K Dec 5 20:58 interactionModel.json -rw-r--r-- 1 root root 1.1K Dec 5 20:58 LICENSE -rw-r--r-- 1 root root 90 Dec 5 20:58 Procfile -rw-r--r-- 1 root root 44 Dec 5 20:58 Procfile.dev -rw-r--r-- 1 root root 6.2K Dec 5 20:58 README.md -rw-r--r-- 1 root root 115 Dec 5 20:58 requirements.txt -rw-r--r-- 1 root root 13 Dec 5 20:58 runtime.txt -rw-r--r-- 1 root root 194 Dec 5 20:58 server.py -rw-r--r-- 1 root root 33 Dec 5 20:58 setup.cfg

This is the command I'm using to build the image: docker build - < Dockerfile

i'm not building the docker image by hand but through docker-compose, you can try this :

$ cat docker-compose.yml

version: "2.4"

services:
  asksonic:
    build: .
    image: local/asksonic
    container_name: asksonic
    restart: unless-stopped
tam481 commented 2 years ago

Thank you for that. I managed to build the image but when I start it I get the following error:

[OKAY] Loaded ENV .env File as KEY=VALUE Format 7:47:24 PM web.1 | [2021-12-06 19:47:24 +0000] [13] [INFO] Starting gunicorn 20.1.0 7:47:24 PM web.1 | [2021-12-06 19:47:24 +0000] [13] [INFO] Listening at: http://0.0.0.0:4545 (13) 7:47:24 PM web.1 | [2021-12-06 19:47:24 +0000] [13] [INFO] Using worker: sync 7:47:24 PM web.1 | [2021-12-06 19:47:24 +0000] [14] [INFO] Booting worker with pid: 14 7:47:25 PM web.1 | [2021-12-06 19:47:24 +0000] [14] [ERROR] Exception in worker process 7:47:25 PM web.1 | Traceback (most recent call last): 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker 7:47:25 PM web.1 | worker.init_process() 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/base.py", line 134, in init_process 7:47:25 PM web.1 | self.load_wsgi() 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi 7:47:25 PM web.1 | self.wsgi = self.app.wsgi() 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/app/base.py", line 67, in wsgi 7:47:25 PM web.1 | self.callable = self.load() 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/app/wsgiapp.py", line 58, in load 7:47:25 PM web.1 | return self.load_wsgiapp() 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp 7:47:25 PM web.1 | return util.import_app(self.app_uri) 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/site-packages/gunicorn/util.py", line 359, in import_app 7:47:25 PM web.1 | mod = importlib.import_module(module) 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/importlib/init.py", line 127, in import_module 7:47:25 PM web.1 | return _bootstrap._gcd_import(name[level:], package, level) 7:47:25 PM web.1 | File "", line 1030, in _gcd_import 7:47:25 PM web.1 | File "", line 1007, in _find_and_load 7:47:25 PM web.1 | File "", line 986, in _find_and_load_unlocked 7:47:25 PM web.1 | File "", line 680, in _load_unlocked 7:47:25 PM web.1 | File "", line 850, in exec_module 7:47:25 PM web.1 | File "", line 228, in _call_with_frames_removed 7:47:25 PM web.1 | File "/app/asksonic/init.py", line 21, in 7:47:25 PM web.1 | from . import intents 7:47:25 PM web.1 | File "/app/asksonic/intents/init.py", line 1, in 7:47:25 PM web.1 | from asksonic.utils.queue.queue_manager import QueueManager 7:47:25 PM web.1 | File "/app/asksonic/utils/queue/queue_manager.py", line 8, in 7:47:25 PM web.1 | from asksonic.utils.subsonic.track import Track 7:47:25 PM web.1 | File "/app/asksonic/utils/subsonic/init.py", line 18, in 7:47:25 PM web.1 | subsonic = Subsonic( 7:47:25 PM web.1 | File "/app/asksonic/utils/subsonic/api.py", line 16, in init 7:47:25 PM web.1 | super().init( 7:47:25 PM web.1 | File "/usr/local/lib/python3.9/site-packages/libsonic/connection.py", line 157, in init 7:47:25 PM web.1 | self._hostname = baseUrl.split('://')[1].strip() 7:47:25 PM web.1 | IndexError: list index out of range 7:47:25 PM web.1 | [2021-12-06 19:47:25 +0000] [14] [INFO] Worker exiting (pid: 14) 7:47:25 PM web.1 | [2021-12-06 19:47:25 +0000] [13] [INFO] Shutting down: Master 7:47:25 PM web.1 | [2021-12-06 19:47:25 +0000] [13] [INFO] Reason: Worker failed to boot. [DONE] Killing all processes with signal SIGINT 7:47:25 PM web.1 Exited with exit code null

Any ideas what's causing this?

srichter commented 2 years ago

Any ideas what's causing this?

Make sure your ASKS_SUBSONIC_URL includes https://

tam481 commented 2 years ago

Thank you so much. That fixed it.

jinyeow commented 2 years ago

Trying to run this through Docker. Followed your instructions above and have the docker container running. Followed the instructions to setup the Alexa Skill.

But when I test it, it always plays/tries to play from Alexa Music.

Any ideas?

kambho commented 2 years ago

Hey all,

Firstly, excellent idea to get this all containerised! I'm still coming to grips with Docker but it's really cool stuff!

I've tried setting it all up using the Dockerfile and docker-compose.yml files above, but when running the Dockerfile, I'm getting issues with: RUN pip3 install -r ./requirements.txt where I get: ERROR: Could not open requirements file: [Errno 2] No such file or directory: './requirements.txt' Any idea on how to get past this? I used git clone to pull the entire contents down.

I've also tried eradicating the requirements.txt file and putting it all into the Dockerfile, but then I get this:

Step 7/15 : RUN pip3 install Flask-Ask @ git+https://github.com/srichter/flask-ask.git@flask2
 ---> Running in d3afae74f57a
ERROR: Invalid requirement: '@'
ERROR: Service 'asksonic' failed to build: The command '/bin/sh -c pip3 install Flask-Ask @ git+https://github.com/srichter/flask-ask.git@flask2' returned a non-zero code: 1

So currently a bit stuck.

On a separate note, would we need to open up a specific port to access this externally? If so, what port are we binding to?

srichter commented 2 years ago

But when I test it, it always plays/tries to play from Alexa Music.

What's the phrase you're giving to Alexa?

I've tried setting it all up using the Dockerfile and docker-compose.yml files above, but when running the Dockerfile, I'm getting issues with:

Is Asksonic being mounted at /app?

If so, what port are we binding to?

4545 by default, you can specify it with the env var ASKS_PORT

kambho commented 2 years ago

Hey,

Is Asksonic being mounted at /app?

My folder layout is the same as https://github.com/srichter/asksonic/issues/5#issuecomment-986269388, so i've just changed ./ to ./asksonic/ in my Dockerfile and it's mounting Asksonic at /app, it's just when it's running the Dockerfile steps it breaks at Step 7:

Building asksonic
Step 1/12 : FROM python:3.9-alpine
 ---> 1b2eadcedc98
Step 2/12 : ADD ./asksonic/asksonic /app
 ---> Using cache
 ---> c28a0b530be6
Step 3/12 : ADD ./asksonic/.env /app
 ---> Using cache
 ---> 6cb1f8ffd192
Step 4/12 : WORKDIR /app
 ---> Using cache
 ---> 0d28493669cb
Step 5/12 : RUN apk add --update gcc libc-dev libffi-dev openssl-dev git nodejs npm
 ---> Using cache
 ---> b9f41b2ca056
Step 6/12 : RUN pip3 install --upgrade pip
 ---> Using cache
 ---> 68457113c611
Step 7/12 : RUN pip3 install -r ./asksonic/requirements.txt
 ---> Running in f47d7c3848cd
ERROR: Could not open requirements file: [Errno 2] No such file or directory: './asksonic/requirements.txt'
ERROR: Service 'asksonic' failed to build: The command '/bin/sh -c pip3 install -r ./asksonic/requirements.txt' returned a non-zero code: 1

4545 by default, you can specify it with the env var ASKS_PORT

Thanks for this! I've got to map a port, so i'll play with the .env and docker-compose.yml :)

kambho commented 2 years ago

Ok so I've managed to get the container running with an edited Dockerfile:

FROM python:3.9-alpine

ADD ./asksonic /app
ADD ./asksonic/.env /app

WORKDIR /app
RUN apk add --update gcc libc-dev libffi-dev openssl-dev git nodejs npm
RUN pip3 install --upgrade pip
# RUN pip3 install -r ./asksonic/requirements.txt
RUN pip3 install git+https://github.com/srichter/flask-ask.git@flask2
RUN pip3 install gunicorn==20.1.0
RUN pip3 install py-sonic==0.7.9
RUN pip3 install requests==2.25.1
RUN npm install -g foreman

ENV PYTHONPATH=/usr/local/lib/python3.5/site-packages
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8

CMD ["nf", "start"]

Progress is being made slowly!

jinyeow commented 2 years ago

But when I test it, it always plays/tries to play from Alexa Music.

What's the phrase you're giving to Alexa?

i've tried a few "navi navi", "stream music", "stream navi", "stream sonic", "sonic music", etc. So e.g. Alexa, stream music from [artist]. or Alexa, navi sonic from [artist]. Which gives me either Amazon music, or it just can't play from my hosted music server.

I've tried setting it all up using the Dockerfile and docker-compose.yml files above, but when running the Dockerfile, I'm getting issues with:

Is Asksonic being mounted at /app?

yes

If so, what port are we binding to?

4545 by default, you can specify it with the env var ASKS_PORT

I left 4545 as is. I'm binding 10443:443 and nginx directs 443 traffic to that container:10443.

kambho commented 2 years ago

Update: I've managed to get the container up and running, and I've built the skill in Amazon Console. I am however having issues with the skill connecting to my container. Alexa is looking for an https, but I'm serving it on http, so that's my next issue. Although it could also be that it's only available on a specific port and Amazon Console doesn't like it. Either way, the skill in the Console builds successfully, but when it comes to testing, it fails.

i've tried a few "navi navi", "stream music", "stream navi", "stream sonic", "sonic music", etc. So e.g. Alexa, stream music from [artist]. or Alexa, navi sonic from [artist]. Which gives me either Amazon music, or it just can't play from my hosted music server.

I think you either say 'ask subsonic' or whatever you called the skill in Amazon Console.

jinyeow commented 2 years ago

yes. I've changed the invocation to a few different things, hoping to get it to connect. but whatever I try it does not run properly

srichter commented 2 years ago

i've tried a few "navi navi", "stream music", "stream navi", "stream sonic", "sonic music", etc.

You'll need to say Alexa, tell [navi navi] to [play my library]. You can also just say Alexa, tell [navi navi] and then it will start the app and prompt you for a command.

Alexa is looking for an https, but I'm serving it on http, so that's my next issue.

Yeah it needs to be available on 443 via https with a valid certificate

prophead commented 2 years ago

Add this to Dockerfile to fix requirements.txt issue: ADD ./requirements.txt /app

davidclaeysquinones commented 1 year ago

I've tried to make a Dockerfile for myself

FROM python:3.9-alpine

ENV SUBSONIC_PORT=443
ENV PORT=4545

ADD ./asksonic /app
ADD ./requirements.txt /app
ADD ./Procfile /app

RUN echo "ASKS_SUBSONIC_URL=$SUBSONIC_URL" > /app/.env
RUN echo "ASKS_SUBSONIC_USER=$SUBSONIC_USER" > /app/.env
RUN echo "ASKS_SUBSONIC_PASS=$SUBSONIC_PASS" > /app/.env
RUN echo "ASKS_SUBSONIC_PORT=$SUBSONIC_PORT" > /app/.env
RUN echo "ASKS_PORT=$PORT" > /app/.env

WORKDIR /app

RUN apk add -U --no-cache gcc libc-dev python3-dev openssl-dev musl-dev libffi-dev cargo pkgconfig git nodejs
#RUN apk add --update gcc libc-dev libffi-dev openssl-dev git nodejs npm
RUN pip3 install --upgrade pip
RUN pip3 install pyopenssl==17.5.0
RUN pip3 install cryptography==2.1.4
# RUN pip3 install -r ./asksonic/requirements.txt
RUN pip3 install git+https://github.com/srichter/flask-ask.git@flask2
RUN pip3 install gunicorn==20.1.0
RUN pip3 install py-sonic==0.7.9
RUN pip3 install requests==2.25.1
RUN npm install -g foreman

ENV PYTHONPATH=/usr/local/lib/python3.5/site-packages
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8

CMD ["nf", "start"]

On time I got it working, but I've changed something and keep getting build errors with cryptography. I'm not able to get back to a working state, so here I am. I'm no expert in building DOCKER images or in Python so my example might not be functional (I've not been able to test it). Help would be appreciated

srichter commented 1 year ago

On time I got it working, but I've changed something and keep getting build errors with cryptography. I'm not able to get back to a working state, so here I am. I'm no expert in building DOCKER images or in Python so my example might not be functional (I've not been able to test it). Help would be appreciated

If you make a discussion thread and post the exact error I can help troubleshoot

davidclaeysquinones commented 1 year ago

I made discussion #28 providing some additional details.

ruipin commented 1 year ago

The issue is that Flask-Ask requires cryptography v2, which is not compatible with OpenSSL 3.

To get everything to work, you need to force the usage of cryptography 3. You also need to update a few other dependencies, e.g. Flask.

The following Dockerfile does this:

FROM python:3.9-alpine

WORKDIR /app
RUN apk add --update gcc libc-dev libffi-dev openssl-dev git nodejs npm

RUN git clone https://github.com/srichter/asksonic.git /app

RUN pip3 install --upgrade pip

# Install Flask-Ask dependencies
RUN pip3 install aniso8601 "flask>=2.0.0,<2.2.0" "cryptography>=3.0.0" pyOpenSSL PyYAML six "Werkzeug<3.0.0" cachelib

# Install Flask-Ask
RUN pip3 install --no-dependencies git+https://github.com/srichter/flask-ask.git@flask2

# Install remaining asksonic dependencies
RUN pip3 install gunicorn py-sonic requests
RUN npm install -g foreman

# Environment
ENV PYTHONPATH=/usr/local/lib/python3.9/site-packages
ENV LC_ALL C.UTF-8
ENV LANG C.UTF-8

# Command
CMD ["nf", "start"]