DJWoodZ / Satisfactory-Discord-Bot

A Discord bot that posts Satisfactory Dedicated Server status information such as online players.
MIT License
17 stars 3 forks source link

EACCESS: permission denied - When using Docker #30

Closed generalrap closed 5 months ago

generalrap commented 6 months ago

I've been troubleshooting for a few hours, and have not been able to figure this problem out.

I'm trying to utilize Docker to run the bot, and keep getting permissions errors. I'm not sure what else to try, and was hoping that someone here might be able to help? If so, I would be hugely grateful.

Here is some context:

My Satisfactory server was installed via the wolveix/satisfactory-server container, and is located at /srv/satisfactory/server_files/config

I have a Discord bot programmed and ready to go; I have not yet gotten to the point where it has had a chance to connect, but I assume it will work once this error is resolved.

Here are my config files, as well as a printout of the error I am receiving when I try to stand up the container:

.env.local

SATISFACTORY_BOT_DB_PATH=./db.json
SATISFACTORY_BOT_DISABLE_UNREACHABLE_FOUND_MESSAGES=false
SATISFACTORY_BOT_DISCORD_CHANNEL_NAME=
SATISFACTORY_BOT_DISCORD_SERVER_NAME=
SATISFACTORY_BOT_DISCORD_TOKEN=--------token_redacted----------
SATISFACTORY_BOT_IGNORE_POLL_STATE_WHEN_MESSAGING=false
SATISFACTORY_BOT_LOG_LOCATION=/srv/satisfactory/server_files/config/gamefiles/FactoryGame/Saved/Logs/FactoryGame.log
SATISFACTORY_BOT_LOG_USE_WATCH_FILE=false
SATISFACTORY_BOT_POLL_INTERVAL_MINUTES=1
SATISFACTORY_BOT_PURGE_DISCORD_CHANNEL_AFTER_DAYS=7
SATISFACTORY_BOT_PURGE_DISCORD_CHANNEL_AFTER_LINES=
SATISFACTORY_BOT_PURGE_DISCORD_CHANNEL_HOUR=2
SATISFACTORY_BOT_PURGE_DISCORD_CHANNEL_NAME=
SATISFACTORY_BOT_PURGE_DISCORD_CHANNEL_ON_STARTUP=false
SATISFACTORY_BOT_PURGE_DISCORD_CHANNEL_SERVER_NAME=
SATISFACTORY_BOT_SERVER_IP=127.0.0.1
SATISFACTORY_BOT_SERVER_MAX_PLAYERS=4
SATISFACTORY_BOT_SERVER_QUERY_PORT=15777
SATISFACTORY_BOT_SERVER_QUERY_TIMEOUT_MS=10000

compose.yaml

services:
  server:
    build:
      context: .
    environment:
      NODE_ENV: production
      SATISFACTORY_BOT_DB_PATH: /usr/src/app/db/db.json
      SATISFACTORY_BOT_LOG_LOCATION: /srv/satisfactory/server_files/config/gamefiles/FactoryGame/Saved/Logs/FactoryGame.log
    env_file:
      - ./.env
      - ./.env.local
    volumes:
       - ./docker-volumes/db/:/usr/src/app/db/
       - /srv/satisfactory/server_files/config/gamefiles/FactoryGame/Saved/Logs/FactoryGame.log:/home/steam/SatisfactoryDedicatedServer/Fac>
    restart: unless-stopped

Result of docker compose up

[+] Running 1/2
 ✔ Network satisfactory-discord-bot_default     Created                                                                                0.1s
 ⠋ Container satisfactory-discord-bot-server-1  Created                                                                                0.1s
Attaching to server-1
server-1  | Poll interval: 60000 milliseconds
server-1  | New DB written: /usr/src/app/db/db.json
server-1  | Logging out
server-1  | node:fs:2342
server-1  |     return binding.writeFileUtf8(
server-1  |                    ^
server-1  |
server-1  | Error: EACCES: permission denied, open '/usr/src/app/db/db.json'
server-1  |     at Object.writeFileSync (node:fs:2342:20)
server-1  |     at initialise (/usr/src/app/bin/server.js:337:8)
server-1  |     at Object.<anonymous> (/usr/src/app/bin/server.js:352:1)
server-1  |     at Module._compile (node:internal/modules/cjs/loader:1369:14)
server-1  |     at Module._extensions..js (node:internal/modules/cjs/loader:1427:10)
server-1  |     at Module.load (node:internal/modules/cjs/loader:1206:32)
server-1  |     at Module._load (node:internal/modules/cjs/loader:1022:12)
server-1  |     at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
server-1  |     at node:internal/main/run_main_module:28:49 {
server-1  |   errno: -13,
server-1  |   code: 'EACCES',
server-1  |   syscall: 'open',
server-1  |   path: '/usr/src/app/db/db.json'
server-1  | }
server-1  |
server-1  | Node.js v20.12.1
server-1 exited with code 0
DJWoodZ commented 6 months ago

Hi @generalrap,

I am sorry you are having trouble with this.

That error suggest that the container cannot write to the location on the host. That Docker Compose configuration will create and use a database JSON file located on the host machine at: .\docker-volumes\db\db.json. Please ensure that the container user has appropriate access to that file.

To find the UID and GID of the container user you can open an interactive shell, for example:

docker exec -it satisfactory-discord-bot-server-1 /bin/sh

To find the UID:

id -u $USER

To find the GID:

id -g $USER

Then simply set the appropriate permissions using chmod, chgrp and/or chown on the host (remember to exit the container's shell first).

generalrap commented 6 months ago

That makes a lot of sense; I was able to get the container to properly start up using that info.

Essentially, I was trying to start the container using a UID/GID of 1003, whereas the container itself was using UID/GID 1000. I couldn't figure out how to set the UID/GID within compose.yaml (it looks like this is a deprecated function?), so I just had to chmod 777 the \db directory db.json resides in.

The container now starts successfully, and the bot connections seem to be working properly, however, the bot is now just reporting "The server is unreachable" within Discord. I'm going to begin troubleshooting, and will report back if I am successful or hit a wall and need some more assistance.

generalrap commented 6 months ago

Unfortunately, I think I've hit a wall.

I'm getting the following when I stand up the bot's container, and the "Updating" section just repeats itself every ~60 seconds or so:

[+] Running 1/0
 ✔ Container satisfactory-discord-bot-server-1  Created                                                                                                                                                        0.0s
Attaching to server-1
server-1  | Poll interval: 60000 milliseconds
server-1  | Found: /usr/src/app/db/db.json
server-1  | Updating...
server-1  | Error: Connection timed out
server-1  |     at Timeout.<anonymous> (/usr/src/app/node_modules/@djwoodz/satisfactory-dedicated-server-query-port-probe/index.js:20:12)
server-1  |     at listOnTimeout (node:internal/timers:573:17)
server-1  |     at process.processTimers (node:internal/timers:514:7)
server-1  | Waiting for log file to exist: /srv/satisfactory/server_files/config/gamefiles/FactoryGame/Saved/Logs/FactoryGame.log
server-1  | Updating...
server-1  | Error: Connection timed out
server-1  |     at Timeout.<anonymous> (/usr/src/app/node_modules/@djwoodz/satisfactory-dedicated-server-query-port-probe/index.js:20:12)
server-1  |     at listOnTimeout (node:internal/timers:573:17)
server-1  |     at process.processTimers (node:internal/timers:514:7)

If I jump into the bot's container using docker exec -it satisfactory-discord-bot-server /bin/sh, and then run tail -f /home/steam/SatisfactoryDedicatedServer/FactoryGame/Saved/Logs/FactoryGame.log, I see the log updating in realtime; it shows the server running, shows users connecting and disconnecting, but the bot doesn't seem to reflect that, and just continues to cycle through Error: Connection timed out messages.

This seems to imply that the bot's container is able to access the game's log, but that there's some small piece somewhere preventing the information from properly flowing?

Any help would be appreciated.

DJWoodZ commented 5 months ago

Hi @generalrap,

There are two parts to the bot. One part reads the dedicated server's log (via the file system) and the other checks the status using the dedicated server's query port (via the network). I suspect you are seeing that error because 127.0.0.1 does not resolve to the host's network. You have a few options, including the following:

By default Docker creates a bridge network. You could configure the containers to communicate over the default or a user-defined bridge network (using the service name for SATISFACTORY_BOT_SERVER_IP):

Alternatively, if the wolveix/satisfactory-server container is running on the same host and you would like to access it via 127.0.0.1, you could use Docker's host network driver. You may find these resources helpful for that:

generalrap commented 5 months ago

Haha, the network; of course. I never trust Docker loopback addresses, and should have suspected that.

I was able to get it to connect rather easily; I just changed SATISFACTORY_BOT_SERVER_IP= to the host machine's own address.

The bot is now connected, and correctly sees whether or not the server is up or down, but does not react to player login/disconnect events. Screenshot 2024-04-09 124942 Screenshot 2024-04-09 125509

What do you think the missing piece might be?

DJWoodZ commented 5 months ago

My apologies for missing that off my previous response.

It appears you changed the SATISFACTORY_BOT_LOG_LOCATION environment variable in the compose.yaml file. I think that is causing your issue.

The SATISFACTORY_BOT_LOG_LOCATION value in the compose.yaml must match the path of the file as it is mapped inside the container (the target path under volumes).

As it only exists inside the container, the target path used can be practically anything, so long as it matches the value in SATISFACTORY_BOT_LOG_LOCATION. So you could try updating the SATISFACTORY_BOT_LOG_LOCATION to match the target, like this:

services:
  server:
    build:
      context: .
    environment:
      NODE_ENV: production
      SATISFACTORY_BOT_DB_PATH: /usr/src/app/db/db.json
      SATISFACTORY_BOT_LOG_LOCATION: /home/steam/SatisfactoryDedicatedServer/FactoryGame/Saved/Logs/FactoryGame.log
    env_file:
      - ./.env
      - ./.env.local
    volumes:
       - ./docker-volumes/db/:/usr/src/app/db/
       - /srv/satisfactory/server_files/config/gamefiles/FactoryGame/Saved/Logs/FactoryGame.log:/home/steam/SatisfactoryDedicatedServer/FactoryGame/Saved/Logs/FactoryGame.log:ro
    restart: unless-stopped

Alternatively, you could try changing the target path (under volumes) to match your SATISFACTORY_BOT_LOG_LOCATION value, if you prefer:

services:
  server:
    build:
      context: .
    environment:
      NODE_ENV: production
      SATISFACTORY_BOT_DB_PATH: /usr/src/app/db/db.json
      SATISFACTORY_BOT_LOG_LOCATION: /srv/satisfactory/server_files/config/gamefiles/FactoryGame/Saved/Logs/FactoryGame.log
    env_file:
      - ./.env
      - ./.env.local
    volumes:
       - ./docker-volumes/db/:/usr/src/app/db/
       - /srv/satisfactory/server_files/config/gamefiles/FactoryGame/Saved/Logs/FactoryGame.log:/srv/satisfactory/server_files/config/gamefiles/FactoryGame/Saved/Logs/FactoryGame.log:ro
    restart: unless-stopped
generalrap commented 5 months ago

That was it!

Everything is fully operational now.

Screenshot 2024-04-10 084545

I can't thank you enough for your help; this bot is awesome, and your assistance in setting it up has been huge.

DJWoodZ commented 5 months ago

Marvellous. You are welcome.