Trellis stuck on Install Composer dependencies

I’m on a Mac and for most of our projects, my deployment process gets stuck on the ‘Install Composer dependencies’ task. My teammates who run on Windows can deploy without any problems. Any idea what it could be?

ansible [core 2.18.4]
  config file = None
  configured module search path = ['/Users/***/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /opt/homebrew/Cellar/ansible/11.4.0/libexec/lib/python3.13/site-packages/ansible
  ansible collection location = /Users/***/.ansible/collections:/usr/share/ansible/collections
  executable location = /opt/homebrew/bin/ansible
  python version = 3.13.3 (main, Apr  8 2025, 13:54:08) [Clang 16.0.0 (clang-1600.0.26.6)] (/opt/homebrew/Cellar/ansible/11.4.0/libexec/bin/python)
  jinja version = 3.1.6
  libyaml = True

What did you get for output when using verbose output? Any composer authentication involved for private packages?

Also see Deploy failed - Composer and https://discourse.roots.io/t/deploy-failed-because-of-composer-dependencies/27810/7 which may offer clues .

1 Like

hi, i didn’t get any output it’s just stuck there without displaying error. yes there are few of private repos.

I’m using Composer version 2.8.8 but my teammates also use version 2+

Also as I said above it’s not for all case but majority of cases

Do a ansible-playbook server.yml -e env=production -vvvv for verbose output. Also see Troubleshooting | Trellis Docs | Roots

Also as I said above it’s not for all case but majority of cases

That is odd. But was thinking ssh key or private composer package key issue. Either way verbose output sharing of one of the failed cases would be good.

this is in verbose with -vvvv
And it’s stuck there forever

You see

TASK
[deploy : Install Composer dependencies] **************:
/Volumes/Workstation/projects
/trellis/roles/deploy/hooks/build-after. yml: 61
redirecting (type: modules) ansible.builtin.composer to community.general.composer redirecting (type: modules) ansible.builtin.composer to community.general. composer
Using module file /opt/homebrew/Cellar/ansible/11.4.0/libexec/lib/python3.13/site-packages/ansible_collections/community/general/plugins/modules/composer.py
Pipelining is enabled.
ESTABLISH SSH CONNECTION FOR USER: web
SSH: EXEC ssh
publickey -o PasswordAuthentication=no -o 'User="web"' -o ConnectTimeout=10 -o 'ControlPath="/Users/
-vwv-0 ForwandAgent=yes -0 ControlMasten-auto -0 ControlPensist-60 -0 HostKeyALgorithms-ssh-d25519-ent-v01@openseh.com, ssh-nsa-cent-v1@openssh.com, ssh-d25519, ssh-na -0 KbdIntenactiveUthentication-no -0 PrefernedAuthentications=gssapi-mith-mic, gssapi-keyex, hostbased,
/bin/sh -e turm /usr/bin/pvthon3.12 && sleep ourne

can you ssh web@your-server-ip with user web? If not with -v as well.

Did you add composer authentication in your setup similar to:

composer_authentications:
    # Advanced Custom Fields (ACF) PRO plugin
    - {
        hostname: "connect.advancedcustomfields.com",
        username: "xxxxxxxxxx==",
        password: "https://domain.com"
      }

for the private ones? See Composer HTTP Basic Authentication | Trellis Docs | Roots

yes i can login to the server no problem.
yes on each project i have auth.json stored in site folder (.gitignored) and if some plugins required composer authentication i add it to both auth.json and vaults

1. Check Composer Version and Dependencies on the Remote

Sometimes the remote server might have an outdated Composer or PHP config that hangs during composer install. SSH into the server and run:

composer --version
php -v

Make sure Composer 2.x and a compatible PHP version are installed.

2. Manually Run Composer Install on Remote

SSH into the deployed release path and manually run composer install. This will help surface any dependency conflicts or interactive prompts.

cd /srv/www/your-site/current
composer install

So this is what my mac has
Composer version 2.8.8
PHP version 8.4.6

And this is from the environment
Composer version 2.8.8
PHP version 8.3.20

Run the “diagnose” command to get more detailed diagnostics output.

Have you tried running composer install directly, whilst SSH’d in?

not yet, i downgraded my mac php to 8.3 and see if this helps. If not i will try running composer install directly from the server

Ok, downgrading php did not helped.

When I SSH to the server to one of the releases folder and run composer update command i get the following message:

Your GitHub credentials are required to fetch private repository metadata (https://github.com/***/***.git)
When working with _public_ GitHub repositories only, head here to retrieve a token:
https://github.com/settings/tokens/new?scopes=&description=Composer+on+***+2025-04-30+1913
This token will have read-only permission for public information only.
When you need to access _private_ GitHub repositories as well, go to:
https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+newadi.levcharity.dev+2025-04-30+1913
Note that such tokens have broad read/write permissions on your behalf, even if not needed by Composer.
Tokens will be stored in plain text in "/srv/www/***/releases/20250430165651/auth.json OR /home/web/.config/composer/auth.json" for future use by Composer.
For additional information, check https://getcomposer.org/doc/articles/authentication-for-private-packages.md#github-oauth

Now this auth.json stored in the server does not contains my git pat token to access private repos. Although my local version auth.json does.

My fine-grained token has: Contents and Metadata (read-only permission)

This is what I do every now and then when my token expires. It gets stored for my user given me access to Github properly again for all work that requires the token including access to private repos.

ll /Users/user/.composer/auth.json 
-rw-------@ 1 user  staff   207B Apr 13 11:00 /Users/user/.composer/auth.json
cat /Users/user/.composer/auth.json
{
    "bitbucket-oauth": {},
    "github-oauth": {
        "github.com": "ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"},
    "gitlab-oauth": {},
    "gitlab-token": {},
    "http-basic": {},
    "bearer": {}
}

That way SSH forwarding and getting data from private repository works.

I found the problem. We are using about 40+ private repos on each project which are directly pulled from Git. The problem is that when you do it through Git, each private repo downloads every tag and every branch. This significantly extends the process of composer update.

After realizing the above, I found this video where the guy explains that for his project with 80k+ tags and multiple branches, updating composer lasted for 3.5h.

Solution is adding your private repos through Private Packagist.

BTW: I don’t know why my colleagues who use Ubuntu didn’t face the same issue.

3 Likes