V prvním příkladu dáváte -c příznak na docker exec . To je snadná odpověď:docker exec nemá -c vlajka.
Ve vašem druhém příkladu to váš shell analyzuje na dva příkazy, než to Docker vůbec uvidí. Je ekvivalentní tomuto:
if docker exec [id] cd /var/www/project
then
    composer install
fi
 Nejprve docker exec je spuštěn, a pokud skončí 0 (úspěch), composer install se pokusí spustit lokálně , mimo Docker.
 Co musíte udělat, je předat oba příkazy jako jeden argument do docker exec pomocí provázku. Pak nebudou interpretovány shellem, dokud nebudou uvnitř kontejneru.
docker exec [id] "cd /var/www/project && composer install"
 Jak jste však poznamenali v komentářích, toto také nefunguje. To proto, že cd je vestavěný shell a sám o sobě neexistuje. Pokus o provedení jako počáteční příkaz selže. Takže dalším krokem je předat to shellu k provedení.
docker exec [id] "bash -c 'cd /var/www/project && composer install'"
 A konečně v tomto bodě && se přesunula do vnitřní sady uvozovek, takže uvozovky kolem bash ve skutečnosti nepotřebujeme příkaz... můžete je zahodit, pokud chcete.
docker exec [id] bash -c 'cd /var/www/project && composer install'
 Vše za ID kontejneru je příkaz ke spuštění, takže v prvním příkladu -c není možnost spustit, ale příkazový docker se pokusí spustit a selže, protože tento příkaz neexistuje.
 S největší pravděpodobností jste tuto syntaxi našli z docker run příkaz, kde byl vstupní bod nastaven na /bin/sh . Exec však obchází vstupní bod, takže ke spuštění musíte zahrnout celý příkaz. Jak jiní zdůraznili, tento příkaz obsahuje shell jako bash nebo v níže uvedeném příkladu sh:
docker exec [id] /bin/sh -c 'cd /var/www/project && composer install'