Every file and folder on Linux has an owner (user) and a group. Only the owner or root can modify a file.

The problem

When a startup script runs as root, any files it creates are owned by root:

root  /opt/zoo_bot/   ← created by root startup script

When you SSH in as ubuntu, you’re a different account. Ubuntu doesn’t own /opt/zoo_bot, so when git tries to write to .git/FETCH_HEAD, Linux blocks it:

error: cannot open .git/FETCH_HEAD: Permission denied

sudo git pull works because you borrowed root’s identity for that one command — not because it’s the right fix.

The proper fix: chown

sudo chown -R ubuntu:ubuntu /opt/zoo_bot
  • chown = change owner
  • -R = recursively (apply to all files inside too)
  • ubuntu:ubuntu = new owner: ubuntu, new group: ubuntu

After this, ubuntu owns everything in /opt/zoo_bot and git pull works without sudo.

Warning

Don’t use sudo as the long-term workaround — it masks the real problem and leaves files owned by root permanently.

Tip

Rule of thumb — avoid running scripts as root when a regular user will need to interact with those files later. In a startup script (e.g. startup.sh.tpl), prefix commands with sudo -u ubuntu so files are created with the right owner from the start.