Capistrano symlinks and MediaTemple's GridServer

So I’ve spent two days jerking my MediaTemple (gs) account around so that I can deploy with Capistrano, and I’ve hit a bit of a wall.

Capistrano writes to my server perfectly. It also creates symlinks. However, the symlinks remain inaccessible to the outside world (403 and 500 errors when attempting to access the site or any linked content).

The problem is this: as a (weird, random, undocumented) limitation to using their GridServer shared hosting service, symlinks must point to relative paths, but Capistrano creates symlinks with absolute paths.

As an experiment, after a deploy, I SSHed into the server, did a rm current, and manually did ln -s current releases/$releasenumber$. Suddenly, my site was accessible.

So, my question is this: can I force Capistrano to use relative paths in symlinks? I’ve found a couple of recipes that do just that, but they appear to be built on previous versions of Capistrano, and I get errors every time I use their methods. (They also don’t account for the shared assets/environment-specific links, the symlinks to which are also absolute by default.)

I don’t know Ruby, so any direction at all would be really helpful.

I managed to figure out a solution. It’s feels a little gross, though, so let me know if there’s a better/more elegant way.

The above solutions that used Capistrano 2 just changed the Rake task that created symlinks, so that’s what I did.

I struggled with it for awhile, though, because Cap would run the default symlink tasks and then run my modified tasks, which meant the symlinked directories just used the original (absolute) paths. So I had to do a Rake::Task["deploy:symlink:linked_dirs"].clear to clear the task out in my Capfile, and then I rewrote it to include the relative paths.

I put the whole Capfile in a gist, in case anybody else runs into the same problem.

(Also, I discovered that the MediaTemple limitation seems only to apply to directories. The absolute path to the .env works just fine.)

This solution seems a little messy to me, so if anybody has other ideas…

What path were you deploying to and did you try different paths before the workaround?

I was deploying to the root of the domain–so the path looked like /home/ACCOUNTNUM/users/.home/domains/myurl.com. MT uses an /html like other hosts use /htdocs, so I also tried deploying to that directory.

The really odd thing is that Capistrano was creating and verifying links just fine. Doing a readlink on /current (and /current/app/.env, and /current/app/uploads) showed the paths were all correct. In SSH, I could even cd into the symlinks. But when trying to access symlinked files via HTTP, the browser would return a 403 or a 500. (FWIW, I also had issues navigating through to the symlinked directories in my FTP client, but that could just have been an issue with my FileZilla.)

The thing that tipped me off (besides the above linked recipes for Cap 2 that talk about relative symlinks) was that I manually created links via SSH as an experiment: ln -s releases/RELEASENUM current, and I could suddenly access linked directories just fine. The issue doesn’t exist, for some reason, when linking to files (.env).

Seems to me the nicest, most reusable thing to do would be to write a separate task (in lib/tasks) that runs after files are linked, and re-creates them to be relative. But alas, I’m short on time and Ruby knowledge.

It may not help but I’d try the format recommended here before writing a new task.

MediaTemple sure is strange… good debugging though.

Your solution is fine and really not that dirty. In fact there isn’t really another way of doing it without skipping the require 'capistrano/deploy' which would mean redefining ALL the deploy tasks.

Thanks for the link, but still no dice. I even tried using the absolute path (pretty sure /home is itself a symlink, so I found the actual hard file path, something like /n04/h02/mnt/blah), and as before, I could cd through the link, but the browser received a 503 error when trying to connect.

Thanks–that’s what I figured. I’ve been with MT for like seven years now, and it’s honestly rare that I butt up against weird problems like this; in my experience, their shared hosting is much less restrictive than other shared hosts. And their support is usually superb–this has been the only time they’ve let me down, honestly. Ah well.

I’ll look into turning this into a reusable task in lib/tasks, then. Guess it’s a good opportunity to learn a bit more Ruby…hopefully my running around saves another (gs) customer some time.

PS: I’ve used Roots for the last year or so, and it’s made me a better developer. Bedrock is doing even more for me than Roots did in that regard. Awesome work on this stuff. Looking forward to the Vagrant stuff.

Awesome! That’s what we like to hear.

I’ve almost got this issue worked out. I can’t figure out why, but the /media symlink is being put in /app/media, instead of /wp/media (where it resides on my local machine). So when I deploy, all images are broken, until I manually move the symlink to the correct directory. I haven’t modified my Capfile or deploy scripts from what was posted above.

When I change deploy.rb to use #{wp/media} for linked folders, the link target changes to /wp/media–not the link itself.

Is that what’s supposed to happen? Sorry if this is obvious–I just can’t seem to work out where the setting is that determines where Capistrano actually puts the symlink.

Otherwise, it’s working really well for me.

Not that this really solves your problem, but is /wp/ the WordPress core itself (via Composer)?

If so, your uploads/media dir shouldn’t be in there. That folder should remain untouched.

Yes, that’s why I find this confusing: I used composer to set this up initially as per instructions in the repository, and the settings all look right. The only things I changed, IIRC, are the deployment/symlink things above.

The link is going where it’s set up to go: /app/media on the server (which links, appropriately, to /shared/media). However, on my local install, media lives in /wp/media. (This is despite the fact that I didn’t modify the composer setup–/media is the default upload directory, and my environment files point to /app, etc.)

So I guess my question is this: I’m already committed to using /wp/media since this project is live and stuff, so is there a way to change where Capistrano puts the symlink? As in, switch it from release/app/media to release/wp/media?

It’s not a huge deal to drag-and-drop the symlink to the appropriate directory on release, but, y’know. Automation and junk.

(It’s worth mentioning that I’m developing on a Windows machine running Apache, so there may be something off there. Windows has always been finicky for me with Apache stuff.)

Roots’ old default was setting /media which by itself doesn’t work with the Composer setup. As you’ve seen, it puts it inside the wp/ dir. A workaround that we use on the roots.io site is in this Gist: https://gist.github.com/swalkinshaw/6400708

With Bedrock now we just recommend not changing the uploads folder. The default will be app/uploads without any settings. You could change this if you wanted, would just require some DB updates.

But if you don’t want that hassle, I’m not really sure how to fix it. Capistrano should be doing the proper thing. Only things I can think of: either some weird MT issue, or maybe clearing out the old symlinks would fix it? Not sure why that would matter though.

Y’know what?

I pulled roots out of the composer.json and replaced it with the latest stable commit (in master) of roots-sass. Is roots-sass that far out of sync? Because I was following Bedrock instructions, but with the sass version as a dependency instead of default. If that’s what’s causing WP to look in /wp/media, Capistrano is doing exactly what it’s supposed to do, and I’m a dunce.

I came across the gist you used in another thread–thanks for that. I messed with it briefly last night, but couldn’t quite get it working. I may be able to fix it tonight.

roots-sass is updated to 6.5.2 which is the version where we removed media from the activation options. But if you previously had an older version it would have that option to the database.

1 Like

Hm. I referenced a specific commit directly in composer.json (simply referencing master of roots-sass kept pulling regular roots down, which was weird and probably my own fault, so I referenced a specific commit), and it’s definitely 6.5.2.

I may have botched something during setup, though. I’ll try to set up and deploy a couple of dummy sites with my existing composer.json tonight to double check.

Check out https://github.com/morrislaptop/capistrano-gridserver

1 Like

Awesome. Thanks. I’ll check it out ASAP.

I actually just moved to a Mac this week, so we’ll see if Windows had something to do with the issues as well… (Still couldn’t get regular ole Roots to deploy symlinks to the correct directory.)