Quick start

Quick Start #

Start new project in empty directory and create .lando.yml and don’t forget to change:

  • project-name change to your project domain e.g. eshop,
  • proxy domains for adminer and mailhog e.g. mailhog.eshop.lndo.site

If you want to use NodeJS, e.g. TypeScript for your frontend, use this:

name: project-name
recipe: lemp
config:
  php: '8.1'
  database: mariadb:10.5
  webroot: www
  xdebug: false
  config:
    vhosts: .deploy/lando/nginx.vhost.conf
proxy:
  adminer:
    - adminer.project-name.lndo.site
  mailhog:
    - mailhog.project-name.lndo.site
services:
  database:
    portforward: 3307
  adminer:
    type: compose
    services:
      image: dehy/adminer:4.7
      command: /bin/s6-svscan /etc/services.d
  mailhog:
    type: mailhog
    hogfrom:
      - appserver
  node:
    type: node:14
    build:
      - yarn install
tooling:
  console:
    service: appserver
    description: Run Symfony console commands
    cmd: php bin/console.php -vvv
  phpstan:
    service: appserver
    description: Run code analysis
    cmd: vendor/bin/phpstan analyse
  phpunit:
    service: appserver
    description: Run phpunit
    cmd: vendor/bin/phpunit
  yarn:
    service: node

If you want to do frontend the old way – with jQuery, use this:

name: project-name
recipe: lemp
config:
  php: '8.1'
  database: mariadb:10.5
  webroot: www
  xdebug: false
  config:
    vhosts: .deploy/lando/nginx.vhost.conf
proxy:
  adminer:
    - adminer.project-name.lndo.site
  mailhog:
    - mailhog.project-name.lndo.site
services:
  database:
    portforward: 3307
  adminer:
    type: compose
    services:
      image: dehy/adminer:4.7
      command: /bin/s6-svscan /etc/services.d
  mailhog:
    type: mailhog
    hogfrom:
      - appserver
tooling:
  console:
    service: appserver
    description: Run Symfony console commands
    cmd: php bin/console.php -vvv
  phpstan:
    service: appserver
    description: Run code analysis
    cmd: vendor/bin/phpstan analyse
  phpunit:
    service: appserver
    description: Run phpunit
    cmd: vendor/bin/phpunit

Lando recipe lemp uses LEMP stack, which is a common infrastructure designed to run PHP applications. This stack uses nginx as a web server. Therefore, you will also need to define nginx configuration file .deploy/lando/nginx.vhost.conf:

server {

    listen 80 default_server;
    listen 443 ssl;

    server_name localhost;

    ssl_certificate           /certs/cert.crt;
    ssl_certificate_key       /certs/cert.key;
    ssl_verify_client         off;

    ssl_session_cache    shared:SSL:1m;
    ssl_session_timeout  5m;

    ssl_ciphers  HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers  on;

    port_in_redirect off;
    client_max_body_size 100M;
    client_header_buffer_size 5120k;
    large_client_header_buffers 16 5120k;

    root "{{LANDO_WEBROOT}}";
    index index.php index.html index.htm;

    location / {
         try_files $uri $uri/ /index.php$is_args$args;
    }

    location ~ \.php$ {
        try_files $uri /index.php =404;
        fastcgi_pass fpm:9000;
        fastcgi_index index.php;
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/letsencrypt/;
        log_not_found off;
    }
}

Download Nette Skeleton #

Now you can create your empty nette project with command:

lando composer create-project nette/web-project my-project

Now move all directories and files from my-project into your project root.

Unfortunately, it is not possible to create new project in your root directory, because the directory is not empty and composer will refuse that.

Configure Project #

To ignore some paths and files from your git repository, you should change the configuration in .gitignore file. You will need to ignore local config, deploy keys (will be described in deployment chapter), vendor directory with all external dependencies, local storage for uploaded files, IDE configuration files, etc.

/.deploy/keys
/config/local.neon
/storage
/vendor

.idea/*
.DS_Store
.phpunit.result.cache

Why you should gitignore vendor directory, but composer.lock file not?

  • Directory vendor contains code, which is not yours. It contains external libraries. This code is maintained by someone else. Therefore, you should not track changes in your repository. What you should track is the version used in your project.
  • On the other hand, composer.lock contains exact version installed in your project. So if you change your dependency, the exact version which you use is written in the lock file. On each install by composer install, the same versions will be user.

In Makefile file in your project root directory, you can create shortcuts to most often used command. To make your project start easier, append this to your Makefile:

start:
	lando rebuild --yes

Rebuild is needed to make sure that your containers are always updated and that mailhog will work as it should.

To make sure that every person who will work on this project will have set same formatting options and encodings, create file .editorconfig in your project root:

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true

[Makefile]
indent_style = tab

[*.{php,css,scss,js,json,neon,latte,xml}]
indent_style = tab
indent_size = 4

[*.sql]
indent_style = space
indent_size = 2

In your local.neon append proxy settings for lando support:

http:
	proxy:
		- 127.0.0.1
		- 172.0.0.0/8

Do not forget to replace COOKIE_SECRET, you can create your own uuid here.

<?php

declare(strict_types=1);

namespace App;

use Nette\Bootstrap\Configurator;
use Nette\Utils\Strings;


final class Bootstrap
{
	private const COOKIE_SECRET = '72039a4b-0450-40c9-bd0d-f66f7be52411';

	public static function configurator(): Configurator
	{
		$configurator = new Configurator;
		$root = dirname(__DIR__);

		$configurator->setTimeZone('Europe/Prague');
		$configurator->setTempDirectory("$root/temp");

		$configurator->createRobotLoader()
			->addDirectory(__DIR__)
			->register();

		$configurator
			->addConfig("$root/config/common.neon")
			->addParameters([
				'wwwDir' => "$root/www",
				'srcDir' => "$root/src",
			]);

		return $configurator;
	}

	public static function boot(): Configurator
	{
		$configurator = self::configurator();
		$root = dirname(__DIR__);

		$configurator->setDebugMode(self::COOKIE_SECRET . '@' . ($_SERVER['REMOTE_ADDR'] ?? php_uname('n')));
//		$configurator->setDebugMode(true);
		$configurator->enableTracy("$root/log");
		$configurator->addConfig("$root/config/local.neon");

		return $configurator;
	}

}

Clear Cache Utility #

Paste into bin/utils/clean-cache.php:

<?php

declare(strict_types = 1);

use Nette\Caching\Cache;
use Nette\Caching\Storage;
use Nette\Utils\FileSystem;

require __DIR__ . '/../../vendor/autoload.php';

FileSystem::delete(__DIR__ . '/../../temp/cache');

$container = App\Bootstrap::boot()->createContainer();
/** @var Storage $storage */
$storage = $container->getByType(Storage::class);
$storage->clean([Cache::ALL => true]);

echo "Cache cleaned successfully\n";

And append to your Makefile:

cache:
	lando php bin/utils/clean-cache.php