<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.3">Jekyll</generator><link href="https://martinvana.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://martinvana.com/" rel="alternate" type="text/html" /><updated>2021-06-30T15:46:49+00:00</updated><id>https://martinvana.com/</id><title type="html">Martin Váňa</title><subtitle>I am a software engineer and a postgraduate student at the University of West Bohemia. I am working as a lead web designer and analytics.
</subtitle><entry><title type="html">4 things you might not have known about Git</title><link href="https://martinvana.com/blog/2018/11/20/4-things-you-might-not-have-known-about-git/" rel="alternate" type="text/html" title="4 things you might not have known about Git" /><published>2018-11-20T08:00:00+00:00</published><updated>2018-11-20T08:00:00+00:00</updated><id>https://martinvana.com/blog/2018/11/20/4-things-you-might-not-have-known-about-git</id><content type="html" xml:base="https://martinvana.com/blog/2018/11/20/4-things-you-might-not-have-known-about-git/">&lt;p&gt;&lt;a href=&quot;https://git-scm.com/&quot;&gt;Git&lt;/a&gt; is a well known &lt;strong&gt;distributed version control system&lt;/strong&gt; which was designed to handle everything from small to very large projects with &lt;strong&gt;speed&lt;/strong&gt; and &lt;strong&gt;efficiency&lt;/strong&gt;. Many developers (including myself) have used it &lt;strong&gt;for years&lt;/strong&gt; not knowing following things.&lt;/p&gt;

&lt;h2 id=&quot;origin-of-the-name&quot;&gt;Origin of the name&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/git/git/blob/b21ebb671bb7dea8d342225f0d66c41f4e54d5ca/README.md&quot;&gt;The official readme&lt;/a&gt; states:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The name “git” was given by Linus Torvalds when he wrote the very first version. He described the tool as “the stupid content tracker” and the name as(depending on your mood):&lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;random three-letter combination that is pronounceable, and not actually used by any common UNIX command. The fact that it is a mispronunciation of “get” may or may not be relevant.&lt;/li&gt;
    &lt;li&gt;stupid. contemptible and despicable. simple. Take your pick from the dictionary of slang.&lt;/li&gt;
    &lt;li&gt;“global information tracker”: you’re in a good mood, and it actually works for you. Angels sing, and a light suddenly fills the room.&lt;/li&gt;
    &lt;li&gt;“goddamn idiotic truckload of sh*t”: when it breaks&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Linus &lt;a href=&quot;https://www.pcworld.idg.com.au/article/129776/after_controversy_torvalds_begins_work_git_/&quot;&gt;once stated&lt;/a&gt;: &lt;em&gt;“I’m an egotistical bastard, and I name all my projects after myself. First ‘Linux’, now ‘git’.”&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;git-was-initially-a-toolkit-for-a-version-control-system&quot;&gt;Git was initially a toolkit for a version control system&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://git-scm.com/book/uz/v2/Git-Internals-Plumbing-and-Porcelain&quot;&gt;Git was initially &lt;strong&gt;a toolkit&lt;/strong&gt;&lt;/a&gt; for a version control system rather than a full user-friendly &lt;abbr title=&quot;Version Control Systems&quot;&gt;VCS&lt;/abbr&gt;. It has &lt;em&gt;plumbing&lt;/em&gt; (low-level commands) and &lt;em&gt;porcelain&lt;/em&gt; (high-level commands). Low-level commands allow you to basically create your own &lt;abbr title=&quot;Version Control Systems&quot;&gt;VCS&lt;/abbr&gt;. Luckily, that is rarely the case since the &lt;em&gt;porcelain&lt;/em&gt; is simply &lt;strong&gt;awesome&lt;/strong&gt;.&lt;/p&gt;

&lt;h2 id=&quot;svn-interoperability&quot;&gt;SVN interoperability&lt;/h2&gt;

&lt;p&gt;Git has &lt;a href=&quot;https://git-scm.com/docs/git-svn&quot;&gt;built-in support for SVN&lt;/a&gt;. It allows a developer to take advantage of Git on projects which use SVN, or it can be used to migrating to Git.&lt;/p&gt;

&lt;h2 id=&quot;lost-data-are-not-really-lost&quot;&gt;Lost data are not really lost&lt;/h2&gt;

&lt;p&gt;Have you ever accidentally deleted a branch or done a hard reset and later found out you shouldn’t have done that? There is a &lt;code class=&quot;highlighter-rouge&quot;&gt;git reflog&lt;/code&gt; which will help you out! It records when the tips of branches and other references were updated in the local repository. For more details see &lt;a href=&quot;https://git-scm.com/docs/git-reflog&quot;&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.com/&quot;&gt;Git&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.com/book/uz/v2/Git-Internals-Plumbing-and-Porcelain&quot;&gt;Git - Plumbing and Porcelain&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/git/git/blob/b21ebb671bb7dea8d342225f0d66c41f4e54d5ca/README.md&quot;&gt;Git - README&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-reflog&quot;&gt;Git - git-reflog Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.pcworld.idg.com.au/article/129776/after_controversy_torvalds_begins_work_git_/&quot;&gt;After controversy, Torvalds begins work on “git”&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-scm.com/docs/git-svn&quot;&gt;Git - git-svn Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://subversion.apache.org/&quot;&gt;Apache Subversion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">Git is a well known distributed version control system which was designed to handle everything from small to very large projects with speed and efficiency. Many developers (including myself) have used it for years not knowing following things.</summary></entry><entry><title type="html">The Fastest and The Safest Web Pages</title><link href="https://martinvana.com/blog/2018/06/29/the-fastest-and-the-safest-web-pages/" rel="alternate" type="text/html" title="The Fastest and The Safest Web Pages" /><published>2018-06-29T07:00:00+00:00</published><updated>2018-06-29T07:00:00+00:00</updated><id>https://martinvana.com/blog/2018/06/29/the-fastest-and-the-safest-web-pages</id><content type="html" xml:base="https://martinvana.com/blog/2018/06/29/the-fastest-and-the-safest-web-pages/">&lt;p&gt;When it comes to the &lt;strong&gt;speed&lt;/strong&gt; and the &lt;strong&gt;safety&lt;/strong&gt; of web pages nothing beats static web pages.
However, they are tedious to write and every change across multiple files hurts.
That is where &lt;strong&gt;static site generator&lt;/strong&gt; comes in handy.&lt;/p&gt;

&lt;h2 id=&quot;what-is-a-static-site-generator&quot;&gt;What is a static site generator?&lt;/h2&gt;

&lt;p&gt;A static site generator transforms page content written in markup language (such as &lt;abbr title=&quot;lightweight markup language&quot;&gt;Markdown&lt;/abbr&gt;) into &lt;abbr title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/abbr&gt; pages.&lt;/p&gt;

&lt;h2 id=&quot;main-advantages&quot;&gt;Main advantages&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Usability — Writing &lt;abbr title=&quot;lightweight markup language&quot;&gt;Markdown&lt;/abbr&gt; instead of &lt;abbr title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/abbr&gt;&lt;/li&gt;
  &lt;li&gt;Flexibility — Page layout is defined at one place&lt;/li&gt;
  &lt;li&gt;Speed — Nothing loads faster than a static &lt;abbr title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/abbr&gt;&lt;/li&gt;
  &lt;li&gt;Safety — No runtime, no place for malicious code&lt;/li&gt;
  &lt;li&gt;Free/cheap hosting&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;where-do-i-get-a-static-site-generator&quot;&gt;Where do I get a static site generator?&lt;/h2&gt;

&lt;p&gt;There is a list of static site generators at &lt;a href=&quot;https://www.staticgen.com/&quot;&gt;StaticGen&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;which-do-i-choose&quot;&gt;Which do I choose?&lt;/h3&gt;

&lt;p&gt;It depends. Personally, I recommend using the one which matches your use case, and/or is written in a programming language you know in case you want to write a plugin.&lt;/p&gt;

&lt;p&gt;I can recommend &lt;a href=&quot;https://jekyllrb.com&quot;&gt;Jekyll&lt;/a&gt; and &lt;a href=&quot;https://gohugo.io&quot;&gt;Hugo&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;use-cases&quot;&gt;Use cases&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;This blog uses Jekyll&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
  &lt;li&gt;Blog&lt;/li&gt;
  &lt;li&gt;Project site&lt;/li&gt;
  &lt;li&gt;Business / Personal sites&lt;/li&gt;
  &lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;hosting&quot;&gt;Hosting&lt;/h2&gt;

&lt;p&gt;To name a few free hosting services:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://pages.github.com/&quot;&gt;GitHub Pages&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.gitlab.com/ee/user/project/pages/&quot;&gt;GitLab Pages&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.netlify.com/&quot;&gt;Netlify&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;what-if-i-need-some-dynamic-content&quot;&gt;What if I need some dynamic content?&lt;/h2&gt;

&lt;p&gt;It is possible with &lt;strong&gt;JAMstack&lt;/strong&gt;. &lt;a href=&quot;https://jamstack.org/&quot;&gt;JAMstack&lt;/a&gt; is a modern web development architecture based on client-side JavaScript, reusable APIs, and prebuilt Markup.&lt;/p&gt;</content><author><name></name></author><summary type="html">When it comes to the speed and the safety of web pages nothing beats static web pages. However, they are tedious to write and every change across multiple files hurts. That is where static site generator comes in handy.</summary></entry><entry><title type="html">Applying Nette Coding Standard with PHP &amp;lt;7.1</title><link href="https://martinvana.com/blog/2017/08/23/applying-nette-coding-standard-with-php-71/" rel="alternate" type="text/html" title="Applying Nette Coding Standard with PHP &lt;7.1" /><published>2017-08-23T07:00:00+00:00</published><updated>2017-08-23T07:00:00+00:00</updated><id>https://martinvana.com/blog/2017/08/23/applying-nette-coding-standard-with-php-71</id><content type="html" xml:base="https://martinvana.com/blog/2017/08/23/applying-nette-coding-standard-with-php-71/">&lt;p&gt;A few days ago, I came across a &lt;a href=&quot;https://www.tomasvotruba.cz/blog/2017/08/14/how-to-apply-nette-coding-standard-in-your-project/&quot;&gt;How to Apply Nette Coding Standard in Your Project&lt;/a&gt; blog post and I &lt;strong&gt;fell in love&lt;/strong&gt;. That was exactly what I was looking for! The only problem is that I &lt;strong&gt;do not&lt;/strong&gt; have &lt;strong&gt;PHP 7.1&lt;/strong&gt; installed (I have got PHP 7.0) and I cannot update (at least not easily without breaking things).&lt;/p&gt;

&lt;h1 id=&quot;solution&quot;&gt;Solution&lt;/h1&gt;

&lt;p&gt;Recently, I was &lt;a href=&quot;//blog/2017/07/28/lamp-with-vagrant/&quot;&gt;fiddling with Vagrant&lt;/a&gt;. Therefore, I used gained knowledge to set up a simple &lt;a href=&quot;https://github.com/vanam/ncs-vagrant&quot;&gt;vagrant project&lt;/a&gt; solving my problem.&lt;/p&gt;

&lt;h2 id=&quot;usage&quot;&gt;Usage&lt;/h2&gt;

&lt;h3 id=&quot;synchronize-project-folder&quot;&gt;Synchronize project folder&lt;/h3&gt;

&lt;p&gt;Add project folder, you want to check, to &lt;code class=&quot;highlighter-rouge&quot;&gt;Vagrantfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;synced_folder&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;path/to/project-to-check&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/vagrant_data/project-to-check&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;blockquote&gt;
  &lt;p&gt;Note: You can add multiple project folders&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;style-check--fix&quot;&gt;Style check &amp;amp; fix&lt;/h3&gt;

&lt;p&gt;Now run Vagrant and connect via &lt;abbr title=&quot;Secure Shell&quot;&gt;SSH&lt;/abbr&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant up
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant ssh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once you are connected via &lt;abbr title=&quot;Secure Shell&quot;&gt;SSH&lt;/abbr&gt; move to &lt;code class=&quot;highlighter-rouge&quot;&gt;/vagrant&lt;/code&gt; folder and run check&amp;amp;fix.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./ecs check /vagrant_data/project-to-check/app/ &lt;span class=&quot;nt&quot;&gt;--config&lt;/span&gt; vendor/nette/coding-standard/coding-standard-php70.neon &lt;span class=&quot;nt&quot;&gt;--fix&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For more details read &lt;a href=&quot;https://github.com/nette/coding-standard&quot;&gt;tool documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;for-whom-is-this&quot;&gt;For whom is this?&lt;/h2&gt;

&lt;p&gt;This solution is for people who for some reason do not have PHP ≥7.1 installed and still want to check&amp;amp;fix their PHP coding style according to &lt;a href=&quot;https://nette.org/en/coding-standard&quot;&gt;Nette Coding Standards&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/vanam/ncs-vagrant&quot;&gt;Source code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.tomasvotruba.cz/blog/2017/08/14/how-to-apply-nette-coding-standard-in-your-project/&quot;&gt;How to Apply Nette Coding Standard in Your Project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">A few days ago, I came across a How to Apply Nette Coding Standard in Your Project blog post and I fell in love. That was exactly what I was looking for! The only problem is that I do not have PHP 7.1 installed (I have got PHP 7.0) and I cannot update (at least not easily without breaking things).</summary></entry><entry><title type="html">A cron job using Vagrant</title><link href="https://martinvana.com/blog/2017/08/01/a-cron-job-using-vagrant/" rel="alternate" type="text/html" title="A cron job using Vagrant" /><published>2017-08-01T08:00:00+00:00</published><updated>2017-08-01T08:00:00+00:00</updated><id>https://martinvana.com/blog/2017/08/01/a-cron-job-using-vagrant</id><content type="html" xml:base="https://martinvana.com/blog/2017/08/01/a-cron-job-using-vagrant/">&lt;p&gt;In &lt;a href=&quot;//blog/2017/07/20/a-cron-basics/&quot;&gt;A cron basics&lt;/a&gt; we learned how to set up a cron job in a local environment. Today I am going to show you how to set it programmatically using Vagrant.&lt;/p&gt;

&lt;h2 id=&quot;provisioning-files&quot;&gt;Provisioning files&lt;/h2&gt;

&lt;h3 id=&quot;a-script-file&quot;&gt;A script file&lt;/h3&gt;

&lt;p&gt;First, we write a script we want to execute. To make it as simple as possible we just write current date to a &lt;code class=&quot;highlighter-rouge&quot;&gt;/vagrant/www/cron.html&lt;/code&gt; file&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# File: vagrant/cron/cron-job.sh&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Write current date to cron.html&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;date&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; /vagrant/www/cron.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;crontab-file&quot;&gt;Crontab file&lt;/h3&gt;

&lt;p&gt;Secondly, we define a crontab file.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Run example cron job
*/1 * * * * bash /vagrant/vagrant/cron/cron-job.sh

# Comment to make sure there is new line at the end of file
# https://askubuntu.com/questions/23009/why-crontab-scripts-are-not-working/23337#23337
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Do you know how often will be this script executed? No? Go check the &lt;a href=&quot;https://crontab.guru/#*/1_*_*_*_*&quot;&gt;Online Crontab Editor&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;installation&quot;&gt;Installation&lt;/h3&gt;

&lt;p&gt;Finally, we install new crontab file.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# File: vagrant/cron/cron.sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Setting up cron ...&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Overwrite crontab configuration&lt;/span&gt;
crontab /vagrant/vagrant/cron/crontab
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And we update master unprivileged script because we do not need a privileged user for that.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# File: vagrant/unprivileged.sh&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Available unprivileged configurations&lt;/span&gt;
bash /vagrant/vagrant/cron/cron.sh
&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;does-it-work&quot;&gt;Does it work?&lt;/h2&gt;

&lt;p&gt;To see if it works visit &lt;code class=&quot;highlighter-rouge&quot;&gt;http://project.v.martinvana.com/cron.html&lt;/code&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;//blog/2017/07/20/a-cron-basics/&quot;&gt;A cron basics&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;//blog/2017/07/28/lamp-with-vagrant/&quot;&gt;LAMP with Vagrant&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/vanam/vagrant-kickstarter/tree/d462755c2889fdb78d158d4e48b7ba44e31417f8&quot;&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">In A cron basics we learned how to set up a cron job in a local environment. Today I am going to show you how to set it programmatically using Vagrant.</summary></entry><entry><title type="html">LAMP with Vagrant</title><link href="https://martinvana.com/blog/2017/07/28/lamp-with-vagrant/" rel="alternate" type="text/html" title="LAMP with Vagrant" /><published>2017-07-28T08:00:00+00:00</published><updated>2017-07-28T08:00:00+00:00</updated><id>https://martinvana.com/blog/2017/07/28/lamp-with-vagrant</id><content type="html" xml:base="https://martinvana.com/blog/2017/07/28/lamp-with-vagrant/">&lt;p&gt;In &lt;a href=&quot;//blog/2017/07/26/setting-up-vagrant/&quot;&gt;Setting up Vagrant&lt;/a&gt; I showed you &lt;em&gt;Hello world&lt;/em&gt; project with Vagrant. Now I am going to show you how to set up a &lt;abbr title=&quot;Linux, Apache, MySQL, and PHP&quot;&gt;LAMP&lt;/abbr&gt; environment.&lt;/p&gt;

&lt;h2 id=&quot;provisioning&quot;&gt;Provisioning&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.vagrantup.com/docs/provisioning/&quot;&gt;Provisioning&lt;/a&gt; is a way to install and configure software inside a virtual machine. Simplest usable way of doing so is using a &lt;strong&gt;shell script&lt;/strong&gt;. That is what I am going to do.&lt;/p&gt;

&lt;p&gt;However, that is not the only option. You can use more advanced automatic &lt;strong&gt;configuration and orchestration tools&lt;/strong&gt; such as &lt;a href=&quot;https://www.vagrantup.com/docs/provisioning/&quot;&gt;Ansible&lt;/a&gt; or &lt;a href=&quot;https://puppet.com/&quot;&gt;Puppet&lt;/a&gt; if you are proficient with them.&lt;/p&gt;

&lt;h3 id=&quot;configuring-vagrant&quot;&gt;Configuring Vagrant&lt;/h3&gt;

&lt;p&gt;First, we take a look at &lt;code class=&quot;highlighter-rouge&quot;&gt;Vagrantfile&lt;/code&gt;. The minimum configuration contains box definition.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ubuntu/xenial64&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With a configuration like this, our only way of accessing VM is using SSH. Therefore, we create a &lt;a href=&quot;https://en.wikipedia.org/wiki/Private_network&quot;&gt;private network&lt;/a&gt;, which allows host-only access to the machine using a &lt;strong&gt;specific IP&lt;/strong&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ubuntu/xenial64&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;network&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;private_network&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;ip: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;192.168.33.10&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we could manually edit &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/hosts&lt;/code&gt; and map &lt;code class=&quot;highlighter-rouge&quot;&gt;192.168.33.10&lt;/code&gt; address to a hostname &lt;code class=&quot;highlighter-rouge&quot;&gt;project.v.martinvana.com&lt;/code&gt;. But life is too short to do things manually.&lt;/p&gt;

&lt;p&gt;Therefore we install a &lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant-hostmanager&lt;/code&gt; plugin.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant plugin &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;vagrant-hostmanager
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can let &lt;abbr title=&quot;Dynamic Host Configuration Protocol&quot;&gt;DHCP&lt;/abbr&gt; select an IP address and we set up a custom IP resolver.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ubuntu/xenial64&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;network&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;private_network&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;type: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;dhcp&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;hostname&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;project.v.martinvana.com&quot;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;has_plugin?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'vagrant-hostmanager'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;hostmanager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;enabled&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;hostmanager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;manage_host&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
		&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;hostmanager&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ip_resolver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;proc&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
			&lt;span class=&quot;sb&quot;&gt;`vagrant ssh -c &quot;hostname -I&quot;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
		&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since we are using a &lt;a href=&quot;https://www.virtualbox.org/&quot;&gt;Virtualbox&lt;/a&gt; it is reasonable to &lt;a href=&quot;https://www.vagrantup.com/docs/virtualbox/configuration.html&quot;&gt;limit resources&lt;/a&gt; it can consume. Allow using 1GB &lt;abbr title=&quot;Random Access Memory&quot;&gt;RAM&lt;/abbr&gt; and 1CPU which can use up to 50% of a single host &lt;abbr title=&quot;Central Processing Unit&quot;&gt;CPU&lt;/abbr&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;provider&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;virtualbox&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;customize&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;modifyvm&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;--cpuexecutioncap&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;50&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;memory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;cpus&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, we got to the provisioning part of a configuration. Folder &lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant&lt;/code&gt; in our project is going to contain all provisioning files.&lt;/p&gt;

&lt;p&gt;We could define an arbitrary number of provisioning scripts. Therefore I set up three:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;install.sh&lt;/code&gt;      – Install and configure software&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;load.sh&lt;/code&gt;         – Actions to do on &lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant up&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;unprivileged.sh&lt;/code&gt; – Actions to do as a unprivileged user&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;provision&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:shell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;vagrant/install.sh&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;provision&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:shell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;vagrant/load.sh&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;run: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;always&quot;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;provision&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:shell&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:path&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;vagrant/unprivileged.sh&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;privileged: &lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Content of &lt;code class=&quot;highlighter-rouge&quot;&gt;install.sh&lt;/code&gt; is following:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Setting Prague timezone ...&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-sf&lt;/span&gt; /usr/share/zoneinfo/Europe/Prague /etc/localtime

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Add repositories ...&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Re-synchronize the package index files from their sources ...&quot;&lt;/span&gt;
apt-get update

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Install the newest versions of all packages currently installed on the system ...&quot;&lt;/span&gt;
apt-get upgrade &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Available configurations&lt;/span&gt;
bash /vagrant/vagrant/apache/apache.sh
bash /vagrant/vagrant/mysql/mysql.sh
bash /vagrant/vagrant/php/php.sh
bash /vagrant/vagrant/utils/utils.sh

&lt;span class=&quot;c&quot;&gt;# Cleanup&lt;/span&gt;
apt-get &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; autoremove
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, I am not creating one huge install script but rather several small ones. &lt;code class=&quot;highlighter-rouge&quot;&gt;load.sh&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;unprivileged.sh&lt;/code&gt; files are empty for now.&lt;/p&gt;

&lt;h3 id=&quot;apache&quot;&gt;Apache&lt;/h3&gt;

&lt;p&gt;To set up &lt;a href=&quot;https://httpd.apache.org/&quot;&gt;Apache&lt;/a&gt; we need to configure a &lt;a href=&quot;http://httpd.apache.org/docs/2.4/vhosts/&quot;&gt;virtual host&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-apache highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# File: vagrant/apache/sites-available/project.conf&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; *:80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;  &lt;span class=&quot;nc&quot;&gt;ServerAdmin&lt;/span&gt; webmaster@localhost
  &lt;span class=&quot;nc&quot;&gt;DocumentRoot&lt;/span&gt; /var/www/www

  &lt;span class=&quot;nc&quot;&gt;LogLevel&lt;/span&gt; warn

  &lt;span class=&quot;nc&quot;&gt;ErrorLog&lt;/span&gt; ${APACHE_LOG_DIR}/error.log
  &lt;span class=&quot;nc&quot;&gt;CustomLog&lt;/span&gt; ${APACHE_LOG_DIR}/access.log combined
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;VirtualHost&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-apache highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# File: vagrant/apache/conf-available/project.conf&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt; /var/www/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;  &lt;span class=&quot;nc&quot;&gt;Options&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;FollowSymLinks&lt;/span&gt;
  &lt;span class=&quot;nc&quot;&gt;AllowOverride&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;All&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;&amp;lt;/&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;Directory&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First, we install Apache, then we create a symbolic link to shared folder &lt;code class=&quot;highlighter-rouge&quot;&gt;/vagrant&lt;/code&gt;, and finally, we configure a virtual host.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# File: vagrant/apache/apache.sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Installing apache ...&quot;&lt;/span&gt;
apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; apache2

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Setup /var/www to point to /vagrant ...&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/www&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
	&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-rf&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/www&quot;&lt;/span&gt;
	&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-fs&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/vagrant&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/www&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Apache / Virtual Host Setup&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Install Apache configurations ...&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-rf&lt;/span&gt; /etc/apache2/sites-enabled/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/apache2/sites-available&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
	if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/apache2/sites-available/project.conf&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
		&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/vagrant/vagrant/apache/sites-available/project.conf&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/apache2/sites-available/project.conf&quot;&lt;/span&gt;
	&lt;span class=&quot;k&quot;&gt;fi
	&lt;/span&gt;a2ensite &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt; project.conf
&lt;span class=&quot;k&quot;&gt;fi

if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-L&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/apache2/conf-available/project.conf&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;then
	&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;rm&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/apache2/conf-available/project.conf&quot;&lt;/span&gt;
	&lt;span class=&quot;nb&quot;&gt;ln&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/vagrant/vagrant/apache/conf-available/project.conf&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/etc/apache2/conf-available/project.conf&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;fi
&lt;/span&gt;a2enconf &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt; project.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To verify that everything went as expected we create a HTML file.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; www/index.html
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can view the page at &lt;code class=&quot;highlighter-rouge&quot;&gt;http://project.v.martinvana.com/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The last thing we do is to make sure we restart Apache on &lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant up&lt;/code&gt; in order to server configuration file to take effect.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# File: vagrant/load.sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Restarting Apache ...&quot;&lt;/span&gt;
service apache2 restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;php&quot;&gt;PHP&lt;/h3&gt;

&lt;p&gt;To install PHP we first have to add &lt;abbr title=&quot;Personal Package Archives&quot;&gt;PPA&lt;/abbr&gt; with PHP 7.1.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# File: vagrant/install.sh&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Add repositories ...&quot;&lt;/span&gt;
add-apt-repository ppa:ondrej/php

&lt;span class=&quot;c&quot;&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can install PHP, its extensions, and &lt;a href=&quot;https://getcomposer.org/&quot;&gt;Composer&lt;/a&gt; in a similar fashion as in the case of Apache.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# File: vagrant/php/php.sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Installing php ...&quot;&lt;/span&gt;
apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        php7.1 &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        php7.1-xdebug &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        php7.1-zip &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        php7.1-mysql &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        libapache2-mod-php7.1

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Installing composer ...&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;EXPECTED_SIGNATURE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;wget &lt;span class=&quot;nt&quot;&gt;-q&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-O&lt;/span&gt; - https://composer.github.io/installer.sig&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;
php &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;copy('https://getcomposer.org/installer', 'composer-setup.php');&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;ACTUAL_SIGNATURE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;php &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;echo hash_file('SHA384', 'composer-setup.php');&quot;&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$EXPECTED_SIGNATURE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$ACTUAL_SIGNATURE&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;then&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&amp;amp;2 &lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'ERROR: Invalid installer signature'&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else
  &lt;/span&gt;php composer-setup.php &lt;span class=&quot;nt&quot;&gt;--quiet&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--install-dir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/usr/local/bin &lt;span class=&quot;nt&quot;&gt;--filename&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;composer
&lt;span class=&quot;k&quot;&gt;fi

&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;rm &lt;/span&gt;composer-setup.php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To verify that everything went as expected we create a PHP file.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;$'&amp;lt;?php&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;phpinfo();'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; www/info.php
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;At &lt;code class=&quot;highlighter-rouge&quot;&gt;http://project.v.martinvana.com/info.php&lt;/code&gt; we can view the PHP information page.&lt;/p&gt;

&lt;h3 id=&quot;mysql&quot;&gt;MySQL&lt;/h3&gt;

&lt;p&gt;The only thing we have to take care of during MySQL installation is setting the root password.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# File: vagrant/mysql/mysql.sh&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Installing mysql ...&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Username: root&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Password: root&lt;/span&gt;
debconf-set-selections &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'mysql-server mysql-server/root_password password root'&lt;/span&gt;
debconf-set-selections &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'mysql-server mysql-server/root_password_again password root'&lt;/span&gt;

apt-get &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-y&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
        mysql-server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To verify MySQL (and also Composer) installation I created a simple project with &lt;a href=&quot;https://github.com/dg/adminer-custom&quot;&gt;Adminer&lt;/a&gt; database management tool.&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;vanam/vagrant-kickstarter&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;project&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;require&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;php&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;gt;=7.1.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ext-mysql&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ext-zip&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;

        &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;dg/adminer-custom&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^1.9&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now you should be able to log in as &lt;em&gt;root&lt;/em&gt; user.&lt;/p&gt;

&lt;p&gt;With composer project in place, we also want to automate dependency updating. For this, we use the &lt;code class=&quot;highlighter-rouge&quot;&gt;unprivileged.sh&lt;/code&gt; file.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Moving to '/vagrant' directory ...&quot;&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cd&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/vagrant&quot;&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;----- Provision: Installing composer dependencies ...&quot;&lt;/span&gt;
composer &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--no-interaction&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;pitfalls&quot;&gt;Pitfalls&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;You need a stable internet connection during provisioning.&lt;/li&gt;
  &lt;li&gt;Until you call &lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant up --provision&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant provision&lt;/code&gt; changes will not be applied.&lt;/li&gt;
  &lt;li&gt;Provisioning files should be idempotent (have the same effect if run multiple times).&lt;/li&gt;
  &lt;li&gt;Every configuration change must be written down in a script otherwise it will be lost.&lt;/li&gt;
  &lt;li&gt;Installation scripts might fail. For advanced workflows use configuration and orchestration tools such as &lt;a href=&quot;https://www.vagrantup.com/docs/provisioning/&quot;&gt;Ansible&lt;/a&gt; or &lt;a href=&quot;https://puppet.com/&quot;&gt;Puppet&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As you can see, configuring a first (&lt;abbr title=&quot;Linux, Apache, MySQL, and PHP&quot;&gt;LAMP&lt;/abbr&gt;) virtual machine is not hard if you have previous knowledge of GNU/Linux systems. There is minimum Vagrant configuration and the rest is just a system configuration.&lt;/p&gt;

&lt;p&gt;Full source code is available on &lt;a href=&quot;https://github.com/vanam/vagrant-kickstarter/tree/7c5c3e1fbff4c6f15b272c3fbc2961841078b652&quot;&gt;Github&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.vagrantup.com/docs/index.html&quot;&gt;Vagrant documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;//blog/2017/07/26/setting-up-vagrant/&quot;&gt;Setting up Vagrant&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=crvJ2C7Hr_g&quot;&gt;YouTube – Stop what you’re doing, and learn Vagrant today - An introduction&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">In Setting up Vagrant I showed you Hello world project with Vagrant. Now I am going to show you how to set up a LAMP environment.</summary></entry><entry><title type="html">Setting up Vagrant</title><link href="https://martinvana.com/blog/2017/07/26/setting-up-vagrant/" rel="alternate" type="text/html" title="Setting up Vagrant" /><published>2017-07-26T17:00:00+00:00</published><updated>2017-07-26T17:00:00+00:00</updated><id>https://martinvana.com/blog/2017/07/26/setting-up-vagrant</id><content type="html" xml:base="https://martinvana.com/blog/2017/07/26/setting-up-vagrant/">&lt;p&gt;Did your colleague ever tell you &lt;em&gt;I am unable to run the app on my computer because …&lt;/em&gt; or &lt;em&gt;It works on my machine&lt;/em&gt;? From now on, this is never going to be a problem again.&lt;/p&gt;

&lt;h2 id=&quot;what-is-vagrant&quot;&gt;What is Vagrant?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.vagrantup.com/&quot;&gt;Vagrant&lt;/a&gt; is a tool for building and &lt;strong&gt;managing virtual machine environments&lt;/strong&gt;. Vagrant &lt;strong&gt;is not&lt;/strong&gt; a virtualization tool. Therefore, you have to get some.&lt;/p&gt;

&lt;p&gt;Vagrant comes with &lt;strong&gt;out-of-the-box&lt;/strong&gt; support for &lt;a href=&quot;https://www.virtualbox.org/&quot;&gt;Virtualbox&lt;/a&gt; which is the most popular, free, and cross-platform. However, it is not the only option. Vagrant also works with &lt;a href=&quot;https://www.vmware.com/&quot;&gt;VMware&lt;/a&gt;, &lt;a href=&quot;http://www.microsoft.com/hyper-v&quot;&gt;Hyper-V&lt;/a&gt;, and &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;advantages&quot;&gt;Advantages&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Reproducible and portable environment&lt;/li&gt;
  &lt;li&gt;Automation&lt;/li&gt;
  &lt;li&gt;Same environment as production server&lt;/li&gt;
  &lt;li&gt;All configuration files are plain text files (&lt;abbr title=&quot;Version Control System&quot;&gt;VCS&lt;/abbr&gt; love it!)&lt;/li&gt;
  &lt;li&gt;Developer works in his favourite OS, the app runs in a virtual environment&lt;/li&gt;
  &lt;li&gt;Fast start for a new team member&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;installation&quot;&gt;Installation&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;It is not recommended to install Vagrant using package managers. Use direct download instead.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Install &lt;a href=&quot;https://www.virtualbox.org/&quot;&gt;Virtualbox&lt;/a&gt; (or else).&lt;/p&gt;

&lt;p&gt;Install Vagrant using a &lt;a href=&quot;https://www.vagrantup.com/downloads.html&quot;&gt;binary package&lt;/a&gt;. Debian, Windows, Centos, and Mac OS X systems are supported.&lt;/p&gt;

&lt;h2 id=&quot;getting-boxes&quot;&gt;Getting boxes&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;box&lt;/strong&gt; is an image of a virtual machine. You can also create your own box if you desire to do so. However, for most cases, it is a huge speedup for you and your team to utilise &lt;a href=&quot;https://app.vagrantup.com/boxes/search&quot;&gt;already made boxes&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;adding-a-box&quot;&gt;Adding a box&lt;/h3&gt;

&lt;blockquote&gt;
  &lt;p&gt;Naming convention of boxes is following: &amp;lt;username&amp;gt;/&amp;lt;box-name&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let’s say we have chosen the &lt;code class=&quot;highlighter-rouge&quot;&gt;ubuntu/xenial64&lt;/code&gt; box. We could use the box right a way but it is useful to add the box to Vagrant so that multiple Vagrant environments can reuse it (It will take a while to download the box).&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant box add ubuntu/xenial64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we can verify that the box was added.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant box list
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;initialise-a-project-with-vagrant&quot;&gt;Initialise a project with Vagrant&lt;/h2&gt;

&lt;p&gt;First, move to the root of your project. Then execute following:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant init ubuntu/xenial64
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will create a &lt;code class=&quot;highlighter-rouge&quot;&gt;Vagrantfile&lt;/code&gt; with content:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;Vagrant&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;vm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;box&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;ubuntu/xenial64&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Surprising but that’s all.&lt;/p&gt;

&lt;h2 id=&quot;running-a-vm-and-accessing-it&quot;&gt;Running a VM and accessing it&lt;/h2&gt;

&lt;p&gt;Now we are ready to boot the Vagrant environment.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant up
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There is no UI to access the VM. Therefore, we use the good old SSH.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant ssh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;how-do-i-transfer-files-to-vm&quot;&gt;How do I transfer files to VM?&lt;/h3&gt;

&lt;p&gt;Everything in your project folder is automatically synchronised with VM by Vagrant. It appears in &lt;code class=&quot;highlighter-rouge&quot;&gt;/vagrant/&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Let’s try it.&lt;/p&gt;

&lt;p&gt;1) Create a new file in your project folder (not in VM)&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hello world!&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; hello.txt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;2) Then go to VM.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant ssh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;3) List files in &lt;code class=&quot;highlighter-rouge&quot;&gt;/vagrant/&lt;/code&gt; directory.&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;ubuntu@ubuntu-xenial:~&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-la&lt;/span&gt; /vagrant/
total 68
drwxrwxr-x  1 ubuntu ubuntu  4096 Jul 26 18:26 &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
drwxr-xr-x 24 root   root    4096 Jul 26 18:08 ..
drwxrwxr-x  1 ubuntu ubuntu  4096 Jul 26 18:06 .vagrant
&lt;span class=&quot;nt&quot;&gt;-rw-rw-r--&lt;/span&gt;  1 ubuntu ubuntu  3022 Jul 26 17:58 Vagrantfile
&lt;span class=&quot;nt&quot;&gt;-rw-rw-r--&lt;/span&gt;  1 ubuntu ubuntu    13 Jul 26 18:26 hello.txt
&lt;span class=&quot;nt&quot;&gt;-rw-------&lt;/span&gt;  1 ubuntu ubuntu 46138 Jul 26 18:08 ubuntu-xenial-16.04-cloudimg-console.log

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;update-your-box&quot;&gt;Update your box&lt;/h2&gt;

&lt;p&gt;The following command will download the new version for your box.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant box update
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that updating the box will not update an already-running Vagrant machine. To reflect the changes in the box, you will have to destroy and bring back up the Vagrant machine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you want just to check for updates:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant box outdated
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Since updating installs new boxes (and leaves the old ones) it is a good practice to remove old boxes from time to time.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant box prune
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;finishing-the-work&quot;&gt;Finishing the work&lt;/h2&gt;

&lt;p&gt;We can either &lt;a href=&quot;https://www.vagrantup.com/intro/getting-started/teardown.html&quot;&gt;shut the VM down, suspend or destroy&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;shut-down&quot;&gt;Shut down&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant halt
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Halting the virtual machine &lt;strong&gt;shuts down&lt;/strong&gt; the guest operating system and &lt;strong&gt;powers down&lt;/strong&gt; the guest machine. You can use &lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant up&lt;/code&gt; when you are ready to boot it again.&lt;/p&gt;

&lt;h3 id=&quot;suspend&quot;&gt;Suspend&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant &lt;span class=&quot;nb&quot;&gt;suspend&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Suspending &lt;strong&gt;saves the current running state&lt;/strong&gt; of the machine and &lt;strong&gt;stops it&lt;/strong&gt;. When you are ready to begin working again, just &lt;code class=&quot;highlighter-rouge&quot;&gt;run vagrant up&lt;/code&gt;, and it will be resumed from where you left off.&lt;/p&gt;

&lt;h3 id=&quot;destroy&quot;&gt;Destroy&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;vagrant destroy
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Destroying the virtual machine &lt;strong&gt;removes all traces&lt;/strong&gt; of the guest machine from your system. It’ll stop the guest machine, power it down, and remove all of the guest hard disks.&lt;/p&gt;

&lt;h2 id=&quot;cli-overview&quot;&gt;CLI overview&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant box add &amp;lt;username&amp;gt;/&amp;lt;box-name&amp;gt;&lt;/code&gt; – Add a box&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant box list&lt;/code&gt; – List all the boxes that are installed&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant box update&lt;/code&gt; – Update the box for the current environment if there are updates available&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant box outdated&lt;/code&gt; – Check if the box you are using in your current environment is outdated.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant box prune&lt;/code&gt; – Remove old versions of installed boxes&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant up&lt;/code&gt; – Create and configure guest machine using your &lt;code class=&quot;highlighter-rouge&quot;&gt;Vagrantfile&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant halt&lt;/code&gt; – Shut down the running machine&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant suspend&lt;/code&gt; – Suspend the guest machine&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;vagrant destroy&lt;/code&gt; – Stop the running machine and destroy all resources that were created during the machine creation process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Setting up a development environment with the virtual machine is a piece of cake with Vagrant. Next time I am going to show you how to set up a &lt;a href=&quot;//blog/2017/07/28/lamp-with-vagrant/&quot;&gt;&lt;abbr title=&quot;Linux, Apache, MySQL, and PHP&quot;&gt;LAMP&lt;/abbr&gt; environment&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.vagrantup.com/docs/index.html&quot;&gt;Vagrant documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://app.vagrantup.com/boxes/search&quot;&gt;Discover Vagrant Boxes&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.zdrojak.cz/clanky/uvod-do-vagrantu/&quot; hreflang=&quot;cs&quot; lang=&quot;cs&quot;&gt;Úvod do Vagrantu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content><author><name></name></author><summary type="html">Did your colleague ever tell you I am unable to run the app on my computer because … or It works on my machine? From now on, this is never going to be a problem again.</summary></entry><entry><title type="html">A cron basics</title><link href="https://martinvana.com/blog/2017/07/20/a-cron-basics/" rel="alternate" type="text/html" title="A cron basics" /><published>2017-07-20T17:00:00+00:00</published><updated>2017-07-20T17:00:00+00:00</updated><id>https://martinvana.com/blog/2017/07/20/a-cron-basics</id><content type="html" xml:base="https://martinvana.com/blog/2017/07/20/a-cron-basics/">&lt;p&gt;&lt;em&gt;What is a cron?&lt;/em&gt; and &lt;em&gt;How can we use it in web development?&lt;/em&gt; are the most common questions people ask. I am going to answer these questions and discuss issues you might encounter.&lt;/p&gt;

&lt;h2 id=&quot;glossary&quot;&gt;Glossary&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;A &lt;strong&gt;cron&lt;/strong&gt; is a programme which executes programmes according to schedule. It is a time-based job scheduler.&lt;/li&gt;
  &lt;li&gt;A &lt;strong&gt;cron task&lt;/strong&gt; is a programme being executed by cron.&lt;/li&gt;
  &lt;li&gt;A &lt;strong&gt;crontab&lt;/strong&gt; is a file which contains the schedule of cron tasks to be run and at specified times.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;setting-up-a-cron&quot;&gt;Setting up a cron&lt;/h2&gt;

&lt;h3 id=&quot;crontab-commands&quot;&gt;Crontab commands&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;crontab -e&lt;/code&gt; – Edit crontab file, or create one if it doesn’t already exist.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;crontab -l&lt;/code&gt; – Crontab list of cron jobs, display crontab file contents.&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;crontab -r&lt;/code&gt; – Remove your crontab file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;crontab-syntax&quot;&gt;Crontab syntax&lt;/h3&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;*     *     *   *    *        command to be executed
-     -     -   -    -
|     |     |   |    |
|     |     |   |    +----- day of week (0 - 6) (Sunday=0)
|     |     |   +------- month (1 - 12)
|     |     +--------- day of month (1 - 31)
|     +----------- hour (0 - 23)
+------------- min (0 - 59)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Even though the syntax is simple it is much better to use &lt;a href=&quot;https://crontab.guru/&quot;&gt;Online Crontab Expression Editor&lt;/a&gt;, especially for beginners.&lt;/p&gt;

&lt;h3 id=&quot;write-a-script&quot;&gt;Write a script&lt;/h3&gt;

&lt;p&gt;It can be basically anything executable on a given system (Bash, Python, PHP, Ruby, C , etc.). It should behave like a normal programme – return zero on success and return non-zero value otherwise.&lt;/p&gt;

&lt;h2 id=&quot;use-case&quot;&gt;Use case&lt;/h2&gt;

&lt;p&gt;Let’s say we are building a simple mailing service [&lt;sup id=&quot;fnref:1&quot;&gt;&lt;a href=&quot;#fn:1&quot; class=&quot;footnote&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;]. A task is to send emails to lots of people (~1000) at once eg. newsletter, special offer.&lt;/p&gt;

&lt;h3 id=&quot;an-obvious-solution---loop&quot;&gt;An obvious solution - loop&lt;/h3&gt;

&lt;p&gt;An obvious solution is to loop through all email addresses and send all emails on the push of the button.&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$emails&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$recipient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;sendMail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$recipient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$subject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$content&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;However, this solution has a flaw – too many emails are being sent during a short period of time. Mail servers do not like that, especially, if you are using the basic ones build in the programming language. It also takes a very long time.&lt;/p&gt;

&lt;h3 id=&quot;cron-solution&quot;&gt;Cron solution&lt;/h3&gt;

&lt;p&gt;We can create a simple queue of emails using a database:&lt;/p&gt;

&lt;div class=&quot;language-sql highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;TABLE&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;`email`&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;`id`&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AUTO_INCREMENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;`sender`&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;COLLATE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utf8_unicode_ci&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;`recipient`&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;varchar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;255&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;COLLATE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utf8_unicode_ci&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;`subject`&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;longtext&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;COLLATE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utf8_unicode_ci&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;`content`&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;longtext&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;COLLATE&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;utf8_unicode_ci&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;`created`&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;datetime&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;NULL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;`id`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ENGINE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InnoDB&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CHARSET&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;utf8&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;COLLATE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;utf8_unicode_ci&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Such queue contains mails which are to be sent. Once they are sent, we delete them. Sending script might look like this using &lt;em&gt;Nette&lt;/em&gt; and &lt;em&gt;Symfony Console&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-php highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EmailModule\Console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Doctrine\ORM\ORMInvalidArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EmailModule\Entity\Email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EmailModule\Facade\EmailFacade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Nette\InvalidStateException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Nette\Mail\Message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Nette\Mail\SendmailMailer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Console\Command\Command&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Console\Input\InputInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Symfony\Component\Console\Output\OutputInterface&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;sd&quot;&gt;/**
 * Class EmailCommand sends at most 50 oldest emails from email queue.
 *
 * @package EmailModule\Console
 */&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EmailCommand&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Command&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;/**
     * Command configuration.
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'app:email'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setDescription&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Sends enqueued emails'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;sd&quot;&gt;/**
     * Command execution routine.
     *
     * @param InputInterface $input
     * @param OutputInterface $output
     * @return int return status
     */&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;protected&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;InputInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;OutputInterface&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$output&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;/** @var EmailFacade $emailFacade */&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$emailFacade&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getHelper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'container'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getByType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'EmailModule\Facade\EmailFacade'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$emails&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$emailFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getEmailsToSend&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$sentCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$responseStatus&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// Try to send all emails&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$emails&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;sd&quot;&gt;/** @var Email $email */&lt;/span&gt;

            &lt;span class=&quot;nv&quot;&gt;$mail&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$mail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setFrom&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSender&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$mail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;addTo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getRecipient&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$mail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setSubject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getSubject&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
            &lt;span class=&quot;nv&quot;&gt;$mail&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setHtmlBody&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$email&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getContent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;

            &lt;span class=&quot;nv&quot;&gt;$mailer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SendmailMailer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$mailer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$mail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$sentCount&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$emailFacade&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;dequeueEmail&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;InvalidStateException&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;writeLn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'&amp;lt;error&amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/error&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$responseStatus&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ORMInvalidArgumentException&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;writeLn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'&amp;lt;error&amp;gt;'&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getMessage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'&amp;lt;/error&amp;gt;'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;nv&quot;&gt;$responseStatus&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;nv&quot;&gt;$output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;writeLn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;nv&quot;&gt;$output&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;writeLn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$sentCount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;  &lt;span class=&quot;s2&quot;&gt;&quot;/&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$emails&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;' emails sent.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;$responseStatus&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It loops through emails and tries to send them. Now we add a cron task. We want to execute the task with some reasonable period. For example, every 15 minutes send up to 50 emails, that means at most 200 emails per hour (Feel free to modify these numbers to suit your use case). Crontab entry looks like this:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;*/15 * * * * /home/www/mail_service/app/console app:email
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;pitfalls&quot;&gt;Pitfalls&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Cron task might fail.&lt;/li&gt;
  &lt;li&gt;Crontab entry might not be set (programmer forgot).&lt;/li&gt;
  &lt;li&gt;Crontab entry might be set incorrectly (typing error)&lt;/li&gt;
  &lt;li&gt;Crontab &lt;a href=&quot;https://askubuntu.com/a/23337&quot;&gt;must end with empty line&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;As you can see, setting up a cron task is simple. First, you write a programme in your favourite language, then you figure out when it should be executed and then you set the cron task up.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;sources&quot;&gt;Sources&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.adminschoice.com/crontab-quick-reference&quot;&gt;Crontab – Quick Reference&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://crontab.guru/&quot;&gt;Online Crontab Expression Editor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;footnotes&quot;&gt;Footnotes&lt;/h2&gt;

&lt;div class=&quot;footnotes&quot;&gt;
  &lt;ol&gt;
    &lt;li id=&quot;fn:1&quot;&gt;
      &lt;p&gt;Actually, it is not a very good idea to create a mail sending service like this. To know why read &lt;a href=&quot;https://blog.engineyard.com/2011/5-subtle-ways-youre-using-mysql-as-a-queue-and-why-itll-bite-you&quot;&gt;5 subtle ways you’re using MySQL as a queue, and why it’ll bite you&lt;/a&gt;. It is much better to use message queue like &lt;a href=&quot;https://www.rabbitmq.com/&quot;&gt;RabbitMQ&lt;/a&gt;; &lt;a href=&quot;#fnref:1&quot; class=&quot;reversefootnote&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
    &lt;/li&gt;
  &lt;/ol&gt;
&lt;/div&gt;</content><author><name></name></author><summary type="html">What is a cron? and How can we use it in web development? are the most common questions people ask. I am going to answer these questions and discuss issues you might encounter.</summary></entry></feed>