{"id":188,"date":"2025-11-09T03:44:06","date_gmt":"2025-11-09T08:44:06","guid":{"rendered":"https:\/\/4starhost.com\/blog\/?p=188"},"modified":"2025-11-09T03:49:07","modified_gmt":"2025-11-09T08:49:07","slug":"advanced-git-cpanel-detailed-walkthrough","status":"publish","type":"post","link":"https:\/\/4starhost.com\/blog\/advanced-git-cpanel-detailed-walkthrough\/","title":{"rendered":"Advanced Git + cPanel: Detailed Walkthrough"},"content":{"rendered":"<h2>1. Repository Setup in cPanel<\/h2>\n<ul>\n<li>Go to <strong>Files \u2192 Git Version Control<\/strong> in cPanel.<\/li>\n<li>Choose <strong>Clone Repository<\/strong> and paste your GitHub\/GitLab URL:\n<div>\n<div>\n<div>Code<button title=\"Collapse code snippet\" type=\"button\" aria-expanded=\"true\"><\/button><\/div>\n<div><\/div>\n<\/div>\n<div class=\"rounded-b-xl bg-background-static-850 px-4 pb-1.5 dark:bg-background-static-900\">\n<div>\n<pre><code>https:\/\/github.com\/yourusername\/yourproject.git\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/li>\n<li>Select the target directory (e.g., <code>\/home\/username\/repos\/project<\/code>).<\/li>\n<\/ul>\n<p>\ud83d\udc49 <strong>Pro Tip:<\/strong> Keep repositories outside <code>public_html<\/code> to avoid exposing <code>.git<\/code> directories publicly. Deploy into <code>public_html<\/code> via scripts instead.<\/p>\n<div><\/div>\n<h2>2. Deployment with <code>.cpanel.yml<\/code><\/h2>\n<p>cPanel looks for a <code>.cpanel.yml<\/code> file in the repo root. This file defines <strong>deployment tasks<\/strong> that run after each push.<\/p>\n<p>Example for a PHP\/Laravel app:<\/p>\n<div>\n<div>\n<div>yaml<button title=\"Collapse code snippet\" type=\"button\" aria-expanded=\"true\"><\/button><\/div>\n<div><\/div>\n<\/div>\n<div class=\"rounded-b-xl bg-background-static-850 px-4 pb-1.5 dark:bg-background-static-900\">\n<div>\n<pre><code>deployment:\r\n  tasks:\r\n    - export DEPLOYPATH=\/home\/username\/public_html\/\r\n    - \/bin\/rsync -av --exclude='.git' --exclude='storage\/' .\/ $DEPLOYPATH\r\n    - \/usr\/local\/bin\/composer install --no-dev --optimize-autoloader -d $DEPLOYPATH\r\n    - \/usr\/local\/bin\/php $DEPLOYPATH\/artisan migrate --force\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<h3>What\u2019s happening here:<\/h3>\n<ul>\n<li><strong>rsync<\/strong> copies files into <code>public_html<\/code> while excluding sensitive directories.<\/li>\n<li><strong>composer install<\/strong> ensures dependencies are installed on the server.<\/li>\n<li><strong>artisan migrate<\/strong> runs database migrations automatically after deployment.<\/li>\n<\/ul>\n<div><\/div>\n<h2>3. Branch-Specific Deployments<\/h2>\n<p>You can configure deployments to trigger only on certain branches. For example, staging vs production:<\/p>\n<div>\n<div>\n<div>yaml<button title=\"Collapse code snippet\" type=\"button\" aria-expanded=\"true\"><\/button><\/div>\n<div><\/div>\n<\/div>\n<div class=\"rounded-b-xl bg-background-static-850 px-4 pb-1.5 dark:bg-background-static-900\">\n<div>\n<pre><code>deployment:\r\n  tasks:\r\n    - if [ \"$CPANEL_BRANCH\" == \"staging\" ]; then\r\n        export DEPLOYPATH=\/home\/username\/staging\/;\r\n        \/bin\/rsync -av .\/ $DEPLOYPATH;\r\n      fi\r\n    - if [ \"$CPANEL_BRANCH\" == \"main\" ]; then\r\n        export DEPLOYPATH=\/home\/username\/public_html\/;\r\n        \/bin\/rsync -av .\/ $DEPLOYPATH;\r\n      fi\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<p>\ud83d\udc49 This lets you push to <code>staging<\/code> for testing, and <code>main<\/code> for production.<\/p>\n<div><\/div>\n<h2>4. Custom Git Hooks<\/h2>\n<p>Beyond <code>.cpanel.yml<\/code>, you can edit hooks directly in:<\/p>\n<div>\n<div>\n<div>Code<button title=\"Collapse code snippet\" type=\"button\" aria-expanded=\"true\"><\/button><\/div>\n<div><\/div>\n<\/div>\n<div class=\"rounded-b-xl bg-background-static-850 px-4 pb-1.5 dark:bg-background-static-900\">\n<div>\n<pre><code>\/home\/username\/repos\/project\/.git\/hooks\/\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<p>Examples:<\/p>\n<ul>\n<li><strong>pre-receive<\/strong>: Run tests before accepting commits.<\/li>\n<li><strong>post-receive<\/strong>: Trigger notifications (e.g., Slack webhook).<\/li>\n<\/ul>\n<p>Sample <code>post-receive<\/code> hook:<\/p>\n<div>\n<div>\n<div>bash<button title=\"Collapse code snippet\" type=\"button\" aria-expanded=\"true\"><\/button><\/div>\n<div><\/div>\n<\/div>\n<div class=\"rounded-b-xl bg-background-static-850 px-4 pb-1.5 dark:bg-background-static-900\">\n<div>\n<pre><code>#!\/bin\/bash\r\nDEPLOYPATH=\/home\/username\/public_html\/\r\ngit --work-tree=$DEPLOYPATH --git-dir=\/home\/username\/repos\/project checkout -f main\r\ncurl -X POST -H 'Content-type: application\/json' \\\r\n     --data '{\"text\":\"Deployment completed on production!\"}' \\\r\n     https:\/\/hooks.slack.com\/services\/XXXX\/YYYY\/ZZZZ\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<div><\/div>\n<h2>5. CI\/CD Integration<\/h2>\n<p>For advanced automation, connect GitHub Actions or GitLab CI to cPanel:<\/p>\n<p><strong>GitHub Actions workflow (<\/strong><code>.github\/workflows\/deploy.yml<\/code><strong>):<\/strong><\/p>\n<div>\n<div>\n<div>yaml<button title=\"Collapse code snippet\" type=\"button\" aria-expanded=\"true\"><\/button><\/div>\n<div><\/div>\n<\/div>\n<div class=\"rounded-b-xl bg-background-static-850 px-4 pb-1.5 dark:bg-background-static-900\">\n<div>\n<pre><code>name: Deploy to cPanel\r\non:\r\n  push:\r\n    branches: [ \"main\" ]\r\n\r\njobs:\r\n  deploy:\r\n    runs-on: ubuntu-latest\r\n    steps:\r\n      - name: Checkout code\r\n        uses: actions\/checkout@v3\r\n\r\n      - name: Deploy via SSH\r\n        uses: appleboy\/ssh-action@v0.1.7\r\n        with:\r\n          host: ${{ secrets.CPANEL_HOST }}\r\n          username: ${{ secrets.CPANEL_USER }}\r\n          key: ${{ secrets.CPANEL_SSH_KEY }}\r\n          script: |\r\n            cd repos\/project\r\n            git pull origin main\r\n            \/bin\/rsync -av .\/ \/home\/username\/public_html\/\r\n<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<p>\ud83d\udc49 This ensures every push to <code>main<\/code> automatically updates your live site.<\/p>\n<div><\/div>\n<h2>6. Best Practices<\/h2>\n<ul>\n<li><strong>SSH Keys<\/strong>: Add your public key in cPanel \u2192 SSH Access for secure Git pulls.<\/li>\n<li><strong>Environment Variables<\/strong>: Use <code>.env<\/code> files for secrets, never commit them.<\/li>\n<li><strong>Rollback Strategy<\/strong>: Keep tagged releases (<code>git tag v1.0<\/code>) so you can quickly revert.<\/li>\n<li><strong>Monitoring<\/strong>: Check deployment logs in cPanel under <strong>Git Version Control \u2192 Manage<\/strong>.<\/li>\n<\/ul>\n<div><\/div>\n<h2>\ud83d\udd11 Key Takeaway<\/h2>\n<p>For advanced users, cPanel\u2019s Git integration isn\u2019t just about version control \u2014 it\u2019s a <strong>deployment automation platform<\/strong>. By combining <code>.cpanel.yml<\/code>, hooks, and external CI\/CD pipelines, you can achieve <strong>professional-grade workflows<\/strong> even on shared hosting.<\/p>\n<p>\u00a0<\/p>\n<p>If you\u2019re looking for more beginner level git help go here <a href=\"https:\/\/4starhost.com\/blog\/mastering-git-version-control-in-cpanel-a-step-by-step-guide-for-beginners\/\">Git with cpanel for beginners<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1. Repository Setup in cPanel Go to Files \u2192 Git Version Control in cPanel. Choose Clone Repository and paste your GitHub\/GitLab URL: Code https:\/\/github.com\/yourusername\/yourproject.git Select the target directory (e.g., \/home\/username\/repos\/project). \ud83d\udc49 Pro Tip: Keep repositories outside public_html to avoid exposing .git directories publicly. Deploy into public_html via scripts instead. 2. Deployment with .cpanel.yml cPanel looks [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":190,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,100],"tags":[],"class_list":["post-188","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cpanel-hosting","category-git"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/posts\/188","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/comments?post=188"}],"version-history":[{"count":3,"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/posts\/188\/revisions"}],"predecessor-version":[{"id":192,"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/posts\/188\/revisions\/192"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/media\/190"}],"wp:attachment":[{"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/media?parent=188"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/categories?post=188"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/4starhost.com\/blog\/wp-json\/wp\/v2\/tags?post=188"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}