Tutorial · Laravel

Instalar o Laravel 13 num servidor Debian 13 com nginx

5 capítulos · 1 h 15 · Intermédio · Composer, Debian · verificado a 7 Setembro 2026

Resposta rápida

No Debian 13, o PHP 8.4 vem dos repositórios oficiais: não é preciso nenhum repositório externo. Instala o PHP e as suas extensões, o Composer (verificando a assinatura), cria o projeto com composer create-project laravel/laravel, dá permissões de escrita a storage/ e a bootstrap/cache/ e aponta a raiz do nginx para public/. Confirma o resultado: a página inicial tem de responder 200 e /.env tem de responder 403.

Este guia percorre a instalação completa de uma aplicação Laravel 13 num servidor Debian 13, de um sistema virgem até uma página servida pelo nginx. Cada etapa foi executada num Debian 13 «trixie» limpo a 2 de setembro de 2026, e o resultado final verificado: resposta HTTP 200 na página inicial, ficheiro .env inacessível a partir da web.

Artigo do percurso Desenvolvimento web. Cinco etapas têm o seu próprio capítulo detalhado, listado na barra lateral. O que se segue é a sequência completa, com o que é preciso para chegar ao fim.

O que é preciso antes de começar

  • Um servidor Debian 13 «trixie» acessível por SSH. O Debian 12 também serve, com PHP 8.2.
  • Um utilizador não-root com sudo. Não instales nem faças deploy como root.
  • Uma máquina de desenvolvimento do teu lado. No macOS, o bloqueio habitual é o comando laravel não encontrado.
  • Um nome de domínio a apontar para o servidor, se contas usar HTTPS.

Cria o utilizador que vai suportar a aplicação, se ainda não existir:

bash
sudo adduser deploy
sudo usermod -aG sudo deploy

1. O PHP e as suas extensões

O Debian 13 fornece o PHP 8.4, o que dispensa o repositório externo Sury:

bash
sudo apt update
sudo apt install -y php-cli php-fpm \
  php-mbstring php-xml php-curl php-zip \
  php-bcmath php-intl php-mysql php-sqlite3 \
  unzip curl ca-certificates

php -v   # PHP 8.4.24

O detalhe das extensões necessárias, as afinações do php.ini e o procedimento para instalar outra versão do PHP estão no capítulo dedicado ao PHP.

2. O Composer

Instala-o verificando a assinatura do instalador, como prescreve a documentação oficial:

bash
EXPECTED="$(curl -sS https://composer.github.io/installer.sig)"
curl -sS https://getcomposer.org/installer -o composer-setup.php
ACTUAL="$(php -r 'echo hash_file("sha384", "composer-setup.php");')"

if [ "$EXPECTED" = "$ACTUAL" ]; then
    sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
fi
rm composer-setup.php

composer --version   # Composer version 2.10.3

3. Criar o projeto Laravel

Como utilizador deploy, nunca como root:

bash
su - deploy
composer create-project laravel/laravel /home/deploy/app --no-interaction
cd /home/deploy/app
php artisan --version   # Laravel Framework 13.30.1

O create-project gera o ficheiro .env, cria a chave da aplicação e executa as migrações na base SQLite predefinida. Para uma base MySQL ou MariaDB, cuja instalação tem um capítulo próprio, preenche a ligação e volta a lançar as migrações:

.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=un_mot_de_passe_solide
bash
php artisan migrate --force

4. Permissões dos ficheiros

É o passo que se salta e que produz a página em branco, ou um erro 500. As pastas em causa correspondem a storage_path() e bootstrap/cache, descritas em os caminhos da aplicação, mais database/ enquanto a aplicação usar a base SQLite criada na instalação: o driver de sessão escreve nela a cada visita. O servidor web tem de poder escrever nestas três pastas, e apenas nestas:

bash
sudo chown -R deploy:www-data /home/deploy/app/storage /home/deploy/app/bootstrap/cache /home/deploy/app/database
sudo chmod -R 775 /home/deploy/app/storage /home/deploy/app/bootstrap/cache /home/deploy/app/database

Se o projeto viver na pasta pessoal de um utilizador, o nginx tem de a poder atravessar:

bash
sudo chmod o+x /home/deploy
Nunca chmod -R 777

É o conselho mais divulgado e o mais perigoso: torna a aplicação modificável por qualquer conta do servidor. 775 com o grupo certo chega, e foi o que se usou na verificação.

5. nginx e PHP-FPM

Esta secção instala o nginx. Se preferires o Apache, mais comum em alojamento partilhado, segue antes o capítulo dedicado ao Apache: o resto do guia mantém-se válido.

bash
sudo apt install -y nginx php-fpm

Anota o caminho exato do socket, que traz o número de versão do PHP:

bash
grep -h '^listen' /etc/php/8.4/fpm/pool.d/www.conf
# listen = /run/php/php8.4-fpm.sock

Cria o ficheiro do site. A raiz aponta para public/, nunca para a raiz do projeto:

/etc/nginx/sites-available/laravel
server {
    listen 80;
    server_name exemple.com;
    root /home/deploy/app/public;
    index index.php;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.4-fpm.sock;
        fastcgi_index index.php;
        include fastcgi.conf;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

Ativa o site, desativa o predefinido, verifica a sintaxe:

bash
sudo ln -s /etc/nginx/sites-available/laravel /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t
sudo systemctl reload nginx
code
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

6. Verificar a instalação

Bastam dois controlos para saber se a instalação se aguenta:

bash
curl -s -o /dev/null -w "page d'accueil : %{http_code}\n" http://127.0.0.1/
curl -s -o /dev/null -w ".env          : %{http_code}\n" http://127.0.0.1/.env
code
page d'accueil : 200
.env          : 403

O segundo é o mais importante. Um 200 em /.env significaria que as tuas credenciais de base de dados e a tua APP_KEY são publicamente legíveis. É o bloco location ~ /\.(?!well-known).* que o impede, e é por isso que a raiz do site tem de ser public/.

7. Passar a produção

A configuração de desenvolvimento deixa fugir informação. Três linhas no .env:

.env
APP_ENV=production
APP_DEBUG=false
APP_URL=https://exemple.com

Depois as caches, a regenerar a seguir a cada deploy:

bash
composer install --no-dev --optimize-autoloader
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan about --only=environment   # O Debug Mode deve mostrar OFF

O detalhe desta afinação é tratado no artigo sobre o modo de depuração.

Acrescenta o HTTPS com o Certbot, que altera ele próprio a configuração do nginx:

Se a aplicação expuser formulários públicos, prevê também uma proteção contra os envios automatizados.

bash
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d exemple.com

Por fim, o agendador de tarefas, se a aplicação usar algum:

bash
sudo crontab -u deploy -e
# * * * * * cd /home/deploy/app && php artisan schedule:run >> /dev/null 2>&1

Para a cache, as sessões e as filas de espera em Redis, continua com o capítulo dedicado ao Redis.

Começar o tutorial

Erros frequentes

Raiz do nginx no projeto em vez de public/ Todo o código-fonte, incluindo o ficheiro .env, fica descarregável. Confirma sempre que /.env devolve 403.
chmod -R 777 em storage Torna a aplicação modificável por qualquer conta do servidor. Chega 775 com o grupo www-data.
Composer lançado com sudo Os scripts das dependências correm como root e os ficheiros criados deixam de ser escrevíveis pelo servidor web.
Caminho do socket PHP-FPM escrito à mão O caminho contém o número de versão: /run/php/php8.4-fpm.sock. Lê-o no pool em vez de o copiar.
Pasta pessoal não atravessável Um projeto em /home/deploy exige chmod o+x /home/deploy, senão o nginx devolve um erro de permissões.
Esquecer de regenerar as caches Depois de um deploy, config:cache, route:cache e view:cache têm de ser relançados, senão fica ativa a configuração antiga.
Newsletter

Os novos testes, tutoriais e projetos, por e-mail.

Testes reproduzíveis, código versionado, resultados datados. Nunca spam.