Dan's picture

Howdy! Thanks so much for providing this excellent platform, we use TurnkeyLinux boxes in production all day every day.

Cutting to the chase....    I have a LAMP instance hosting an intranet application, not accessible outside our network.

I have a development platform on another LAMP instance and during development I am using a linux application that has permissions set to 755.

When I "deploy" this application the platform I use pushes this application out to the production server and its permissions get set to either 666 if I use a ZIP to send and then manually unzip, or 644 if I let my development platform do its own FTP/SFTP file transfer.

I think this is all related to me using the root user when I run either my deployment or my ZIP transfer that I then use webmin console to unzip.

Anyone point me in the right direction to finding a solution?  I think perhaps umask may have something to do with it, but I dont want ALL files I upload to be 755, just this one... so my only option may be to put this one executable file outside the development servers "deploy" scope so it doesnt overwrite it each time with the wrong permissions.

Thanks for any and all advice.


Jeremy Davis's picture

First up, it's a little unclear on what permissions you want/need for this file? I'm guessing that you want it to remain the same as the dev server, but I'm not 100% sure... I'm also a little unclear on whether you have the option to adjust the commands that your "deployment platform" uses when deploying to the production server. If that's an option, then there are a number of quite interesting and different ways your could do that. I have a few ideas, which I'll get to in bit.

It's perhaps also worth noting, that AFAIK, zip does not preserve file permissions. Tar can. Rsync (over SSH) is another tool which will (or at least can) preserve permissions. SFTP (as well as SCP; a similar but slightly different protocol that also leverages OpenSSH) can also preserve permissions. IIRC all of these use the '-p' switch to preserve permissions.

It's worth noting though that AFAIK, none of these (nor any other tool I'm aware of - at least by default) preserve the user/group name, just the UID/GID (i.e. the user/group id number, not the actual name). So if files are owned on one server by a user called 'myuser', with an ID of 1001 then transferred to another server who has a different user with the same ID (e.g. 'myotheruser' with ID of 1001) then this different user (with same ID) will be the new owner of the transferred files.

Having said all that, I doubt that is your issue as likely the main users at play here would be root (almost always ID 0) and/or www-data (which is a default system user with an ID of 33 by default). Note though that whilst not advisable, the usernames of these (and other default system accounts) can be changed, but unless you've explicitly done that (and why would you?) that wouldn't be an issue for you... Also "normal" Linux users (e.g. desktop users, a new user you might create, etc) always have an ID >=1000 - unless of course you explicitly set a lower user ID; again not recommended as ids

Re umask, that may be a solution, although it's worth noting, that it's already set! And adjusting it can be a security risk. As you note, it will impact all files. Unix ACLs, may be an answer as they are much more fine grained that the usual Unix permissions, however, Idon't know a lot about them, and aren't sure if they would solve your issue.

As I hinted above, there are a myriad of ways that you might work around this issue. What will be the best in your scenario, will depend on whether you need to continue using your current "deployment platform", if you do; what configurations/adjustments you can apply to it and/or which sort of solution would work best in your scenario.

In no particular order:

  • Deployment platform/process:
    • Adjust SFTP to use the '-p' switch.
    • Use an alternate tool (or combination of tools) to deploy, e.g. Rsync, Tar, SCP, etc.
    • Deploy via git. I.e. keep your app in git on both your prod and dev environment and link them via SSH. Use separate branches for production and development. Your deployment platform could then just auto push (or pull) the "production" branch of your code from your dev server. You could even have a git hook to auto push any new commits to the production branch. FWIW git only preserves the numerical permissions, not the owner/group IDs (ownership is inherited from the user who owns the repo; i.e. originally cloned it).
  • Server side:
    • Cron job to adjust permissions - note cron is a poor tool for this job. It's smallest increment is 1 minute intervals.
    • Custom daemon - write your own script to check/fix the permissions of that file, control it via SystemD. Again a blunt tool, but should be pretty easy to script.
    • Incrond job - incrond is like cron, but triggered by filesystem changes rather than time (so possibly an ideal tool for this job if a serverside solution is desirable with no other changes?).
  • More generic options (require tweaks on both production and dev servers):
    • Create a new "deployment" user with access to files on both production and dev servers and use that user to push to production (note additional options as per above may still be required to enforce the desired permissions on the specific files(s)).
  • As per most things on Linux, there are probably plenty other ways to resolve this too. That's just a few ideas off the top of my head. Happy to elaborate on any of them if you are interested.

Add new comment