.cpanel.yml and Staging/Production environments

jjstruck

Member
Oct 17, 2019
5
0
1
USA
cPanel Access Level
Root Administrator
I'm at wits end with this. I have 2 cPanel domains (environments). One for staging and one for production. I have a cPanel remote repo that I can push to based off my local repo's staging branch and I have another cPanel remote repo for production which would push based off my master branch.

The problem here is, because the .cpanel.yml file needs to be CHECKED OUT in the repo, I can't just push to the remote repo and be done with it. I have to keep updating the deploy path each time I want to push to either staging or master in order for it to copy to the correct document root. This is not ideal and creates a high risk.

Does anyone out there have a good way of doing this? Because the file needs to be checked out in the repo, it can't just live at the folder's root on the server and uncommitted elsewhere. This would solve the problem as I could have separate .cpanel.yml files on my staging server and production server and not have to commit the file. I've done tons of reading and there seem to be no good solutions for handling cPanel staging and production environments from a single, local repo using branches as deploy points.

Has anybody successfully done this in a way that makes sense? Perhaps there are some env variables that can discern what the .config.yml should do based off the branch? Is there a way to make the .cpanel.yml function without it being checked out? I'm sick of dealing with this.
 
Last edited:

cPanelLauren

Product Owner
Staff member
Nov 14, 2017
13,293
1,279
313
Houston

jjstruck

Member
Oct 17, 2019
5
0
1
USA
cPanel Access Level
Root Administrator
I'm familiar with git and git checkout. And yes, I've read the documentation. The problem is that the .cpanel.yml HAS to be checked in. Simply being at the root of the directory isn't enough. Because of this, I can't have 2 separate .cpanel.yml's. One for my staging environment which I like to push from my local staging branch to the remote cPanel repo, and one for my production environment which I push from my local master branch to another remote cPanel repo.
 

jjstruck

Member
Oct 17, 2019
5
0
1
USA
cPanel Access Level
Root Administrator
I'm also confused on what githooks would do. The .cpanel.yml file needs to be checked into the repo. Can you explain more how I'd use githooks to help out here?
 

jjstruck

Member
Oct 17, 2019
5
0
1
USA
cPanel Access Level
Root Administrator
So I finally figured this out. I'm writing this out here for anyone who might be having the same issue. The secret to this is... you don't need the .cpanel.yml.

1. Create an empty repo in your cPanel portal.
2. Add that repo as a remote from your local/product repo (git add remote production/staging {repo clone url}).
3. Might need a force to push your local to the remote repo as there could be some errors thrown for different git histories.

Once they're in sync, what you want to do is to look at the .git folder on your cPanel's repo folder. Inside you'll find a hooks folder. (.git/hooks). From here what you'll want to do is to create or edit a post-receive file. Inside you'll want to add this:

Code:
#!/bin/bash

while read oldrev newrev ref
do
  branch=`echo $ref | cut -d/ -f3`

  if [ "master" == "$branch" ]; then
    git --work-tree=PATH_FROM_REPO_LOCATION_TO_PRODUCTION_FOLDER checkout -f $branch
  fi

  if [ "staging" == "$branch" ]; then
    git --work-tree=PATH_FROM_REPO_LOCATION_TO_STAGING_FOLDER checkout -f $branch
  fi
done
You'll probably need to tweak it/play with it to get it working for your side of things. Once you push to remote either yourself or using a build server, it should copy the files to the destination directory for your staging/production sites.

I wish this was better documented rather than just pasting links and having people just figure things out. I hope this helps anyone else out there. I got so hung up on trying to find a workaround for the .cpanel.yml file. Hopefully this saves people time. I wish I had this when I started.
 

cPanelLauren

Product Owner
Staff member
Nov 14, 2017
13,293
1,279
313
Houston
This is what I was actually leaning towards but I was waiting on one of our product owners who is currently traveling more familiar with this feature to provide more information.

I did have a conversation with him briefly about this and he noted there was a specific security concern for why they were forcing you to checkin the .cpanel.yml file. I'd hoped the githooks documentation/information might provide a reliable path for you but I do also want to point out that this is a customization and we don't typically provide much documentation on customizations outside of the way the product is intended for use. I will also say that pending the method you're using doesn't have a security concern, I think we could use some resources/kb articles on the subject which I will look into further.

Thanks!
 

jjstruck

Member
Oct 17, 2019
5
0
1
USA
cPanel Access Level
Root Administrator
If I could suggest that the .cpanel.yml need not be checked into the repo. That way people could just place the .cpanel.yml at the root of each remote repo directory and it would build against that rather than it needing to be checked in. Having it checked in works great if you don't use multiple environments, but as soon as you need to do that, the .cpanel.yml becomes just a hinderance.
 

cPanelAdamF

cPanel Product Owner
Staff member
Mar 21, 2013
287
125
168
Houston TX
cPanel Access Level
DataCenter Provider
Twitter
Originally the .cpanel.yml file mechanism was intended to be a very simple way of exposing a git-hook without needing to write a bash shell script or understand how git's hooking mechanism works.

An option you could consider...if you'd rather not get into the .git/hooks dir to do it the more canonical way...would be to simply use the .cpanel.yml file as a dispatcher to a custom deploy script where your environment awareness lies.

Something like...
YAML:
# pseudo-code ahead
---
deployment:
 tasks:
 - source ./deployment/environment.rc # created by hand during initial deployment environment setup, fills $PROJECT_ENV
 - ./deployment/deploy.sh $PROJECT_ENV
...where environment.rc is NOT checked in. deploy.sh could be written in your preferred programming language (rather than bash) as well.