lloesche / valheim-server-docker

Valheim dedicated gameserver with automatic update, World backup, BepInEx and ValheimPlus mod support
https://hub.docker.com/r/lloesche/valheim-server
Apache License 2.0
1.92k stars 269 forks source link

Restart if idle only restarts when NOT idle #551

Open ajgoda90 opened 1 year ago

ajgoda90 commented 1 year ago

If RESTART_IF_IDLE is set, it checks for idle, but then restarts when there are players. valheim-is-idle returns 0 if idle, but the restart is triggered if it returns 1. I noticed this because I forgot to set a timezone so it was happening at 11PM instead of 5AM while we were playing.

# valheim-is-idle returns 0 if the server is idle or 1 if players are connected https://github.com/lloesche/valheim-server-docker/blob/249cf9572f1c58fb13b87b81806cf760a5dd4094/valheim-is-idle#L2

echo "$RESTART_CRON $cmd_valheim_is_idle && $cmd_supervisorctl restart valheim-server" >> "$crontab" https://github.com/lloesche/valheim-server-docker/blob/d1e7298f8021dec926dc106d8d26adffc3ba6303/valheim-bootstrap#L96

wcdanh2 commented 1 year ago

I'm also having the issue of my servers restarting at midnight EST (5am UTC) but after some testing I'm thinking it may not be the cron job.

To test it I opened a shell in my docker image like so: docker exec -ti valheim-server /bin/bash then in the shell ran the following: /usr/local/bin/valheim-is-idle && echo "restart"

When there is a player on the server the echo "restart" does not get evaluated, when there is no one on the server it prints "restart"

wcdanh2 commented 1 year ago

Narrowing this down a bit, It appears that valheim-status does not execute properly in the cron environment and is getting a timeout error and returning 0. Update: this is only happening on my second server which is not on the default ports. The SERVER_PORT environment variable is not present inside cron so valheim-status gets left trying the default port.

CrypticSafe5 commented 1 year ago

I've been having issues with my server restarting when having RESTART_IF_IDLE=true which should prevent it from restarting if people are connected. Upon running /usr/local/bin/valheim-status, the output is:

{
    "error": "timeout('timed out')",
    "last_status_update": "2023-01-07T17:02:15.282721+00:00"
}

I dove into valheim-status and found that a2s.status() is giving an error. I attempted setting the port manually to 2456 and 2457, neither of which provide a response.

Here's a valheim.env file to reproduce with:

# Server configs
SERVER_NAME=TEST-SERVER-NAME
WORLD_NAME=TEST-WORLD-NAME
SERVER_PASS=test
SERVER_PUBLIC=false

# Restarts/updates
RESTART_CRON=*/5 * * * *
RESTART_IF_IDLE=true
UPDATE_CRON=*/15 * * * *
UPDATE_IF_IDLE=false

# Saves
BACKUPS_MAX_AGE=1
BACKUPS_IF_IDLE=false
BACKUPS_MAX_COUNT=3
wcdanh2 commented 1 year ago
# Server configs
SERVER_NAME=TEST-SERVER-NAME
WORLD_NAME=TEST-WORLD-NAME
SERVER_PASS=test
SERVER_PUBLIC=false

# Restarts/updates
RESTART_CRON=*/5 * * * *
RESTART_IF_IDLE=true
UPDATE_CRON=*/15 * * * *
UPDATE_IF_IDLE=false

# Saves
BACKUPS_MAX_AGE=1
BACKUPS_IF_IDLE=false
BACKUPS_MAX_COUNT=3

When server_public=false valheim does not respond on the query port. In this setup the server_is_idle function should be counting udp packets instead of using valheim-status.

Also you may want to look into setting the TZ and adjusting the restart schedule (I just noticed you have it set to restart every 5 minutes). You really shouldn't need every 5 minutes unless you think it's going to be that hard to find a time when no one is online, though with the server set to private that seems unlikely.

CrypticSafe5 commented 1 year ago

Sorry for the confusion. I was using this config as a test to see if I could get it to NOT restart while I was connected while trying different configurations.

In regards to the public mode, I had switched it to true to but it started crashing repeatedly. To be fair, I didn't spend too much time trying to troubleshoot, as I don't have a desire to have it publicly available.

I forgot about the difference between public and not. I'll look at the UDP datagram tracking stuff in a bit.

wcdanh2 commented 1 year ago

shell into your docker container: docker exec -it {container name} /bin/bash and edit your crontab with crontab -e add SERVER_PUBLIC=false above the other crontab lines.

If that fixes it I have a related pull request I can add this to.

(the cron environment does not get the environment variables that are set under the normal user. The backup and updater script don't run into this problem because they are not launched by cron, they are only signaled to do work by cron.)

CrypticSafe5 commented 1 year ago

That corrected the behavior! The server no longer restarts while someone is connected, and does when nobody is connected. I watched the logs show where the checks were done and they seem appropriate.

lloesche commented 1 year ago

@wcdanh2 I just merged your PR. Can everyone check if that fixes the issue for you?

ajgoda90 commented 1 year ago

I just updated my image, then manually set RESTART_CRON to 9:30PM and it still restarted while I was connected. Non-public server. I'm not experienced with bash, but I believe the issue is that $cmd_valheim_is_idle is returning a 1(true) instead of a 0(false) when players are logged on. That would mean a NOT operator is needed ahead of it, right?

wcdanh2 commented 1 year ago

shell into your docker container: docker exec -it {container name} /bin/bash and edit your crontab with crontab -e add SERVER_PUBLIC=false above the other crontab lines.

If that fixes it I have a related pull request I can add this to.

(the cron environment does not get the environment variables that are set under the normal user. The backup and updater script don't run into this problem because they are not launched by cron, they are only signaled to do work by cron.)

@ajgoda90 try this. This change didn't get merged in yet.

fritzw commented 6 months ago

I just updated my image, then manually set RESTART_CRON to 9:30PM and it still restarted while I was connected. Non-public server. I'm not experienced with bash, but I believe the issue is that $cmd_valheim_is_idle is returning a 1(true) instead of a 0(false) when players are logged on. That would mean a NOT operator is needed ahead of it, right?

In Bash, a result of 0 means "success" or "true", and anythint else is an error. The reason is that this allows commands to return different kinds of errors, depending on what went wrong. So if valheim-is-idle; then do something; fi would execute do something only if valheim-is-idle returns 0.