{"id":1009,"date":"2026-11-05T09:00:00","date_gmt":"2026-11-05T09:00:00","guid":{"rendered":"https:\/\/vpslake.com\/blog\/?p=1009"},"modified":"2026-11-05T09:00:00","modified_gmt":"2026-11-05T09:00:00","slug":"install-php-composer-debian-11","status":"publish","type":"post","link":"https:\/\/vpslake.com\/blog\/2026\/11\/05\/install-php-composer-debian-11\/","title":{"rendered":"How to Install PHP Composer on Debian 11 (Step-by-Step)"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Install PHP Composer on Debian 11 with a verified installer, then use it to add a PHP package and generate an autoloader. You can complete the setup and run the test project in about ten minutes on a fresh VPS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>A Debian GNU\/Linux 11 (Bullseye) 64-bit VPS. Debian 11 is an older release, so use a supported Debian version for a new long-lived production server when possible.<\/li>\n\n\n<li>SSH access as <code>root<\/code>, or a normal account with <code>sudo<\/code> privileges and a writable home directory.<\/li>\n\n\n<li>At least 1 GB of RAM and 2 GB of free disk space for PHP, Composer&#8217;s cache, and the sample project.<\/li>\n\n\n<li>Outbound HTTPS access to <code>getcomposer.org<\/code> and Packagist. Composer does not require a domain or an inbound firewall port.<\/li>\n\n\n<li>A <a href=\"https:\/\/vpslake.com\/buy-vps\">VPSLake Linux VPS<\/a> if you need a Debian server with root access.<\/li>\n\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">The commands below use <code>sudo<\/code> for a normal SSH account. If you are already <code>root<\/code>, remove <code>sudo<\/code> and run the commands from a non-production test directory where appropriate.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 1: Confirm Debian 11 and install PHP prerequisites<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Check the release first so you do not mix Bullseye packages with repositories for a newer Debian version.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>grep -E '^(PRETTY_NAME|VERSION_CODENAME)=' \/etc\/os-release\ndpkg --print-architecture\nsudo apt update\nsudo apt install -y ca-certificates curl git php-cli php-curl php-zip unzip<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><code>php-cli<\/code> provides the PHP command Composer runs, while <code>php-curl<\/code>, <code>php-zip<\/code>, and <code>unzip<\/code> let Composer download and extract packages efficiently. Debian 11 should report <code>VERSION_CODENAME=bullseye<\/code>; the usual VPS architectures are <code>amd64<\/code> and <code>arm64<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>PRETTY_NAME=\"Debian GNU\/Linux 11 (bullseye)\"\nVERSION_CODENAME=bullseye\namd64<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Confirm the PHP version before continuing:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The Debian 11 repository normally provides PHP 7.4. Composer&#8217;s current stable line supports PHP 7.2.5 and newer, but a package you later choose can set a higher PHP requirement.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 2: Download and verify the Composer installer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The checksum comparison detects a changed or incomplete installer before PHP executes it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Work in your home directory and fetch both the installer and its current SHA-384 signature from Composer&#8217;s official endpoints:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\ncurl -fsSLo composer-setup.php https:\/\/getcomposer.org\/installer\nEXPECTED_CHECKSUM=\"$(curl -fsSL https:\/\/composer.github.io\/installer.sig)\"\nACTUAL_CHECKSUM=\"$(php -r \"echo hash_file('sha384', 'composer-setup.php');\")\"\nif [ \"$EXPECTED_CHECKSUM\" != \"$ACTUAL_CHECKSUM\" ]; then echo 'ERROR: Invalid Composer installer checksum'; rm -f composer-setup.php; exit 1; fi\necho 'Installer checksum verified'<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Installer checksum verified<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the check fails, do not run the installer. Remove the file, check DNS and HTTPS connectivity, and download it again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 3: Install Composer globally<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Place the Composer executable in <code>\/usr\/local\/bin<\/code> so every user can call <code>composer<\/code> without changing their shell profile.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo php composer-setup.php --install-dir=\/usr\/local\/bin --filename=composer\nsudo chmod 0755 \/usr\/local\/bin\/composer\nrm -f composer-setup.php<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The installer prints a success message and the path it used. The exact Composer version changes over time, so do not hard-code the version from an example:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>All settings correct for using Composer\nComposer (version 2.x.y) successfully installed to: \/usr\/local\/bin\/composer<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Composer&#8217;s <a href=\"https:\/\/getcomposer.org\/doc\/00-intro.md\" target=\"_blank\" rel=\"noopener\">official installation guide<\/a> documents the installer and its PHP requirements. Verify the binary and run its diagnostics:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>composer --version\ncomposer diagnose<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Expected output includes a Composer 2 version, your PHP version, and a final line similar to <code>Everything is OK<\/code> from the diagnostics. Warnings about optional tools are worth reviewing before a production deployment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 4: Create a project as a non-root user<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Composer can execute package-provided scripts, so keep project files owned by a normal deployment user instead of running dependency installation as <code>root<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your SSH session is currently <code>root<\/code>, switch to the account that will own the application before creating the project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo -iu YOUR_DEPLOY_USER<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace <code>YOUR_DEPLOY_USER<\/code> with an existing non-root account. Stay in that user&#8217;s shell for the remaining project commands.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a small project and require Monolog 2, which supports the PHP version normally shipped with Debian 11:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/composer-demo\ncd ~\/composer-demo\ncomposer require monolog\/monolog:^2.0<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Composer creates <code>composer.json<\/code>, resolves compatible dependencies, writes the exact versions to <code>composer.lock<\/code>, and builds <code>vendor\/autoload.php<\/code>. The output should finish with package installation and autoload generation messages.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inspect the generated files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>find . -maxdepth 2 -type f -printf '%p\\n' | sort<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see at least these paths:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.\/composer.json\n.\/composer.lock\n.\/vendor\/autoload.php<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>composer.json<\/code> file declares what the project needs; <code>composer.lock<\/code> records the resolved versions so another server can reproduce the same dependency set.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step 5: Test Composer&#8217;s autoloader<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Requiring <code>vendor\/autoload.php<\/code> lets PHP find the Monolog classes without manually including files from each package.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a short script that writes one log entry to standard output:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/composer-demo\ntee demo.php &gt;\/dev\/null &lt;&lt;'PHP'\n&lt;?php\n\nrequire __DIR__ . '\/vendor\/autoload.php';\n\nuse Monolog\\Handler\\StreamHandler;\nuse Monolog\\Logger;\n\n$log = new Logger('demo');\n$log-&gt;pushHandler(new StreamHandler('php:\/\/stdout', Logger::INFO));\n$log-&gt;info('Composer autoloading works on Debian 11.');\nPHP\nphp demo.php<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The timestamp will differ, but the message proves that PHP loaded the Composer-generated autoloader and the installed package:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[2026-10-08T12:00:00.000000+00:00] demo.INFO: Composer autoloading works on Debian 11. [] []<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Verify Composer on Debian 11<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run these checks from the project directory to validate the executable, manifest, lock file, platform extensions, and PHP script:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/composer-demo\ncomposer --version\ncomposer validate --strict\ncomposer check-platform-reqs\nphp demo.php<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The validation command should report that <code>composer.json<\/code> is valid, platform checks should show successful requirements, and the last command should print the Monolog message. There is no web server or public port in this example, so no firewall rule is needed.<\/p>\n\n\n\n<aside class=\"vl-element vl-cta-banner\" aria-label=\"Run Composer on Bullseye\">\n\t<div class=\"vl-cta-banner__content\">\n\t\t<p class=\"vl-cta-banner__eyebrow\">Debian VPS<\/p>\n\t\t<h3 class=\"vl-cta-banner__title\">Run Composer on Bullseye<\/h3>\n\t\t<p class=\"vl-cta-banner__text\">Build PHP projects on a Debian VPS with dependable root access and fast SSD storage.<\/p>\n\t<\/div>\n\t<a class=\"vl-cta-banner__button\" href=\"\/buy-vps\" aria-label=\"View Linux VPS plans\">View Linux VPS plans<\/a>\n<\/aside>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><code>php: command not found<\/code> or the installer rejects the PHP version<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The PHP CLI package is missing, or the shell is using a different PHP binary than expected. Install Debian 11&#8217;s CLI package and check the active binary:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt install -y php-cli\ncommand -v php\nphp --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Do not bypass Composer&#8217;s PHP requirement with <code>--ignore-platform-reqs<\/code>; install a supported PHP version or choose a package release compatible with Debian 11.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>Invalid Composer installer checksum<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The installer and signature did not come from the same download, or a proxy returned an altered response. Delete the file and retry after confirming that HTTPS and DNS work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>rm -f ~\/composer-setup.php\ncurl -I https:\/\/getcomposer.org\/installer\ncurl -I https:\/\/composer.github.io\/installer.sig<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the endpoints are blocked, fix the VPS&#8217;s outbound network or proxy configuration rather than executing an unchecked installer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>Do not run Composer as root\/super user<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This is a safety warning because dependency scripts can run with the permissions of the account that launches Composer. Switch to the account that owns the application and run Composer there; use <code>sudo<\/code> only for system-wide installation in <code>\/usr\/local\/bin<\/code>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo -iu YOUR_DEPLOY_USER\ncd \/PATH\/TO\/YOUR_PROJECT\ncomposer install<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace the uppercase placeholders with an existing deployment account and project path. Avoid setting <code>COMPOSER_ALLOW_SUPERUSER=1<\/code> unless you fully control every package and script being installed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><code>Your requirements could not be resolved<\/code> or a missing <code>ext-*<\/code> extension<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The selected package needs a PHP version or extension that is not available in the current environment. Read the first requirement named in the error, then check and install the matching Debian package:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>php -m | sort\nsudo apt install -y php-curl php-zip\ncomposer check-platform-reqs<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If the package itself requires PHP 8.x, do not force the install on Debian 11&#8217;s default PHP 7.4. Select an older compatible package constraint or plan an OS\/PHP upgrade.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hardening<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n\n<li>Keep <code>composer.lock<\/code> in application deployments so production receives the versions you reviewed, and run <code>composer install<\/code> rather than an unrestricted <code>composer update<\/code> there.<\/li>\n\n\n<li>Review dependency advisories with <code>composer audit<\/code> before releasing an application.<\/li>\n\n\n<li>Keep the Composer binary and PHP packages updated, but schedule the Debian 11 upgrade because the release is old for new production workloads.<\/li>\n\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">FAQ<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Does Composer work with PHP 7.4 on Debian 11?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Yes. Composer&#8217;s current stable requirements include PHP 7.2.5 and newer, so Debian 11&#8217;s usual PHP 7.4 package can run Composer. The individual library you install may still require PHP 8.x, so Composer will check each project&#8217;s platform requirements.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Should I use <code>composer install<\/code> or <code>composer update<\/code>?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Use <code>composer update<\/code> when you intentionally want Composer to resolve newer versions and rewrite <code>composer.lock<\/code>. Use <code>composer install<\/code> on a server or fresh checkout when you want the versions already recorded in the lock file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Where does the global Composer command live?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This guide installs it at <code>\/usr\/local\/bin\/composer<\/code>, a standard system-wide executable path. Run <code>command -v composer<\/code> to confirm which copy your shell is using if another Composer installation is already present.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Do I need a domain or web server to use Composer?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">No. Composer manages PHP project dependencies and only needs outbound HTTPS access to download packages. Add a domain, web server, and TLS later if the PHP application itself will serve public requests.<\/p>\n\n\n\n<script type=\"application\/ld+json\">{\"@context\": \"https:\/\/schema.org\", \"@type\": \"FAQPage\", \"mainEntity\": [{\"@type\": \"Question\", \"name\": \"Does Composer work with PHP 7.4 on Debian 11?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Yes. Composer's current stable requirements include PHP 7.2.5 and newer, so Debian 11's usual PHP 7.4 package can run Composer. The individual library you install may still require PHP 8.x, so Composer will check each project's platform requirements.\"}}, {\"@type\": \"Question\", \"name\": \"Should I use `composer install` or `composer update`?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"Use `composer update` when you intentionally want Composer to resolve newer versions and rewrite `composer.lock`. Use `composer install` on a server or fresh checkout when you want the versions already recorded in the lock file.\"}}, {\"@type\": \"Question\", \"name\": \"Where does the global Composer command live?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"This guide installs it at `\/usr\/local\/bin\/composer`, a standard system-wide executable path. Run `command -v composer` to confirm which copy your shell is using if another Composer installation is already present.\"}}, {\"@type\": \"Question\", \"name\": \"Do I need a domain or web server to use Composer?\", \"acceptedAnswer\": {\"@type\": \"Answer\", \"text\": \"No. Composer manages PHP project dependencies and only needs outbound HTTPS access to download packages. Add a domain, web server, and TLS later if the PHP application itself will serve public requests.\"}}]}<\/script>\n\n","protected":false},"excerpt":{"rendered":"Install PHP Composer on Debian 11 with signature verification, a working Monolog project, autoloading test, update commands, and fixes for common errors.","protected":false},"author":1,"featured_media":1010,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_singular_sidebar":"","csco_page_header_type":"","csco_page_load_nextpost":"","footnotes":""},"categories":[5,9],"tags":[122,96,72,121],"class_list":["post-1009","post","type-post","status-publish","format-standard","has-post-thumbnail","category-guides","category-vps-hosting","tag-composer","tag-debian-11","tag-php","tag-php-composer","cs-entry"],"_links":{"self":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/1009","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/comments?post=1009"}],"version-history":[{"count":1,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/1009\/revisions"}],"predecessor-version":[{"id":3898,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/posts\/1009\/revisions\/3898"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media\/1010"}],"wp:attachment":[{"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/media?parent=1009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/categories?post=1009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vpslake.com\/blog\/wp-json\/wp\/v2\/tags?post=1009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}