<p>Symlinks won't transfer over FTP and I'm like 98% sure there isn't a way to get Craft to re-create those symlinks natively.</p>

<p>So you'd need SSH access to the box with Composer installed in the terminal.  Then you could upload your custom plugins, <code>composer.json</code> and run <code>composer update</code> or upload <code>composer.json</code> and <code>composer.lock</code> and run <code>composer install</code> to have the dependencies pulled down and the symlinks re-created.</p>

<p>Alternatively, and this is probably cleaner, you can setup a <code>vcs</code> type of repository in your <code>composer.json</code> file, along side your <code>path</code> repository.  <a href="https://getcomposer.org/doc/05-repositories.md#loading-a-package-from-a-vcs-repository" rel="nofollow noreferrer">https://getcomposer.org/doc/05-repositories.md#loading-a-package-from-a-vcs-repository</a></p>

<p>They'd both point to the same plugin.  When you deploy to production, Composer should see that the <code>path</code> repo doesn't resolve to a valid path on the production file system and move onto the <code>vcs</code> repo for the same plugin and pull the files down that way.</p>

<p>It's compatible with private repositories, too: <a href="https://getcomposer.org/doc/05-repositories.md#using-private-repositories" rel="nofollow noreferrer">https://getcomposer.org/doc/05-repositories.md#using-private-repositories</a> and you can setup Github access tokens if you'd rather go that way: <a href="https://www.previousnext.com.au/blog/managing-composer-github-access-personal-access-tokens" rel="nofollow noreferrer">https://www.previousnext.com.au/blog/managing-composer-github-access-personal-access-tokens</a></p>

CC BY-SA 4.0
2018-09-08T10:45:53.827Z
It's possible to [create symlinks using PHP](http://www.php.net/manual/en/function.symlink.php), but of course that would be a terrible approach.
Mats Mikkel Rummelhoff
CC BY-SA 4.0
2018-09-10T14:12:38.957Z
Thanks Brad. I wonder if you can add to your answer an explanation of the preferred approach, since clearly this it not the way you expect people to be doing things? What is the _de rigueur_ way to maintain a private plugin and publish ongoing changes to staging/production servers?
Derek Hogue
CC BY-SA 4.0
2018-09-11T23:20:32.473Z
@DerekHogue updated answer
Brad Bell
CC BY-SA 4.0
2018-09-07T21:14:53.607Z
2018-09-11T23:20:17.290Z
2018-09-11T23:20:17.290Z
Brad Bell
<p>I have a couple of custom plugins for a site, which I successfully added by using <code>path</code> repositories in my <code>composer.json</code> file. However, when I upload the site to my staging server (via FTP - no SSH access or Git on this server), the symlinks in <code>craft/vendor/myvendorname</code> (which are automatically created during any <code>composer update</code>) won't upload. Thus, my site breaks, trying to load plugins which it cannot find.</p>

<p>I can manually upload the actual folders to that location (which is my fix for now), but that's not sustainable on an ongoing basis really.</p>

<p>Is there some way I can force Craft (or really Composer I suppose) to recreate those symlinks on the remote server? Or is this a case where I simply need SSH access so I can do it manually?</p>

CC BY-SA 4.0
2018-09-06T23:17:19.650Z
Just so I'm following, you still want to use `path` repositories on your staging/production servers, too?
Brad Bell
CC BY-SA 4.0
2018-09-07T13:03:55.257Z
I had thought so ... is there a reason to not? I am new to this Composer-managed-code thing.
Derek Hogue
CC BY-SA 4.0
2018-09-07T21:07:18.147Z
You can do it that way, but you'll need SSH access.  Will add an answer.
Brad Bell
<plugin-development><composer>
How to recreate symlinks to path-based plugins after moving to live server?
# How to recreate symlinks to path-based plugins after moving to live server?

(Asked by: username_0 on 2018-09-04)

I have a couple of custom plugins for a site, which I successfully added by using `path` repositories in my `composer.json` file. However, when I upload the site to my staging server (via FTP - no SSH access or Git on this server), the symlinks in `craft/vendor/myvendorname` (which are automatically created during any `composer update`) won't upload. Thus, my site breaks, trying to load plugins which it cannot find.

I can manually upload the actual folders to that location (which is my fix for now), but that's not sustainable on an ongoing basis really.

Is there some way I can force Craft (or really Composer I suppose) to recreate those symlinks on the remote server? Or is this a case where I simply need SSH access so I can do it manually?

**Tags:** plugin-development, composer
> **Comments:**
> **username_1**: Just so I'm following, you still want to use `path` repositories on your staging/production servers, too?  
> **username_0**: I had thought so ... is there a reason to not? I am new to this Composer-managed-code thing.  
> **username_1**: You can do it that way, but you'll need SSH access.  Will add an answer.  

---

## 1 answers

### Answer by username_1 on 2018-09-07. Score: 2 | Accepted answer

Symlinks won't transfer over FTP and I'm like 98% sure there isn't a way to get Craft to re-create those symlinks natively.

So you'd need SSH access to the box with Composer installed in the terminal. Then you could upload your custom plugins, `composer.json` and run `composer update` or upload `composer.json` and `composer.lock` and run `composer install` to have the dependencies pulled down and the symlinks re-created.

Alternatively, and this is probably cleaner, you can setup a `vcs` type of repository in your `composer.json` file, along side your `path` repository. <https://getcomposer.org/doc/05-repositories.md#loading-a-package-from-a-vcs-repository>

They'd both point to the same plugin. When you deploy to production, Composer should see that the `path` repo doesn't resolve to a valid path on the production file system and move onto the `vcs` repo for the same plugin and pull the files down that way.

It's compatible with private repositories, too: <https://getcomposer.org/doc/05-repositories.md#using-private-repositories> and you can setup Github access tokens if you'd rather go that way: <https://www.previousnext.com.au/blog/managing-composer-github-access-personal-access-tokens>

> **Comments:**
> **username_2**: It's possible to [create symlinks using PHP](http://www.php.net/manual/en/function.symlink.php), but of course that would be a terrible approach.  
> **username_0**: Thanks Brad. I wonder if you can add to your answer an explanation of the preferred approach, since clearly this it not the way you expect people to be doing things? What is the _de rigueur_ way to maintain a private plugin and publish ongoing changes to staging/production servers?  
> **username_1**: @DerekHogue updated answer  

---

