Development Environment with Puphpet

in programming •  7 years ago  (edited)

Development Environment with Puphpet

General

I've been using PHP and the LAMP stack as my main environment since 2009.
At the beginning of every project I had same issues related to a VM preparation.

I found several tools on the market which I tested: Vagrant, Chef, Ansible, Puppet - these all are great and help prepare the development environment automatization.

Today, I want to show a helpful tool (esspecialy from the PHP developer point of view): Puphpet
Puphpet is a configurator for Vagrant and Puppet. It prepares a package with all necessary files to run a new virtual machine with all required components by a PHP application.

Puphpet website preview

In short, Puphpet helps to prepare a local development environment without detailed knowledge about Vagrant and Puppet.

Configuration

The following example shows how to run a PHP application based on the Symfony framework.
The app uses LAMP.

Requirements

You need install Vagrant and Virtualbox to finish that example.

Puphpet Creator

General options

Go to the https://puphpet.com/ website and click the green button.

Get started

On the first step, I chose the Virtualbox provider (you can use VmWare solutions as well) and the Ubuntu Xenial 16.04 LTS x64 operating system.

Provider and OS

Now is the time to set machines. I need an only one machine in the example, but that configurator gives us the possibility to specify as many as we need.
To create more advanced configuration we can add more machines. The case would look like below:

  1. I need an e-commerce system
  2. I need a PIM solution
  3. In the configurator, I can create to separated machines to test integrations between those etc.

Have a look at the following picture:

Machines setup

The first and the second input specify identification. It doesn't really matter now, you can fill as you like. Ip Address input specifies an address which we can use by ssh or http to connect the new VM.
In this form are also two values responsible for the memory amount (assigned to the VM) and a number of CPU's assigned to the machine (no worries you can change it later).

A crucial step in the configuration process is setting-up shared folders.
I want to share the /var/www directory between the host and VM.
Files used by the application I will put into the ../www directory. Also, I'd like to share /vagrant folder with my local machine. The directory will contain all data from the puphpet project directory.
At the end I will see php application files in /var/www and puphpet application files in the /vagrant location.

To share files between my local system (in my case it's MacOs) and the Virtual Machine environment (Ubuntu) I used shared folders option, like below.

www directory

vagrant directory

Packages

What is amazing, Puphpet has a packages configurator.
Let's say that we need several packages installed on our VM, you can update that list also after we finish the configurator.
To run my app I need following packages

  • wkhtmltopdf - my app would use it to generate pdf documents based on website views
  • htop, vim
  • zip

Note that you don't have to specify any php extensions here, there is a step later which does it.

packages setup

Users and Groups

The netx step precise groups and users created in the VM.
I need an only one user named: testapp. See the picture below to find how to make it.

Users and Groups

Cron jobs

I missed steps Locale, Firewall and Resolv in that usage showcase (left default values) adn went directly to the Cron Jobs step.

The cron job configurator defines a scheduler for scripts available in the VM.
I know that /var/www directory will be shared with my ../www folder, therefore I can specify a script run automatically every second hour.

Cron job setup

Apache Installation

Now I want to configure the apache instance (look that you can choose Nginx if you prefer).

For the example needs I add the only one host, let's say that I want to run my application using the http://testapp.dev address and I put my public app file into the /var/www/testapp/web directory.

Apache installation

And basically, that's it - it will create all necessary file to tun the host. What is nice, vagrant takes care of the /etc/hosts/ file update.

PHP Configuration

Here we're able to specify the php version and as I've mentioned before - php extensions.
I added few modules required by my app.
Find all available php modules here: https://launchpad.net/~ondrej/+archive/ubuntu/php/

Here I also specified php-fpm settings, actually I used the default values but here is the right place to change it. At the end, I also checked the composer installation to improve the automatization process.

Install php

Mysql / Mariadb

The last step I'm going to use is the database setup.
I want to create an initial database used by my app using Mariadb (a MySql fork).

Mariadb

Other Steps and Download

Of course, there are a lot of steps you can configure like: Solr, Redis and so on but now is enough to make a test application based on that configuration. Go to the last step: Download Your Customized Archive.

Here is the place where we can download the config puphpet module file or all projects files.
Let's click on the green button

Download archive

And create somewhere two folders. I've chosen following paths:

  • ~/testapp/vagrant
  • ~/testapp/www

Unpack all downloaded file into the testapp/vagrant directory.

Config.yaml

The only one file generated by the configurator is located in the vagrant/puphpet/config.yaml path.
Our file should look like below:

vagrantfile:
    target: local
    vm:
        provider:
            local:
                box: puphpet/ubuntu1604-x64
                box_url: 'false'
                box_version: '0'
                chosen_virtualizer: virtualbox
                virtualizers:
                    virtualbox:
                        modifyvm:
                            natdnshostresolver1: false
                        showgui: 0
                    vmware:
                        numvcpus: 1
                    parallels:
                        linked_clone: 0
                        check_guest_tools: 0
                        update_guest_tools: 0
                machines:
                    vflm_k4itnhhid5s4:
                        id: machine1
                        hostname: machine1.puphpet
                        network:
                            private_network: 192.168.56.102
                            forwarded_port:
                                vflmnfp_j24v5o08cywg:
                                    host: '6637'
                                    guest: '22'
                        memory: '2048'
                        cpus: '4'
        provision:
            puppet:
                manifests_path: puphpet/puppet/manifests
                module_path:
                    - puphpet/puppet/modules
                    - puphpet/puppet/manifests
                options:
                    - '--verbose'
                    - '--hiera_config /vagrant/puphpet/puppet/hiera.yaml'
        synced_folder:
            vflsf_8wdfqwrda380:
                owner: www-data
                group: www-data
                source: ./
                target: /vagrant
                sync_type: nfs
                smb:
                    smb_host: ''
                    smb_username: ''
                    smb_password: ''
                    mount_options:
                        dir_mode: '0775'
                        file_mode: '0664'
                rsync:
                    args:
                        - '--verbose'
                        - '--archive'
                        - '-z'
                    exclude:
                        - .vagrant/
                        - .git/
                    auto: 'true'
            vflsf_20wd8du0kjef:
                owner: www-data
                group: www-data
                source: ../www
                target: /var/www
                sync_type: nfs
                smb:
                    smb_host: ''
                    smb_username: ''
                    smb_password: ''
                    mount_options:
                        dir_mode: '0775'
                        file_mode: '0664'
                rsync:
                    args:
                        - '--verbose'
                        - '--archive'
                        - '-z'
                    exclude:
                        - .vagrant/
                        - .git/
                    auto: 'true'
        usable_port_range:
            start: 10200
            stop: 10500
        post_up_message: ''
    ssh:
        host: 'false'
        port: 'false'
        private_key_path: 'false'
        username: vagrant
        guest_port: 'false'
        keep_alive: '1'
        forward_agent: 'false'
        forward_x11: 'false'
        shell: 'bash -l'
        insert_key: 'false'
    vagrant:
        host: detect
    proxy:
        http: ''
        https: ''
        ftp: ''
        no_proxy: ''
server:
    install: '1'
    packages:
        - vim
        - htop
        - wkhtmltopdf
        - zip
users_groups:
    install: '1'
    groups:
        - testapp
    users:
        - '{testapp}{testapp}'
locale:
    install: '1'
    settings:
        default_locale: en_US.UTF-8
        locales:
            - en_GB.UTF-8
            - en_US.UTF-8
        timezone: UTC
firewall:
    install: '1'
    rules: {  }
resolv:
    install: '1'
    nameservers:
        - 8.8.8.8
        - 8.8.4.4
    domainname: ''
    searchpath: {  }
cron:
    install: '1'
    jobs:
        cj_prs7zkvw7g1b:
            name: 'testapp jobs'
            user: vagrant
            command: 'php /var/www//testapp/cron.php > /dev/null'
            minute: '1'
            hour: '*/2'
            weekday: '*'
            month: '*'
            monthday: ''
nginx:
    install: '0'
    settings:
        version: present
        default_vhost: 1
        proxy_buffers: '4 256k'
        proxy_buffer_size: 128k
        proxy_connect_timeout: 600s
        proxy_send_timeout: 600s
        proxy_read_timeout: 600s
        names_hash_bucket_size: 128
    upstreams: {  }
    vhosts:
        nxv_n087wiye8ku9:
            server_name: awesome.dev
            server_aliases:
                - www.awesome.dev
            www_root: /var/www/awesome
            listen_port: '80'
            client_max_body_size: 1m
            ssl: '0'
            locations:
                nxvl_ffz4010gqxpk:
                    www_root: /var/www/awesome/web
                    location: /
                    autoindex: 'off'
                    internal: 'false'
                    index_files:
                        - index.html
                        - index.php
                        - app.php
                    try_files:
                        - $uri
                        - $uri/
                        - /index.php$is_args$args
                        - /app.php$is_args$args
                    fastcgi: ''
                    fastcgi_index: ''
                    fastcgi_split_path: ''
                    proxy: ''
                    proxy_redirect: ''
                nxvl_ekxxfmbtwfxp:
                    www_root: /var/www/awesome/web
                    location: '~ ^/(app_dev|config)\.php(/|$)'
                    autoindex: 'off'
                    internal: 'false'
                    try_files:
                        - $uri
                        - $uri/
                        - /app_dev.php$is_args$args
                    fastcgi: '127.0.0.1:9000'
                    fastcgi_index: app_dev.php
                    fastcgi_split_path: '^(.+\.php)(/.*)$'
                    fast_cgi_params_extra:
                        - 'SCRIPT_FILENAME $document_root$fastcgi_script_name'
                        - 'APP_ENV dev'
                    set:
                        - '$path_info $fastcgi_path_info'
                    proxy: ''
                    proxy_redirect: ''
                nxvl_kiz7c855rr19:
                    www_root: /var/www/awesome/web
                    location: '~ ^/index\.php(/|$)'
                    autoindex: 'off'
                    internal: 'false'
                    try_files:
                        - $uri
                        - $uri/
                        - /index.php$is_args$args
                    fastcgi: '127.0.0.1:9000'
                    fastcgi_index: index.php
                    fastcgi_split_path: '^(.+\.php)(/.*)$'
                    fast_cgi_params_extra:
                        - 'SCRIPT_FILENAME $document_root$fastcgi_script_name'
                    set:
                        - '$path_info $fastcgi_path_info'
                    proxy: ''
                    proxy_redirect: ''
                nxvl_4x0fk1jrwczd:
                    www_root: /var/www/awesome/web
                    location: '~ ^/app\.php(/|$)'
                    autoindex: 'off'
                    internal: 'false'
                    try_files:
                        - $uri
                        - $uri/
                        - /app.php$is_args$args
                    fastcgi: '127.0.0.1:9000'
                    fastcgi_index: app.php
                    fastcgi_split_path: '^(.+\.php)(/.*)$'
                    fast_cgi_params_extra:
                        - 'SCRIPT_FILENAME $document_root$fastcgi_script_name'
                        - 'APP_ENV prod'
                    set:
                        - '$path_info $fastcgi_path_info'
                    proxy: ''
                    proxy_redirect: ''
    proxies: {  }
apache:
    install: '1'
    settings:
        version: 2.4
        user: www-data
        group: www-data
        default_vhost: true
        manage_user: false
        manage_group: false
        sendfile: 0
    modules:
        - proxy_fcgi
        - rewrite
    vhosts:
        av_ds7c9tnjwhe7:
            servername: testapp.dev
            docroot: /var/www/testapp/web
            port: '80'
            setenvif:
                - 'Authorization "(.*)" HTTP_AUTHORIZATION=$1'
            custom_fragment: ''
            ssl: '0'
            ssl_cert: LETSENCRYPT
            ssl_key: LETSENCRYPT
            ssl_chain: LETSENCRYPT
            ssl_certs_dir: LETSENCRYPT
            ssl_protocol: ''
            ssl_cipher: ''
            directories:
                avd_rt2ki1ql2fu5:
                    path: /var/www/testapp/web
                    directoryindex: 'index.php app.dev app.php'
                    options:
                        - Indexes
                        - FollowSymlinks
                        - MultiViews
                    allow_override:
                        - All
                    require:
                        - 'all granted'
                    custom_fragment: ''
                    provider: directory
            files_match:
                avfm_v71rd527gjtf:
                    path: (app_dev|config)\.php$
                    sethandler: 'proxy:fcgi://127.0.0.1:9000'
                    setenv:
                        - 'APP_ENV dev'
                    custom_fragment: ''
                    provider: filesmatch
                avfm_qy6m6xg433l6:
                    path: app\.php$
                    sethandler: 'proxy:fcgi://127.0.0.1:9000'
                    setenv:
                        - 'APP_ENV prod'
                    custom_fragment: ''
                    provider: filesmatch
                avfm_cb8wrbi2n6zb:
                    path: \.php$
                    sethandler: 'proxy:fcgi://127.0.0.1:9000'
                    custom_fragment: ''
                    provider: filesmatch
letsencrypt:
    install: '1'
    settings:
        email: ''
        webserver_service: ''
    domains: {  }
php:
    install: '1'
    settings:
        version: '7.1'
    modules:
        php:
            - cli
            - intl
            - xml
            - curl
            - bz2
            - mysql
            - geoip
        pear: {  }
        pecl: {  }
    ini:
        display_errors: 'On'
        error_reporting: '-1'
        session.save_path: /var/lib/php/session
        date.timezone: UTC
    fpm_ini:
        error_log: /var/log/php-fpm.log
    fpm_pools:
        phpfp_ebvr4hi3kq17:
            ini:
                prefix: www
                listen: '127.0.0.1:9000'
                security.limit_extensions: .php
                user: www-user
                group: www-data
    composer: '1'
    composer_home: ''
xdebug:
    install: '1'
    settings:
        xdebug.default_enable: '1'
        xdebug.remote_autostart: '0'
        xdebug.remote_connect_back: '1'
        xdebug.remote_enable: '1'
        xdebug.remote_handler: dbgp
        xdebug.remote_port: '9000'
blackfire:
    install: '0'
    settings:
        server_id: ''
        server_token: ''
        agent:
            http_proxy: ''
            https_proxy: ''
            log_file: stderr
            log_level: '1'
        php:
            agent_timeout: '0.25'
            log_file: ''
            log_level: '1'
xhprof:
    install: '0'
wpcli:
    install: '0'
    version: v1.1.0
drush:
    install: '0'
    version: 8.0.5
ruby:
    install: '1'
    versions:
        rv_fgahfoxuxm8m:
            default: '1'
            bundler: '1'
            version: 2.3.1
            gems:
                - [email protected]
                - [email protected]
                - [email protected]
python:
    install: '1'
    packages: {  }
    versions: {  }
nodejs:
    install: '0'
    settings:
        version: '6'
    npm_packages: {  }
mariadb:
    install: '1'
    settings:
        version: '10.1'
        root_password: '123'
        override_options: {  }
    users:
        mariadbnu_9ujhdpfj2d60:
            name: testapp
            password: '123'
    databases:
        mariadbnd_6bxe69ouot9n:
            name: testapp
            sql: ''
    grants:
        mariadbng_z4drxt7vpk11:
            user: testapp
            table: '*.*'
            privileges:
                - ALL
mysql:
    install: '0'
    settings:
        version: '5.7'
        root_password: '123'
        override_options: {  }
    users:
        mysqlnu_74n6vlw5x1vr:
            name: dbuser
            password: '123'
    databases:
        mysqlnd_w1gyqiltk87y:
            name: dbname
            sql: ''
    grants:
        mysqlng_4nlv2f7bql9c:
            user: dbuser
            table: '*.*'
            privileges:
                - ALL
postgresql:
    install: '0'
    settings:
        global:
            encoding: UTF8
            version: '9.6'
        server:
            postgres_password: '123'
    databases: {  }
    users: {  }
    grants: {  }
mongodb:
    install: '0'
    settings:
        bind_ip: 127.0.0.1
        port: '27017'
    globals:
        version: 2.6.0
    databases: {  }
redis:
    install: '0'
    settings:
        port: '6379'
sqlite:
    install: '0'
    databases: {  }
mailhog:
    install: '0'
    settings:
        smtp_ip: 0.0.0.0
        smtp_port: 1025
        http_ip: 0.0.0.0
        http_port: '8025'
        path: /usr/local/bin/mailhog
beanstalkd:
    install: '0'
    settings:
        listenaddress: 0.0.0.0
        listenport: '11300'
        maxjobsize: '65535'
        maxconnections: '1024'
        binlogdir: /var/lib/beanstalkd/binlog
        binlogfsync: null
        binlogsize: '10485760'
    beanstalk_console: 0
rabbitmq:
    install: '0'
    settings:
        port: '5672'
    users: {  }
    vhosts: {  }
    plugins: {  }
elastic_search:
    install: '0'
    settings:
        version: 2.3.1
        java_install: true
    instances:
        esi_299dbdf64vje:
            name: es-01
solr:
    install: '0'
    settings:
        version: 5.5.2
        port: '8984'


As you probably have already realized, the configurator is just a gui for the generated file. If you need change something just edit it or put it again into the https://puphpet.com/ (drag & drop works) to load values again and add something.

Run the Machine

To run the machine go to the vagrant using a terminal and use the vagrant up command.
Meantime when vagrant is running the VM put someting into the www/testapp/web/index.php location.
I added the following code:

<?php
phpinfo();

To check if machine is working properly use vagrant status.
To connect by ssh use vagrant ssh.

To check if everything has been resolved properly so far just go to the http://testapp.dev. You should see the phpinfo page like that:

Phpinfo

I hope you will enjoy the tool as much as I do.
Next time I will show how to extend Puppet by new instructions - I will deploy my application using the configuration I created here.

Bests!

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Congratulations @egoto! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 2 years!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Vote for @Steemitboard as a witness to get one more award and increased upvotes!