Continuous deployment with Kirby (shared folders like accounts, content and media)

Hi there

I have just setup a continuous deployment with deployhq.
Everything looks nice but I need some kirby specific advice.

  1. First I upload the files
  2. Then I run composer install
  3. and now comes the funny part.

I want to have the content stay the same over all my releases of course.
So I thought I just create symlinks from the release pointing to a shared folder.

I would do that for


Now if I do that and visit the panel of the page, first I got an error that I had some problems with the rights of my media folder:

To me it seems to be alright
I have the following rights:

drwxr-xr-x shared/media
drwxr-xr-x shared/content
drwxr-xr-x shared/accounts

and my symlinks look like this:
lrwxrwxrwx content -> shared/content
lrwxrwxrwx media -> shared/media
lrwxrwxrwx site/accounts -> shared/accounts

I then deleted the media folder (just to test). That error went away because kirby jsut recreates it.

But now I get the error The accounts directory could not be created
But it should already be there… right?

I would be super glad if somebody has some experience with this.

Thank you in advance.

consider using a “public” folder setup and move all shared folders to one and only one symlinked “storage” (“shared”) folder. like accounts, cache, media, content, sessions.
personally i create all these folders manually so i am not sure if kirby can create those beyond a symlink but it should.

another thing to consider is that copying symlinks or moving the folder will not work since the paths stored are absolute. you can push a symlink into a repo but it will not work on deployed server.
i ended up creating the symlinks with php to avoid that.

the example above only symlinks the media folder since in my deploy chain i setup the symlink to storage using the envoyer web interface. but you can definitively do that in index.php as well.

deployhq also supports creating a .deployignore file with same structure as a gitignore file. you could simply add the folders mentioned above to that file and skip the symlinking step.

Hm Yeah that could work! I did not know that you can just set the locations of the directories as you want…
I will just try to set it up like that. Thank you.
I will also want to setup the symlinks with deployhq.
Just to be sure:
Now I just have to symlink the whole storage folder from within my release to the shared/storage folder right?

The symlink for media is a bit special then, because it contains public images? Or what’s the deal there?

What you mean by the deployignore, I don’t really get.
I already excluded all those folders (accounts, content, media etc.) from even being pushed to github, so I guess I don’t need that right?

But even if you meant that I don’t know why I would skip the symlinking step.

On my remote I want to share the storage folder across all my releases, so I still would need to symlink the release storage folder to the shared storage folder, right?

Thanks for a bit of clarification. And thanks for the hint into a new direction. I think this could be a good one.

yes. just the storage folder.

files/folders defined in the .deployignore file will not be copied from repo NOR removed. this can be used to keep files/folder continuously without the need to put them into a different dir. (just with deplohq obviously)

yes. you still need that symlink.

about the custom folder setup see this link to the docs.

yes. the media folder is special since i wanted it to be in storage/media but it needs to be public. thus the symlink.

Do you know what that could be?
It tells me that there is no media folder right?

But when I connect via ssh:

-rw-r--r--  1 some-sy psacln  2231 Apr  9 23:02
lrwxrwxrwx  1 some-sy psacln    21 Apr  9 23:02 accounts -> ../../shared/accounts
-rw-r--r--  1 some-sy psacln   222 Apr  8 14:38 composer.json
-rw-r--r--  1 some-sy psacln 48992 Apr  8 14:38 composer.lock
drwxr-xr-x  4 some-sy psacln  4096 Apr  9 23:02 content
drwxr-xr-x  8 some-sy psacln  4096 Apr  8 14:38 kirby
drwxr-xr-x  3 some-sy psacln  4096 Apr  8 15:59 media
drwxr-xr-x  3 some-sy psacln  4096 Apr  9 23:02 public
drwxr-xr-x 10 some-sy psacln  4096 Apr  9 23:02 site
lrwxrwxrwx  1 some-sy psacln    29 Apr  9 23:02 storage ->
drwxr-xr-x 18 some-sy psacln  4096 Apr  9 23:02 vendor

(Forget about the accounts symlink, I just forgot about that)…

But you can see that I linked the storage folder (which is the correct location), and my storage folder does contain these three folders… accounts content media.

So is this maybe a problem with the symlinking of the media, or does the whole storage-folder approach not work?

Thank you in advance.

my setup assumed storage/media. please fix the paths in index.php

I tried to fix things, and I first checked the symlinks and that seems to be ok.

I have:
(this is where my host is pointing at)

(this is where I have the kirby roots being setup.

This is the symlink that Kirby should make if it does not exist yet.
This is also the point where it fails, because during the creation of that symlink it says that the directory $kirby->roots()->media() does not exist.

But I also have this

So the folder media exists.

I also have this shell command run after the deploy:
ln -fs %shared_path%/storage %release_path%/storage
In my case this resolves to:

releases/123456789/storage -> shared/storage

Also within the Kirby setup I have this line (just as you do):
'storage' => $storage = $base . '/storage',
So this should determine the symlink storage within my release as the $storage.

When doing:
'media' => $storage . '/media',
this later on, this should to my understanding kind of chain two symlinks.
And I think this is where the problem occurs?!

The $storage itself is a symlink and we are defining the media root as a child of that storage folder.

And then later we try to make the symlink with kirby and it tells me that this directory does not exist…

Or am I missing something?

Just for the sake of completeness:

Content of the shared folder:

$ cd /
$ ls -l
lrwxrwxrwx 1 systemuser psacln   25 Apr 10 10:35 current -> ./releases/20200410103538
drwxr-xr-x 4 systemuser psacln 4096 Apr 10 10:35 releases
drwxr-xr-x 3 systemuser psacln 4096 Apr 10 10:28 shared

Content of the shared folder:

$ cd /
$ ls -l
total 20
drwxr-xr-x 5 systemuser psacln 4096 Apr 10 09:58 accounts
drwxr-xr-x 2 systemuser psacln 4096 Apr 10 09:54 cache
drwxr-xr-x 4 systemuser psacln 4096 Apr  9 23:06 content
drwxr-xr-x 4 systemuser psacln 4096 Apr 10 09:56 media
drwxr-xr-x 2 systemuser psacln 4096 Apr 10 10:05 sessions

Content of the release

$ cd /
$ ls -l
total 68
-rw-r--r--  1 systemuser psacln   222 Apr 10 10:32 composer.json
-rw-r--r--  1 systemuser psacln 48992 Apr 10 10:32 composer.lock
drwxr-xr-x  8 systemuser psacln  4096 Apr 10 10:32 kirby
drwxr-xr-x  3 systemuser psacln  4096 Apr 10 10:32 public
drwxr-xr-x  8 systemuser psacln  4096 Apr 10 10:32 site
lrwxrwxrwx  1 systemuser psacln    30 Apr 10 10:57 storage -> /

(Where I also tried to make a relative symlink: lrwxrwxrwx 1 systemuser psacln 20 Apr 10 10:59 storage -> ../../shared/storage. Both solutions don’t work…

Thanks for any hints to solve this…

------ Edit:
Oh I think I have found something:
Kirby does set symlinks a bit differently, I guess:

$ cd /
$ ls -l
-rw-r--r-- 1 systemuser psacln 1799 Apr 10 10:32 index.php
lrwxrwxrwx 1 systemuser psacln   91 Apr 10 10:32 media -> /home/httpd/vhosts/XXX/
drwxr-xr-x 2 systemuser psacln 4096 Apr 10 10:32 proxy

You see that it messing up that symlink of media…
Do you know how I could fix this?
(Manually rewriting the symlink made by kirby to lrwxrwxrwx 1 systemuser psacln 16 Apr 10 11:05 media -> ../storage/media works…, but I don’t want any manual work of course)

I think I could solve it by just letting deployhq add relative symlinks.
Also I let deployhq create the symlink that kirby is trying to define. So I already have a working symlink and kirby can’t mess up things on my remote.

Anyway, if you have some background information, I’d be happy if you shared that.
I also see that there is quite a bit of reading to do for you, so I am not mad if you don’t.
I believe it works now.

Anyway thanks for leading me to the right path :).


1 Like