I've set the pipelines with automatic deployment to the server. These pipelines are using server which has custom user for access to the ubuntu server.
Generally the idea is to run the script.
- npm install
- npm run production
- echo "Copying assets to the server"
- rsync -avz --delete public/build/ $SSH_USER@$SSH_SERVER:/var/lib/docker/volumes/my-project_public-files/_data/build/
Below in this post I will explain all issues related to this rsync topic and how to solve all problems.
Generally when we are inside docker folder in out Ubuntu server we have something like that
ls -l
## output
drwx-----x 3 root root 4096 Mar 11 21:47 my-project_public-files
| Symbol | Name | Meaning |
| ------ | ------- | ----------------------------- |
| `r` | read | View the file’s contents |
| `w` | write | Modify the file’s contents |
| `x` | execute | Run it as a program or script |
Let's see what means drwx-----x
If we want to cd into the folder, all the parents need to have "x" execute permissions for your case. That's why folder volumes has "execute" for everyone else, because folder is public
As soon as we see that out folder is
drwx-----x 3 root root 4096 Mar 11 21:47 my-project_public-files
That means that folder has root owner and root group. How we can give the access to our custom user.
Basically we have two variants:
Common default groups:
sudo
→ lets users run commands as root with sudo
.
adm
→ lets users read system logs.
www-data
→ used by web servers.
Lets see the actual list of out groups on Ubuntu server
compgen -g ## list of groups on server
compgen - u ## list of all users
We can see that group root present in our list of groups. Let's see current users of this group
getent group root
## output
root:x:0:
root
→ Group name
x
→ placeholder for the group password field (not actually stored here; it’s in /etc/gshadow
)
0
→ GID (Group ID number). 0
is special — it’s the superuser group.
(empty after last colon) → means no extra users are explicitly listed as members of the root
group (only the root
user belongs by default, because their primary group is root
).
Let's add our custom user to the group
sudo groupadd project_team ## example how to create new group
sudo usermod -aG root my-user ## add my-user to the root group
And now when we type
getent group root
## output
root:x:0:my-user
So let's make add read-write permissions to our css javascript files which need to be replaced on server but keep execute permissions for traverse folder
Before
cd /var/lib/docker/volumes/my-project_public-files/_data
chmod 751 assets ## explaination below
755
?7 → owner: rwx
→ 4+2+1 = 7
5 → group: r-x
→ 4+0+1 = 5
5 → others: r-x
→ 4+0+1 = 5
After
superuser@my-server:/var/lib/docker/volumes/my-project_public-files/_data/build# ls -l
drwxr-xr-x 2 my-user root 12288 Aug 13 08:13 assets
-rw-r--r-- 1 my-user root 41899 Aug 13 08:13 manifest.json
The owner of assets folder will be replaced into my-user after first replacing files.
In Laravel application inside public folder we also have simlink to the storage. It is better to keep it as it is and dont apply recursive change the owner or permissions
ls -l ## inside volumes/my-project_public_files/_data
lrwxrwxrwx 1 root root 35 Dec 19 2023 storage -> /var/www/project/storage/app/public
When we will change the owner of the storage, the user root will not have permissions for read-write logs and application will stop working.