Skip to main content

Tips & Troubleshooting

Dev server port forwarding

If you run a dev server inside the container (e.g., npm run dev on port 5173), forward it to your local machine:

ssh -L 5173:localhost:5173 -p 3434 abc@<server-ip>

Then open http://localhost:5173 in your browser. Repeat for each port you need. The forwarded port stays alive as long as the SSH session is open.

Keeping Claude Code up to date

Claude Code updates frequently. To update inside the container:

docker exec -it dev-desktop bash
su - abc
source ~/.nvm/nvm.sh
npm update -g @anthropic-ai/claude-code

The update persists in /config/.npm-global, no need to redo it after rebuilds.

Docker-in-Docker permissions

The docker.sock mount gives the container root access to the host's Docker daemon. The abc user inside the container may need to be in the docker group to use it without sudo. If you get permission errors:

docker exec -it dev-desktop bash
sudo usermod -aG docker abc
# Then restart the container

You may also need to match the host's docker GID inside the container.

SSH login issues

Wrong password? Use SUDO_PASSWORD

SSH uses SUDO_PASSWORD, not PASSWORD. The web desktop uses PASSWORD for KasmVNC login. These are two different variables in the compose file.

ssh -p 3434 abc@<server-ip>
# Password: whatever you set as SUDO_PASSWORD

Permission denied even with correct password

First, check the init logs to see if the password was set:

docker logs dev-desktop 2>&1 | grep -i "ssh\|password\|chpasswd"

Look for:

  • SSH password set for abc → password was set, issue is elsewhere
  • WARNING: SUDO_PASSWORD is empty → env var not reaching the container, check compose.yaml
  • WARNING: SUDO_PASSWORD is still the placeholder → you forgot to replace CHANGE_ME_SUDO_PASSWORD
  • ERROR: chpasswd failed → user might not exist yet, check cat /etc/passwd

Also verify SSH is running:

docker exec -it dev-desktop service ssh status

If it's not running, start it:

docker exec -it -u root dev-desktop service ssh start

Multiple projects

The rsync cmd hardcodes the project path. For multiple projects, create separate .code-workspace files, one per project. Each contains its own emeraldwalk.runonsave command with the correct server path.

Known edge cases

rsync timing

If you edit a file and immediately run a command on the server that reads it, the server might still have the old version if you haven't clicked away yet. Click away from the editor first, or save manually (Ctrl+S / Cmd+S) to force an rsync.

rsync needs passwordless SSH

The Run on Save rsync command runs in the background and cannot prompt for a password. You need one of:

  • SSH keys: set up key based authentication so rsync connects without a password
  • SSH multiplexing: if you added the optional ControlMaster config, run ssh -p 3434 abc@<server-ip> once from a terminal to open the shared connection; rsync then rides it without prompting

Setting up your GitHub token

The stack uses GITHUB_TOKEN to authenticate git operations (clone, push, pull) against private repos. It's set in compose.yaml and applied automatically by the init script via git config --global url.insteadOf.

  1. Go to github.com/settings/tokens?type=beta
  2. Click Generate new token
  3. Fill in:
    • Token name: e.g. cloud-dev-stack
    • Resource owner: your user or org
    • Repository access: choose All repositories or pick the specific repos you need
  4. Under PermissionsRepository permissions, set:
    • Contents: Read and write (required for clone, push, pull)
    • Metadata: Read-only (auto selected, required for all tokens)
  5. Click Generate token and copy it

Creating a classic token (alternative)

  1. Go to github.com/settings/tokens
  2. Click Generate new tokenGenerate new token (classic)
  3. Give it a name and check:
    • repo: full control of private repositories (or just public_repo if you only work with public repos)
  4. Click Generate token and copy it

Using the token

Paste the token into your compose file:

# compose.yaml (or compose-casaos.yaml)
environment:
GITHUB_TOKEN: github_pat_xxxxxxxxxxxx # replace CHANGE_ME_GITHUB_TOKEN

Then recreate the container:

docker compose up -d --force-recreate

Verifying it works

SSH into the container and check that git uses the token:

ssh -p 3434 abc@<server-ip>
git config --global url.'https://oauth2:'.insteadOf
# Should print: https://github.com/

Then test with a private repo:

git ls-remote https://github.com/you/private-repo.git
# Should succeed without prompting for a password

Token security

  • The token is stored inside the container's git config: it persists across rebuilds because /config/.gitconfig lives on the shared volume
  • Treat your compose file as a secret: anyone with the token can act as you on GitHub
  • If the token is ever leaked, revoke it immediately at github.com/settings/tokens

See also