Trellis Staging Blues

####Great Roots team + community:

I’ve been kicking the tires on this stack for the last month or so and it’s hugely impressive. Sage has been fantastic to work with and Bedrock is much as it sounds.

Trellis has been more a journey into the darkness for me (thats on me really, as many of the tools are new to me).

Specifically though, I thought I’d see what the community says regarding deployments and setting up that group_vars/staging file. My staging playbook always says it deploys and then I get nothing on my remote box when I SSH in there.

Current group_vars/staging file, anonymized:

mysql_root_password: ...

   - path: "{{ project.local_path }}/web/app/themes/sage"
     cmd: npm install
   - path: "{{ project.local_path }}/web/app/themes/sage"
     cmd: bower install
   - path: "{{ project.local_path }}/web/app/themes/sage"
     cmd: gulp --production

  - name: compiled theme assets
    src: "{{ project.local_path }}/web/app/themes/sage/dist"
    dest: web/app/themes/sage

    local_path: ../bedrock # path targeting local Bedrock site directory (relative to Ansible root)
    branch: master
    # subtree: site # Use this if following the roots-example-project structure
      enabled: false
      subdomains: false
      enabled: false
      enabled: false
      duration: 30s
    system_cron: true
      wp_env: staging
      db_name: my_db
      db_user: my_user
      db_password: my_password
      auth_key: "..."
      auth_salt: "..."
      logged_in_key: "..."
      logged_in_salt: "..."
      nonce_key: "..."
      nonce_salt: "..."
      secure_auth_key: "..."
      secure_auth_salt: "..."

The biggest thing I’m unclear about is the relationship between Sage’s repo and Bedrock’s repo. Does the build task cover everything from Sage effectively? Anything jump out as objectively wrong?

I’m running a pretty vanilla Bedrock site - the only mods I’ve made so far are including Composer packages really. I hunted around a bunch of documentation and cobbled this together, apologizes if some of this is just noob-ness.

I thought it might be helpful to see the playbook output too (anonymized but I think you can get the idea):

PLAY [Deploy WP site] *********************************************************

GATHERING FACTS ***************************************************************
ok: []

TASK: [deploy | Initialize] ***************************************************
ok: []

TASK: [deploy | Clone project files] ******************************************
ok: []

TASK: [deploy | write unfinished file] ****************************************
changed: []

TASK: [deploy | Copy files to new build dir] **********************************
changed: []

TASK: [deploy | Move project subtree into root folder] ************************
skipping: []

TASK: [deploy | Remove unwanted files/folders from new release] ***************
changed: [] => (item=.git)

TASK: [deploy | Run pre_build_commands_local on Ansible host] *****************
changed: [ ->] => (item={'path': u'../example-bedrock/web/app/themes/sage', 'cmd': 'npm install'})
changed: [ ->] => (item={'path': u'../example-bedrock/web/app/themes/sage', 'cmd': 'bower install'})
changed: [ ->] => (item={'path': u'../example-bedrock/web/app/themes/sage', 'cmd': 'gulp --production'})

TASK: [deploy | Copy project local files] *************************************
changed: [ ->] => (item={'dest': 'web/app/themes/sage', 'src': u'../example-bedrock/web/app/themes/sage/dist', 'name': 'compiled theme assets'})

TASK: [deploy | Copy project templates] ***************************************
changed: [] => (item={'dest': '.env', 'src': 'roles/deploy/templates/env.j2', 'name': '.env config'})

TASK: [deploy | Run pre_build_commands in the new_release_path] ***************
skipping: []

TASK: [deploy | Check if project folders exist] *******************************
ok: [] => (item=vendor)

TASK: [deploy | Copy project folders] *****************************************
changed: [] => (item={'invocation': {'module_name': u'stat', 'module_args': u'path="/srv/www/example/current/vendor"'}, 'item': 'vendor', u'stat': {u'uid': 1001, u'exists': True, u'woth': False, u'mtime': 1440497269.68106, u'inode': 787856, u'isgid': False, u'size': 4096, u'wgrp': False, u'isuid': False, u'isreg': False, u'pw_name': u'web', u'gid': 33, u'ischr': False, u'wusr': True, u'xoth': True, u'rusr': True, u'nlink': 5, u'issock': False, u'rgrp': True, u'gr_name': u'www-data', u'path': u'/srv/www/example/current/vendor', u'xusr': True, u'atime': 1440497269.68106, u'isdir': True, u'ctime': 1440497269.68106, u'isblk': False, u'xgrp': True, u'dev': 64769, u'roth': True, u'isfifo': False, u'mode': u'0755', u'islnk': False}, u'changed': False})

TASK: [deploy | Ensure shared sources are present] ****************************
ok: [] => (item={'path': 'web/app/uploads', 'src': 'uploads'})

TASK: [deploy | Ensure shared paths are absent] *******************************
changed: [] => (item={'path': 'web/app/uploads', 'src': 'uploads'})

TASK: [deploy | Create shared symlinks] ***************************************
changed: [] => (item={'path': 'web/app/uploads', 'src': 'uploads'})

TASK: [deploy | Run post_build_commands in the new_release_path] **************
changed: [] => (item={'cmd': 'composer install --no-ansi --no-dev --no-interaction --no-progress --optimize-autoloader --no-scripts'})

TASK: [deploy | Finalize the deploy] ******************************************
changed: []

TASK: [deploy | Run post_finalize_commands] ***********************************
changed: [] => (item=if wp core is-installed; then wp eval 'wp_clean_themes_cache(); switch_theme(get_stylesheet());'; fi)
changed: [] => (item=sudo service php5-fpm reload)

TASK: [deploy | debug ] *******************************************************
ok: [] => {
    "msg": "master@ABC123 deployed as release 201508940189409183123"

PLAY RECAP ********************************************************************             : ok=18   changed=12   unreachable=0    failed=0

If site_hosts has, then wp_home and wp_siteurl should be parallel, i.e., should not have dev subdomain. These might be correct in your pre-anonymized version.

repo: is expected to be a Bedrock repo with a sage theme included (committed to the themes directory).

If that repo also includes Trellis and is structured like the example project, don’t forget to uncomment # subtree: site.

The project_pre_build_commands_local and project_local_files should indeed install your bower components and compile your theme assets, then sync them from your local machine to your server (“covering everything from sage effectively”).

You might want to be sure your version of Trellis is at least as new as b6aba1e (Aug 15, 2015) to avoid some weirdness that can happen while cloning your repo.

Could you explain a little more? Do you mean your theme files seem missing? Or more is missing than that?

As @fullyint said, there is no relationship between them. Trellis deploys a single repository. So if you’re using Sage it means you need to commit Sage to your Bedrock/project repo.

You can always just do a git clone (whatever it is) locally to see exactly what Trellis will “deploy” to the server.

@fullyint + @swalkinshaw: Thanks for the advice. I added Sage into my main bedrock repo but I didnt notice any changes post-deployment. When I uncommented the subtree: site-directory line and also continued to get a successful deployment confirmation.

When I SSH into my server post-deployment, /home/user is empty. So is var/www/html which I’m assuming the target of the deployment payload. I don’t see any of the files on the server - maybe there is a special target directory?

I reran my ansible staging playbook thinking that might be an issue ansible-playbook -i hosts/staging server.yml. It successfully ran so I then did another deploy that says it’s successful but, again, no code seems to be uploaded.

I feel like the staging build file is missing some copy task - any ideas?

You’ll see in deploy.yml that your website files are at
project_root: "{{ www_root }}/{{ site }}"
When you resolve the www_root and site variables, you get something like /srv/www/

You’ll find that the files from your repo are deployed to /srv/www/, so your theme files can be found at /srv/www/

Like Capistrano, that current directory is actually a symlink to one of the time-stamped releases.


@fullyint: Good info, I hadn’t read about that aspect of this system.

I SSHed into /srv/www/site/current and indeed the files are in there. But the server provisioned via Ansible still points at var/www/html when you go to the root domain.

What I don’t get is that if I provisioned the server with ansible and successfully deployed to it, what is the missing piece of glue to get the site showing up at the root domain? Is there some part of the staging script that needs adjusting to complete the loop? Server setting?

I haven’t heard of the /var/www/html issue with with Trellis. Could you share which host you’re using and confirm that you’re just using the stock/bare Ubuntu 14.04 box without anything particular pre-installed (e.g., that you’ve haven’t actually created a LAMP droplet like this)? If you’ve selected extras for the host to install, they might be installed to /var/www/html by default, possibly throwing things off.

I think you may be trying to get the provisioning and deployment working while having some customizations to the default Trellis, which would be totally natural. To ease debugging, however, I’d recommend getting it all working on a vanilla install first and only then adding customizations, and testing as you go.

For example, I think you could test with only 2 tiny config changes to the default:

  • spin up a new droplet
  • config 1: add the droplet IP to hosts/staging
  • config 2: temporarily put a record in your /etc/hosts file that points to that IP
  • run server.yml
  • run deploy.yml
  • visit in your browser and do the WP install via the GUI

I understand you may want to only share anonymized config files, but it’s hard to tell whether inconsistencies are in your pre-anonymized versions, or just artifacts of your anonymizing. For example, first local_path: ../bedrock, but then the playbook output shows the pre_build_commands_local are apparently running in ../example-bedrock. Then you mention "I uncommented the subtree: site-directory", but that directory name usually should correspond with the directory name in local_path, like how it is site for both local_path and subtree in the default configs.

Keep pushing. I think light is right around the corner. :high_brightness: :wink: Although I think it’s usually a little easier than this, all the trial and error will sure have exposed you to stuff that grants you a bigger understanding of the tools, which can only be helpful. Good work.

1 Like

@fullyint: thanks for the instruction and support. I will try out a clean setup today and see what I can glean from all that. Cheers.