Robust Host Ownership Realignment for Containerized Scaffolding #4

Open
inv3ntor01 wants to merge 1 commit from inv3ntor01/permission-fix into main
inv3ntor01 commented 2026-06-04 07:48:08 +00:00 (Migrated from github.com)

During larakube new, scaffolding is handled by a root-run Docker container. Once finished, the CLI attempts to return file ownership to the host user via a chown command. This breaks down in two ways

  1. Hardcoded Fallback: The CLI checks your host ID using posix_getuid(). If that PHP extension is missing, it blindly defaults to UID 1000. If the host user runs on a non-standard ID (like 1001), subsequent file modifications (such as copying .env to .env.production) crash with a Permission Denied fatal error.

  2. Short-Circuit Execution: The cleanup command is chained using && (e.g., laravel new ... && chown ...). If the repository installation fails or times out, the chown is skipped entirely, leaving orphaned, root-owned files in the user's workspace.

The Solution: Dynamic Detection & Guaranteed Cleanup

  • Layered Environment Resolution (app/helpers.php): Replaced the rigid fallback logic with dynamic host_uid() and host_gid() helper functions. They query the system in a resilient cascade:
    POSIX Extension --> Shell Command ('id -u' / 'id -g') --> Strict Default (1000)
    This makes the fix completely universal, resolving accurately for any host user ID (1000, 1001, 2000, etc.) at execution runtime.

  • Guaranteed Ownership Handback (NewCommand.php): Swapped the command chaining operator from short-circuit to sequential (&& -> ;). File ownership is now cleanly returned to the calling host user even if the internal container installation process crashes midway.

  • Consistency & Codebase Cleanup: Integrated these helpers into InteractsWithDocker.php to align all container operations and resolved a missing method regression in ConfigData.php that was triggering cascading scaffolding crashes.

Status: Local environment binary successfully compiled. All automated test suites are passing cleanly.

Example:

  1. Dynamic Detection: The new host_uid() helper function I added doesn't "know" about 1001. Instead, it asks the operating system: "Who is the user running this
    command right now?"
    * If User A (UID 1000) runs it, the function returns 1000.
    * If User B (UID 1001) runs it, the function returns 1001.
    * If User C (UID 2000) runs it, the function returns 2000.
  2. Multiple Detection Layers:
    * It first tries the PHP posix extension (most accurate).
    * If that fails, it runs the system command id -u, which is the standard Linux way to find the current User ID.
    * It only uses 1000 as a "safety net" if both of those fail (which is very unlikely on a standard Linux system).
  3. Correct Ownership: Because the ID is detected at the exact moment you run the command, the Docker container is told to chown (change ownership) to that specific ID. This ensures that the files created inside the container always match the user who started the process, no matter who they are.
permissionIssues permissionFixed
During `larakube new`, scaffolding is handled by a root-run Docker container. Once finished, the CLI attempts to return file ownership to the host user via a chown command. This breaks down in two ways 1. **Hardcoded Fallback**: The CLI checks your host ID using **posix_getuid()**. If that PHP extension is missing, it blindly defaults to UID 1000. If the host user runs on a non-standard ID (like 1001), subsequent file modifications (such as copying .env to .env.production) crash with a Permission Denied fatal error. 1. **Short-Circuit Execution**: The cleanup command is chained using && (e.g., laravel new ... && chown ...). If the repository installation fails or times out, the chown is skipped entirely, leaving orphaned, root-owned files in the user's workspace. ### The Solution: Dynamic Detection & Guaranteed Cleanup - Layered Environment Resolution (app/helpers.php): Replaced the rigid fallback logic with dynamic host_uid() and host_gid() helper functions. They query the system in a resilient cascade: `POSIX Extension --> Shell Command ('id -u' / 'id -g') --> Strict Default (1000)` This makes the fix completely universal, resolving accurately for any host user ID (1000, 1001, 2000, etc.) at execution runtime. - Guaranteed Ownership Handback (NewCommand.php): Swapped the command chaining operator from short-circuit to sequential `(&& -> ;)`. File ownership is now cleanly returned to the calling host user even if the internal container installation process crashes midway. - Consistency & Codebase Cleanup: Integrated these helpers into InteractsWithDocker.php to align all container operations and resolved a missing method regression in ConfigData.php that was triggering cascading scaffolding crashes. Status: Local environment binary successfully compiled. All automated test suites are passing cleanly. Example: 1. Dynamic Detection: The new host_uid() helper function I added doesn't "know" about 1001. Instead, it asks the operating system: "Who is the user running this command right now?" * If User A (UID 1000) runs it, the function returns 1000. * If User B (UID 1001) runs it, the function returns 1001. * If User C (UID 2000) runs it, the function returns 2000. 2. Multiple Detection Layers: * It first tries the PHP posix extension (most accurate). * If that fails, it runs the system command id -u, which is the standard Linux way to find the current User ID. * It only uses 1000 as a "safety net" if both of those fail (which is very unlikely on a standard Linux system). 3. Correct Ownership: Because the ID is detected at the exact moment you run the command, the Docker container is told to chown (change ownership) to that specific ID. This ensures that the files created inside the container always match the user who started the process, no matter who they are. <img width="797" height="668" alt="permissionIssues" src="https://github.com/user-attachments/assets/82302fe4-2a90-4f64-bf01-caadebda085e" /> <img width="914" height="388" alt="permissionFixed" src="https://github.com/user-attachments/assets/29a15577-aefd-4c5a-9f89-08926382219b" />
luchtech commented 2026-06-22 15:09:24 +00:00 (Migrated from github.com)

Yeah, will check on this later once I deployed the ongoing features. This might have been fixed already.

Yeah, will check on this later once I deployed the ongoing features. This might have been fixed already.
This pull request has changes conflicting with the target branch.
  • app/Commands/NewCommand.php
  • app/Traits/InteractsWithDocker.php
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin inv3ntor01/permission-fix:inv3ntor01/permission-fix
git switch inv3ntor01/permission-fix

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff inv3ntor01/permission-fix
git switch inv3ntor01/permission-fix
git rebase main
git switch main
git merge --ff-only inv3ntor01/permission-fix
git switch inv3ntor01/permission-fix
git rebase main
git switch main
git merge --no-ff inv3ntor01/permission-fix
git switch main
git merge --squash inv3ntor01/permission-fix
git switch main
git merge --ff-only inv3ntor01/permission-fix
git switch main
git merge inv3ntor01/permission-fix
git push origin main
Sign in to join this conversation.
No description provided.