{"id":64,"date":"2025-03-12T08:46:00","date_gmt":"2025-03-12T07:46:00","guid":{"rendered":"http:\/\/rarathemesdemo.com\/perfect-portfolio\/?p=64"},"modified":"2025-03-12T09:30:00","modified_gmt":"2025-03-12T08:30:00","slug":"symfony_nextjs","status":"publish","type":"post","link":"https:\/\/www.pasqualepellicani.it\/index.php\/2025\/03\/12\/symfony_nextjs\/","title":{"rendered":"GUIDA COMPLETA: Symfony 7.x + API Platform + Next.js con Apache"},"content":{"rendered":"<p>1\ufe0f\u20e3 <strong>Installazione in locale (localhost)<\/strong><\/p>\n<p>2\ufe0f\u20e3 <strong>Deploy su un server remoto (Ubuntu + Apache)<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<hr \/>\n<h2><strong>\ud83d\udda5\ufe0f 1\ufe0f\u20e3 Installazione in LOCALE<\/strong><\/h2>\n<h2><strong>\ud83d\udccc Struttura del progetto<\/strong><\/h2>\n<pre><code>\/my-project\n\u2502\u2500\u2500 \/backend            # Symfony 7.x + API Platform (backend)\n\u2502   \u2502\u2500\u2500 \/bin\n\u2502   \u2502\u2500\u2500 \/config\n\u2502   \u2502\u2500\u2500 \/migrations\n\u2502   \u2502\u2500\u2500 \/public\n\u2502   \u2502\u2500\u2500 \/src\n\u2502   \u2502\u2500\u2500 \/var\n\u2502   \u2502\u2500\u2500 \/vendor\n\u2502   \u2502\u2500\u2500 .env\n\u2502   \u2502\u2500\u2500 composer.json\n\u2502\u2500\u2500 \/frontend           # Next.js + React Admin (frontend)\n\u2502   \u2502\u2500\u2500 \/components\n\u2502   \u2502\u2500\u2500 \/pages\n\u2502   \u2502\u2500\u2500 \/services\n\u2502   \u2502\u2500\u2500 .env.local\n\u2502   \u2502\u2500\u2500 package.json\n\u2502\u2500\u2500 README.md\n<\/code><\/pre>\n<hr \/>\n<h2><strong>1. Creare il Backend (Symfony + API Platform)<\/strong><\/h2>\n<h3><strong>1\ufe0f\u20e3 Installare Symfony 7.x con API Platform<\/strong><\/h3>\n<pre><code class=\"language-sh\">mkdir my-project\ncd my-project\ncomposer create-project symfony\/skeleton backend\ncd backend\ncomposer require api\n<\/code><\/pre>\n<p>\u2705 <strong>Ora il backend \u00e8 installato in <code>\/backend<\/code>.<\/strong><\/p>\n<h3><strong>2\ufe0f\u20e3 Installare JWT per l&#8217;autenticazione<\/strong><\/h3>\n<pre><code class=\"language-sh\">composer require security lexik\/jwt-authentication-bundle\nphp bin\/console lexik:jwt:generate-keypair\n<\/code><\/pre>\n<p>\u2705 <strong>Questo abilita l&#8217;autenticazione con JWT.<\/strong><\/p>\n<p>Modifica il file <strong><code>.env<\/code><\/strong>:<\/p>\n<pre><code class=\"language-ini\">JWT_SECRET_KEY=%kernel.project_dir%\/config\/jwt\/private.pem\nJWT_PUBLIC_KEY=%kernel.project_dir%\/config\/jwt\/public.pem\nJWT_PASSPHRASE=your-secret-passphrase\n<\/code><\/pre>\n<h3><strong>3\ufe0f\u20e3 Configurare Symfony Security<\/strong><\/h3>\n<p>\ud83d\udcc1 <strong>Modifica <code>config\/packages\/security.yaml<\/code><\/strong><\/p>\n<pre><code class=\"language-yaml\">security:\n    enable_authenticator_manager: true\n    password_hashers:\n        Symfony\\Component\\Security\\Core\\User\\PasswordAuthenticatedUserInterface: \"auto\"\n    \n    providers:\n        app_user_provider:\n            entity:\n                class: App\\Entity\\User\n                property: email\n\n    firewalls:\n        api_login:\n            pattern: ^\/api\/login\n            stateless: true\n            json_login:\n                check_path: \/api\/login\n        api:\n            pattern: ^\/api\/\n            stateless: true\n            jwt: ~\n\n    access_control:\n        - { path: ^\/api\/login, roles: PUBLIC_ACCESS }\n        - { path: ^\/api\/, roles: IS_AUTHENTICATED_FULLY }\n<\/code><\/pre>\n<p>\u2705 <strong>Ora la rotta <code>\/api\/login<\/code> genera un JWT per gli utenti autenticati.<\/strong><\/p>\n<h3><strong>4\ufe0f\u20e3 Creare il Database<\/strong><\/h3>\n<pre><code class=\"language-sh\">php bin\/console doctrine:database:create\nphp bin\/console make:migration\nphp bin\/console doctrine:migrations:migrate\n<\/code><\/pre>\n<hr \/>\n<h2><strong>2. Creare il Frontend (Next.js + React Admin)<\/strong><\/h2>\n<p>Spostati nella cartella principale:<\/p>\n<pre><code class=\"language-sh\">cd ..\nnpx create-next-app@latest frontend\ncd frontend\nnpm install react-admin @api-platform\/admin\n<\/code><\/pre>\n<p>Modifica il file <strong><code>.env.local<\/code><\/strong>:<\/p>\n<pre><code class=\"language-ini\">NEXT_PUBLIC_API_URL=http:\/\/localhost:8000\/api\n<\/code><\/pre>\n<p>Avvia il frontend:<\/p>\n<pre><code class=\"language-sh\">npm run dev\n<\/code><\/pre>\n<p>\u2705 <strong>Ora puoi accedere a <code>http:\/\/localhost:3000<\/code> per vedere il frontend in azione!<\/strong><\/p>\n<hr \/>\n<h2><strong>\ud83c\udf10 2\ufe0f\u20e3 Deploy su un SERVER REMOTO (Apache + PostgreSQL)<\/strong><\/h2>\n<h2><strong>1. Preparare il Server<\/strong><\/h2>\n<p>Accedi via SSH:<\/p>\n<pre><code class=\"language-sh\">ssh user@your-server-ip\n<\/code><\/pre>\n<p>Aggiorna il sistema:<\/p>\n<pre><code class=\"language-sh\">sudo apt update &amp;&amp; sudo apt upgrade -y\n<\/code><\/pre>\n<p>Installa PHP, Composer, Node.js e PostgreSQL:<\/p>\n<pre><code class=\"language-sh\">sudo apt install -y php8.3 php8.3-cli php8.3-mbstring php8.3-xml php8.3-bcmath php8.3-curl php8.3-zip php8.3-pgsql composer unzip curl git apache2 libapache2-mod-php nodejs npm\n<\/code><\/pre>\n<hr \/>\n<h2><strong>2. Clonare il progetto<\/strong><\/h2>\n<p>Spostati nella cartella di deploy:<\/p>\n<pre><code class=\"language-sh\">cd \/var\/www\ngit clone https:\/\/github.com\/tuo-repo\/my-project.git\ncd my-project\n<\/code><\/pre>\n<hr \/>\n<h2><strong>3. Configurare il Backend (Symfony)<\/strong><\/h2>\n<p>Spostati nella cartella <code>\/backend<\/code>:<\/p>\n<pre><code class=\"language-sh\">cd backend\ncomposer install --no-dev --optimize-autoloader\n<\/code><\/pre>\n<p>Configura il database in <code>.env.local<\/code>:<\/p>\n<pre><code class=\"language-ini\">APP_ENV=prod\nDATABASE_URL=\"pgsql:\/\/user:password@localhost:5432\/mydatabase\"\n<\/code><\/pre>\n<p>Esegui le migrazioni:<\/p>\n<pre><code class=\"language-sh\">php bin\/console doctrine:migrations:migrate --no-interaction\n<\/code><\/pre>\n<p>Configura Apache per il backend:<\/p>\n<pre><code class=\"language-sh\">sudo nano \/etc\/apache2\/sites-available\/api.conf\n<\/code><\/pre>\n<p>Aggiungi:<\/p>\n<pre><code>&lt;VirtualHost *:80&gt;\n    ServerName api.miosito.com\n    DocumentRoot \/var\/www\/my-project\/backend\/public\n\n    &lt;Directory \/var\/www\/my-project\/backend\/public&gt;\n        AllowOverride All\n        Require all granted\n    &lt;\/Directory&gt;\n\n    ErrorLog ${APACHE_LOG_DIR}\/api-error.log\n    CustomLog ${APACHE_LOG_DIR}\/api-access.log combined\n&lt;\/VirtualHost&gt;\n<\/code><\/pre>\n<p>Abilita il sito e riavvia Apache:<\/p>\n<pre><code class=\"language-sh\">sudo a2ensite api.conf\nsudo systemctl restart apache2\n<\/code><\/pre>\n<hr \/>\n<h2><strong>4. Configurare il Frontend (Next.js)<\/strong><\/h2>\n<p>Spostati nella cartella <code>\/frontend<\/code>:<\/p>\n<pre><code class=\"language-sh\">cd ..\/frontend\nnpm install\nnpm run build\n<\/code><\/pre>\n<p>Esegui Next.js con <strong>PM2<\/strong> per mantenerlo attivo:<\/p>\n<pre><code class=\"language-sh\">npm install -g pm2\npm2 start \"npm run start\" --name my-frontend\npm2 save\npm2 startup\n<\/code><\/pre>\n<p>\u2705 <strong>Ora il frontend sar\u00e0 visibile su <code>http:\/\/miosito.com<\/code>!<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>1\ufe0f\u20e3 Installazione in locale (localhost) 2\ufe0f\u20e3 Deploy su un server remoto (Ubuntu + Apache) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \ud83d\udda5\ufe0f 1\ufe0f\u20e3 Installazione in LOCALE \ud83d\udccc Struttura del progetto \/my-project \u2502\u2500\u2500 \/backend # Symfony 7.x + API Platform (backend) \u2502 \u2502\u2500\u2500 \/bin \u2502 \u2502\u2500\u2500 \/config \u2502 \u2502\u2500\u2500 \/migrations \u2502 \u2502\u2500\u2500 \/public \u2502 \u2502\u2500\u2500 \/src \u2502 &hellip; <\/p>\n","protected":false},"author":1,"featured_media":709,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[22,21,23,18],"class_list":["post-64","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-howto","tag-api","tag-nextjs","tag-react","tag-symfony"],"_links":{"self":[{"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/posts\/64","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/comments?post=64"}],"version-history":[{"count":3,"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/posts\/64\/revisions"}],"predecessor-version":[{"id":712,"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/posts\/64\/revisions\/712"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/media\/709"}],"wp:attachment":[{"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/media?parent=64"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/categories?post=64"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pasqualepellicani.it\/index.php\/wp-json\/wp\/v2\/tags?post=64"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}