I’m experiencing an unusual issue with my Docker setup. Everything functions correctly on my local machine, but when I execute the same code in my CI pipeline, I encounter permission errors.
The error message I’m receiving is:
Error: EACCES: permission denied, open '/home/node/.n8n/config'
I’ve experimented with various permission setups and ownership configurations, but nothing appears to resolve the issue in the CI environment. Has anyone else faced similar file permission problems between local Docker and CI runners?
Classic Docker volume mount permission issue. Your CI runs with different user permissions than your local setup. Don’t mess with external permissions - create the directories inside the container with proper ownership. Add an init container or modify your compose file to create directories with correct node user ownership before the main service kicks off. You can also use Docker’s --user flag or user: in compose, but make sure the UID matches your CI runner. Different CI platforms use different default users, so check the actual running user ID in your pipeline logs first. Saves tons of debugging headaches.
This happens because CI environments handle filesystem permissions differently than your local Docker setup. Most CI runners use rootless or restricted environments where the container’s user ID doesn’t match the host filesystem permissions. Don’t try fixing permissions externally. Instead, update your compose file with proper user mapping. Run whoami in your pipeline to see what user CI actually uses, then either set the container to run as root temporarily or create volume mount paths with correct ownership in an initContainer step. I’ve had good luck adding user: "0:0" as a temporary fix in CI-only compose files. Not great for production security, but it works. Your local Docker probably runs with more permissive daemon settings than CI does.
Had the same headache with n8n in GitLab CI. It’s probably a user ID mismatch between your local setup and the CI runner. Try adding user: "1000:1000" to your docker-compose service, or run the id command first to see what UID the CI runner’s actually using before you spin up the containers.