steamcmd / api

Read-only API interface for steamcmd app_info
https://www.steamcmd.net
MIT License
56 stars 7 forks source link

Unable to deploy to Digital Ocean app platform #24

Closed Ortovoxx closed 3 years ago

Ortovoxx commented 3 years ago

Hello again!

I forked the api and stripped back lots of the cache and unneeded functions for my use case. Take a look at the code if you want

I have managed to successfully deploy the app to heroku and everything works perfectly. However I also tried to deploy to Digital Ocean ( using their app platform ) and came across this error in the deploy phase:

note There are no problems when building the container

starting container: starting non-root container [ /bin/bash -o pipefail -c gunicorn --workers $WORKERS --threads $THREADS --timeout $TIMEOUT --bind :$PORT run:app]: error finding executable "" in PATH [/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin]: no such file or directory

Is this an easy fix or not? As I managed to deploy to heroku I can make do with that just seems odd Digital Ocean would fail like this. I don't know if it is a Digital Ocean issue or a container issue.

HeCorr commented 3 years ago

@Ortovoxx could you try building again without this line in the Dockerfile? https://github.com/Rusty-Helper/steamcmd/blob/6ffc6e5d5d697d6cf4725441e605ff6a57e787f3/Dockerfile#L40

My guess is that Heroku ignores it for being empty (which I don't think it should be to begin with) but Digital Ocean doesn't.

It would explain the error error finding executable ""

Ortovoxx commented 3 years ago

Unfortunately it didn't work. I am just presented with a new error:

/data/.steam/steamcmd/steamcmd.sh: line 29: /data/.steam/steamcmd/linux32/steamcmd: cannot execute binary file: Exec format error
HeCorr commented 3 years ago

Does it work on Heroku though?

Looks like ARM is not supported.. what's the chance DO is not using x86..?

https://steamcommunity.com/groups/linuxgsm/discussions/0/358415738181524922/

jonakoudijs commented 3 years ago

Hi,

The reason for the ENTRYPOINT to be set to "" is to "clear" the entrypoint. The Docker image of the API uses the steamcmd/steamcmd image as the source (FROM). Because the steamcmd/steamcmd image has the steamcmd command set as the entrypoint, it will normally be inherited by the API image unless it is overwritten. This is the ENTRYPOINT as set in the steamcmd/steamcmd image:

# Set default command
ENTRYPOINT ["steamcmd"]
CMD ["+help", "+quit"]

This partly explains the new error you are getting when not including the ENTRYPOINT from the Dockerfile because it directly executes steamcmd (because that is the default ENTRYPOINT again). To fix this I would suggest not removing the ENTRYPOINT but setting it to a general shell default. I have succesfully tested the following (also I will probably change this in the steamcmd/api Dockerfile as well):

ENTRYPOINT [ "/bin/bash", "-l", "-c" ]

However it is strange that the steamcmd command cannot be executed on Digital Ocean. I did some testing with a Digital Ocean App as well and if I fix the ENTRYPOINT (as recommended before) the app succesfully deploys but errors out when trying to run gunicorn:

steamcmd-api | 2021-04-19 13:22:08 PermissionError: [Errno 1] Operation not permitted
steamcmd-api | 2021-04-19 13:22:08 [2021-04-19 11:22:08 +0000] [12172] [INFO] Worker exiting (pid: 12172)
steamcmd-api | 2021-04-19 13:22:08 [2021-04-19 11:22:08 +0000] [12174] [INFO] Booting worker with pid: 12174
steamcmd-api | 2021-04-19 13:22:08 [2021-04-19 11:22:08 +0000] [12174] [ERROR] Exception in worker process
steamcmd-api | 2021-04-19 13:22:08 Traceback (most recent call last):
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/arbiter.py", line 589, in spawn_worker
steamcmd-api | 2021-04-19 13:22:08     worker.init_process()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/gthread.py", line 92, in init_process
steamcmd-api | 2021-04-19 13:22:08     super().init_process()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/base.py", line 142, in init_process
steamcmd-api | 2021-04-19 13:22:08     self.run()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/gthread.py", line 195, in run
steamcmd-api | 2021-04-19 13:22:08     self.notify()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/base.py", line 75, in notify
steamcmd-api | 2021-04-19 13:22:08     self.tmp.notify()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/workertmp.py", line 46, in notify
steamcmd-api | 2021-04-19 13:22:08     os.fchmod(self._tmp.fileno(), self.spinner)

Executing the exact same image locally works like a charm. It seems that something is a bit different in the Digital Ocean setup when running Docker images because 1 the steamcmd fails and 2 the gunicorn server cannot run or at least not successfully process requests.

jonakoudijs commented 3 years ago

For testing I used the current Dockerfile and changed the following lines:

ENTRYPOINT [ "/bin/bash", "-l", "-c" ]
CMD ["gunicorn --workers $WORKERS --threads $THREADS --timeout $TIMEOUT --bind :$PORT run:app"]

I pushed the image to a temporary Docker repo/tag called jonakoudijs/steamcmd-test:api. Deploying was successful when using this app spec:

name: steamcmd-api
region: ams
services:
- http_port: 8080
  image:
    registry: jonakoudijs
    registry_type: DOCKER_HUB
    repository: steamcmd-test
    tag: api
  instance_count: 1
  instance_size_slug: basic-xxs
  name: steamcmd-api
  routes:
  - path: /

After deploying the Python errors mentioned earlier occur:

steamcmd-api | 2021-04-19 13:22:08 PermissionError: [Errno 1] Operation not permitted
steamcmd-api | 2021-04-19 13:22:08 [2021-04-19 11:22:08 +0000] [12172] [INFO] Worker exiting (pid: 12172)
steamcmd-api | 2021-04-19 13:22:08 [2021-04-19 11:22:08 +0000] [12174] [INFO] Booting worker with pid: 12174
steamcmd-api | 2021-04-19 13:22:08 [2021-04-19 11:22:08 +0000] [12174] [ERROR] Exception in worker process
steamcmd-api | 2021-04-19 13:22:08 Traceback (most recent call last):
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/arbiter.py", line 589, in spawn_worker
steamcmd-api | 2021-04-19 13:22:08     worker.init_process()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/gthread.py", line 92, in init_process
steamcmd-api | 2021-04-19 13:22:08     super().init_process()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/base.py", line 142, in init_process
steamcmd-api | 2021-04-19 13:22:08     self.run()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/gthread.py", line 195, in run
steamcmd-api | 2021-04-19 13:22:08     self.notify()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/base.py", line 75, in notify
steamcmd-api | 2021-04-19 13:22:08     self.tmp.notify()
steamcmd-api | 2021-04-19 13:22:08   File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/workertmp.py", line 46, in notify
steamcmd-api | 2021-04-19 13:22:08     os.fchmod(self._tmp.fileno(), self.spinner)
jonakoudijs commented 3 years ago

One sidenote. Regarding the cache; if the Cache/Redis settings are not explicitly set via environment variables this not used. This logic can be found here: https://github.com/steamcmd/api/blob/master/src/run.py#L215-L298.

It's not pretty but it works for now. In the future this should be documented in the README but.. yeah.. time is not on my side atm :)

Ortovoxx commented 3 years ago

For testing I used the current Dockerfile and changed the following lines:

ENTRYPOINT [ "/bin/bash", "-l", "-c" ]
CMD ["gunicorn --workers $WORKERS --threads $THREADS --timeout $TIMEOUT --bind :$PORT run:app"]

Updating the last bit of the docker file to this works for me. I have managed to deploy the instance to Digital Ocean and it builds and deploys fine and I get a URL for the app.

but errors out when trying to run gunicorn

I haven't been able to reproduce this error mine took s a while to boot up but works perfectly first time

However looking at the logs I don't get a gunicorn error like you suggested instead I get a process error:

/data/.steam/steamcmd/steamcmd.sh: line 29: /data/.steam/steamcmd/linux32/steamcmd: cannot execute binary file: Exec format error
[2021-04-19 16:19:35 +0000] [6] [ERROR] Error handling request /info/server
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/gthread.py", line 271, in handle
    keepalive = self.handle_request(req, conn)
  File "/usr/local/lib/python3.6/dist-packages/gunicorn/workers/gthread.py", line 323, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/data/run.py", line 238, in app
    output = steamcmd(gameid)
  File "/data/run.py", line 142, in steamcmd
    out = check_output(cmd)
  File "/usr/lib/python3.6/subprocess.py", line 356, in check_output
    **kwargs).stdout
  File "/usr/lib/python3.6/subprocess.py", line 438, in run
    output=stdout, stderr=stderr)
subprocess.CalledProcessError: Command '['steamcmd', '+login', 'anonymous', '+app_info_update', '1', '+app_info_print', '258550', '+quit']' returned non-zero exit status 126.

Mind you I have slightly modified the original code so it only has 2 routes for the 2 apps I want to query data for but it seems this is an error with the subprocess

Executing the exact same image locally works like a charm

Very annoying all of this works perfectly on my machine xD kind of defeats the purpose of Docker :(

time is not on my side atm :)

No worries take your time thanks for all the help I appreciate it!

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Alavi1412 commented 2 years ago

I'm having the same issue. Here is my Dockerfile:


ROM python:3.9.13-alpine
LABEL maintainer="alavi_hassan@yahoo.com"

# set work directory
WORKDIR /usr/src/app

# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# install dependencies
COPY ./requirements.txt /requirements.txt
RUN apk add --update --no-cache postgresql-client
RUN apk add --update --no-cache --virtual .tmp-build-deps \
      gcc libc-dev linux-headers postgresql-dev

RUN apk add libffi-dev 
RUN pip install --upgrade pip

COPY ./requirements.txt .
RUN pip install -r requirements.txt

COPY ./app .

CMD [ "gunicorn", "backend.wsgi:application", "--bind", "0.0.0.0:8000" ]

Also, my gunicorn version is 20.1.0.

The error is :


[2022-06-08 10:29:57] Traceback (most recent call last):
[2022-06-08 10:29:57]   File "/usr/local/lib/python3.9/site-packages/gunicorn/arbiter.py", line 589, in spawn_worker
[2022-06-08 10:29:57]     worker.init_process()
[2022-06-08 10:29:57]   File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/base.py", line 142, in init_process
[2022-06-08 10:29:57]     self.run()
[2022-06-08 10:29:57]   File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/sync.py", line 125, in run
[2022-06-08 10:29:57]     self.run_for_one(timeout)
[2022-06-08 10:29:57]   File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/sync.py", line 62, in run_for_one
[2022-06-08 10:29:57]     self.notify()
[2022-06-08 10:29:57]   File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/base.py", line 75, in notify
[2022-06-08 10:29:57]     self.tmp.notify()
[2022-06-08 10:29:57]   File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/workertmp.py", line 46, in notify
[2022-06-08 10:29:57]     os.fchmod(self._tmp.fileno(), self.spinner)
[2022-06-08 10:29:57] PermissionError: [Errno 1] Operation not permitted

The image works perfectly fine on my local.

jonakoudijs commented 2 years ago

After the last update I did not research further. Recently the API has been migrated from Heroku to Azure App Services which also worked without needing to change the image. Why Digital Ocean Apps does not work still baffles me. I wanted to quickly test it out just now but when I try to deploy I get an empty error response:

deployment-error

So that does not help me at all. If you find a possible solution please let us know via this issue (or preferably a new one) and we can incorporate a fix into the image as well (depending on the fix). Seeing the API image works on various other platforms without change I will not further investigate the issues on deploying to Digital Ocean Apps (seeing my time is limited.

Hopefully you will find the solution for your problem :) perhaps users on the Digital Ocean forums can offer a solution?