awslamp

Bitnami How-To Guides for AWS Cloud

Develop Locally, Test Remotely with Bitnami LAMP and Git

Introduction

When developing applications, having consistent server environments is key. This means that individual developers working on the application should use the same development environment, and development, production and test environments should also be consistent with each other. This reduces friction, simplifies the work of DevOps teams and avoids the “it works on my machine” syndrome.

Bitnami stacks provide a solution to this problem. Bitnami’s LAMP stack, for example, provides a complete, fully-integrated and ready to run LAMP development environment for multiple platforms. Since it’s the same image, just packaged differently for each platform, developers can write code on their local systems using the tools they’re most comfortable with, then transfer that code to a cloud server running the same image without ever encountering any missing libraries or incompatibilities. For a solo developer, this out-of-the-box consistency can often save hours of time and effort.

This article will demonstrate how a solo developer can use the Bitnami LAMP stack to develop an application locally and make it available for immediate testing by a client or end-user on a public cloud server. With a little help from Git (which comes pre-installed in the Bitnami LAMP stack), application changes made by the developer on his or her local machine can be immediately reflected in the public test version running in the cloud.

NOTE: The approach outlined in this article is best suited for a solo developer whose goal is to develop an application locally but also be able to deploy it to a public cloud server so that end-users can view and test it. Although this article uses the Bitnami LAMP stack and a PHP application as an example, the approach outlined here will also work for other Bitnami stacks and programming languages.

Assumptions and prerequisites

This guide makes the following assumptions:

  • You know the basics of using PHP, Apache and Composer.
  • You have a Bitnami LAMP VirtualBox virtual machine with SSH enabled.
  • You have deployed the Bitnami LAMP stack on a cloud server.
  • You know the public IP address of the cloud server.
  • You have an SSH key pair and you know the basics of using SSH.
  • You are able to log in to both the Bitnami LAMP virtual machine and the Bitnami LAMP cloud server from your host system using SSH.

TIP: To generate a new SSH key pair, you can use PuTTYgen (Windows) or the ssh-keygen command (Linux and Mac OS X). Read instructions on how to use PuTTYgen and instructions on how to use ssh-keygen.

Step 1: Create a custom PHP application on the LAMP virtual machine

The first step is to create an application on your local development environment: the Bitnami LAMP virtual machine. In this example, we’ll assume that you’re creating a PHP version of the board game Twister and that you’ve decided to use Laravel as the PHP framework.

  • Begin by logging in to the virtual machine using SSH and creating the directory tree for your application. These steps assume that your application will live in the /opt/bitnami/apps/twister/ directory:

    $ cd /opt/bitnami/apps
    $ sudo mkdir twister
    $ sudo chown -R bitnami.bitnami twister/
    $ cd twister/
    $ mkdir conf htdocs
    
  • Create a Laravel skeleton application using Composer (included with the Bitnami LAMP stack):

    $ cd htdocs
    $ composer require laravel/installer
    $ vendor/bin/laravel new -f .
    
  • Set permissions for the writable storage area of the application:

    $ sudo chown -R bitnami.daemon storage/
    $ sudo chmod -R 775 storage/ 
    
  • Create and edit the /opt/bitnami/apps/twister/conf/httpd-prefix.conf file and add the lines below to it. Notice that the document root for the application in this and subsequent configuration files is set to point to the public/ sub-directory of the Laravel application.

    Alias /twister/ "/opt/bitnami/apps/twister/htdocs/public/"
    Alias /twister "/opt/bitnami/apps/twister/htdocs/public"
    Include "/opt/bitnami/apps/twister/conf/httpd-app.conf"
    
  • Create and edit the /opt/bitnami/apps/twister/conf/httpd-app.conf file and add the content below to it. This is the main configuration file for your application, so modify it further depending on your application’s requirements.

    <IfDefine USE_PHP_FPM>
        <Proxy "unix:/opt/bitnami/php/var/run/phpmyadmin.sock|fcgi://phpmyadmin-fpm" timeout=300>
        </Proxy>
    </IfDefine>
    
    <Directory /opt/bitnami/apps/twister/htdocs/public/>
        Options +FollowSymLinks
        AllowOverride None
        <IfVersion < 2.3 >
        Order allow,deny
        Allow from all
        </IfVersion>
        <IfVersion >= 2.3>
        Require all granted
        </IfVersion>
    </Directory>
    

    NOTE: If your application uses .htaccess files, you should change the AllowOverride None option to AllowOverride All.

  • Once you have created the files and directories above, add the following line to the end of the main Apache configuration file at /opt/bitnami/apache2/conf/bitnami/bitnami-apps-prefix.conf, as shown below:

    Include "/opt/bitnami/apps/twister/conf/httpd-prefix.conf"
    
  • Restart the Apache server:

    $ sudo /opt/bitnami/ctlscript.sh restart apache
    

You should now be able to access the skeleton application’s welcome page at http://VM-SERVER-IP/twister. Here’s a screenshot of what you should see:

Laravel default welcome page

Step 2: Create a local Git repository for your application

The next step is to create a local Git repository for your application code and then commit the initial set of files to it by running the commands below. Replace the example name and email address shown below with your correct information.

    $ git config user.name "John Doe"
    $ git config user.name "user@example.com"
    $ cd /opt/bitnami/apps/twister/htdocs/
    $ git init . 
    $ git add .
    $ git commit -a -m "Initial commit"

By default, your changes will be committed to the repository’s master branch. However, you’d typically want to save new, untested changes in a different branch and merge them into the master branch only once you’re confident that they work as expected. With this in mind, create a dev-master branch for work in progress:

    $ git checkout -b dev-master

NOTE: This dev-master branch is the branch that you’ll deploy to the cloud server for you and other users to view and test new changes in the application.

Step 3: Configure Apache on the LAMP cloud server

Once you have your local development environment up and running, the next step is to configure the Bitnami LAMP stack running on the cloud server (where you and/or end-users will test the latest changes). If you wish, you can replicate the same directory structure there but for variety, let’s assume that you want the application on the cloud server to be visible at the document root - that is, at http://CLOUD-SERVER-IP/ instead of http://CLOUD-SERVER-IP/twister.

  • To begin, log in to the cloud server and delete the files in the current Apache document root:

    $ cd /opt/bitnami/apache2/htdocs/
    $ rm -rf *
    
  • Change the Apache configuration so that the document root points to the public/ directory of the Laravel application by editing the /opt/bitnami/apache2/conf/bitnami/bitnami.conf file and replacing all instances of the path /opt/bitnami/apache2/htdocs to /opt/bitnami/apache2/htdocs/public/. Here’s an example of what the end result should look like:

    <VirtualHost _default_:80>
      DocumentRoot "/opt/bitnami/apache2/htdocs/public"
      <Directory "/opt/bitnami/apache2/htdocs/public">
        Options Indexes FollowSymLinks
        AllowOverride All
        <IfVersion < 2.3 >
          Order allow,deny
          Allow from all
        </IfVersion>
        <IfVersion >= 2.3 >
          Require all granted
        </IfVersion>
      </Directory>
    
      # Error Documents
      ErrorDocument 503 /503.html
    
      # Bitnami applications installed with a prefix URL (default)
      Include "/opt/bitnami/apache2/conf/bitnami/bitnami-apps-prefix.conf"
    </VirtualHost>
    ...
    <VirtualHost _default_:443>
      DocumentRoot "/opt/bitnami/apache2/htdocs/public"
      SSLEngine on
    SSLCertificateFile "/opt/bitnami/apache2/conf/server.crt"
    SSLCertificateKeyFile "/opt/bitnami/apache2/conf/server.key"
    
      <Directory "/opt/bitnami/apache2/htdocs/public">
        Options Indexes FollowSymLinks
        AllowOverride All
        <IfVersion < 2.3 >
          Order allow,deny
          Allow from all
        </IfVersion>
        <IfVersion >= 2.3 >
          Require all granted
        </IfVersion>
      </Directory>
    
      # Error Documents
      ErrorDocument 503 /503.html
    
      # Bitnami applications installed with a prefix URL (default)
      Include "/opt/bitnami/apache2/conf/bitnami/bitnami-apps-prefix.conf"
    </VirtualHost>
    ...
    

    NOTE: The /opt/bitnami/apache2/htdocs/public/ directory does not exist yet, but it will be created the first time you deploy the application to the cloud server.

  • As an optional step, depending on your security requirements, password-protect access to the application.

  • Restart Apache to have the configuration changes take effect.

    NOTE: You will see a warning that the public/ directory, which is referenced as the Web server’s document root, does not exist. Ignore this warning for the moment, as this directory will be created when you deploy the application to the cloud server.

    $ sudo /opt/bitnami/ctlscript.sh restart apache
    

Step 4: Create a bare Git repository and post-receive hook

The next step is to create a bare Git repository on the server, and a post-receive hook that will accept new commits and deploy to the server document root.

  • Create a bare Git repository:

    $ cd /home/bitnami
    $ mkdir twister.git
    $ cd twister.git
    $ git init --bare
    
  • Create a local environment file at /home/bitnami/twister.env for the Laravel application and fill it with the following content. This file is Laravel-specific, so you can omit this step for non-Laravel applications:

    APP_NAME=Laravel
    APP_ENV=local
    APP_KEY=base64:+4eyQtLSPQ5p/gjj+qEKJ7i+RIEcLEvv+lYIDcTUOPA=
    APP_DEBUG=true
    APP_URL=http://localhost
    
    LOG_CHANNEL=stack
    
    DB_CONNECTION=mysql
    DB_HOST=127.0.0.1
    DB_PORT=3306
    DB_DATABASE=laravel
    DB_USERNAME=root
    DB_PASSWORD=
    
    BROADCAST_DRIVER=log
    CACHE_DRIVER=file
    QUEUE_CONNECTION=sync
    SESSION_DRIVER=file
    SESSION_LIFETIME=120
    
  • Create a post-receive hook at /home/bitnami/twister.git/hooks/post-receive and fill it with the following code:

    #!/bin/sh
    # check out dev-master branch
    GIT_WORK_TREE=/opt/bitnami/apache2/htdocs git checkout -f dev-master
    
    # custom steps for deployment
    # update this depending on your application needs
    cd /opt/bitnami/apache2/htdocs
    sudo chown -R bitnami.daemon storage
    sudo chmod -R 775 storage
    composer update
    cp /home/bitnami/twister.env .env
    

    Every time you push a new commit to this repository, the post-receive hook will check out the latest version of the dev-master branch to the /opt/bitnami/apache2/htdocs directory. It will then perform any custom deployment steps required to get your application working.

    In this case, the steps are similar to those performed when you initialized the Laravel application in your local development environment. Depending on your application’s requirements, modify the steps shown above as needed.

  • Make the post-receive hook executable:

    $ sudo chmod +x /home/bitnami/twister.git/hooks/post-receive
    

Step 5: Configure SSH and test the Git remote repository

The next step is to configure SSH so that it’s possible to log in to the Bitnami LAMP cloud server from the Bitnami LAMP virtual machine. This is needed so that you can push code changes from the virtual machine to the bare repository on the cloud server.

The easiest way to do this is by forwarding your SSH key on the host machine:

  • On your host system, add the following lines to the ~/.ssh/config file:

    Host *
     ForwardAgent yes
    
  • Add your private key to the SSH agent on the host system:

    $ ssh-add
    

You should now be able to log in to the Bitnami LAMP virtual machine over SSH and, from there, also log in to the Bitnami LAMP cloud server. In case of difficulties, read more about using SSH agent forwarding.

Next, configure the bare Git repository on the Bitnami LAMP cloud server as a remote repository and test it, as follows:

  • Log in to the Bitnami LAMP virtual machine. Add the cloud server as a remote server for your repository, as shown below. Replace the CLOUD-SERVER-IP placeholder with the public IP address of the cloud server:

    $ git remote add test-server ssh://CLOUD-SERVER-IP/home/bitnami/twister.git
    
  • Push the dev-master branch to the cloud server:

    $ git checkout -b dev-master
    $ git push test-server dev-master
    

    This should trigger the post-receive hook script on the cloud server and cause the latest version of the dev-master branch to be deployed with all dependencies, permissions and configuration.

  • Browse to the cloud server’s IP address and confirm that you see the application welcome page.

Step 6: Develop locally, deploy and test remotely

Verify that everything is working correctly by making a change to the application code in your local environment, pushing that change and viewing it on the cloud server.

  • In the Bitnami LAMP virtual machine, edit the welcome page view:

    $ cd /opt/bitnami/apps/twister/htdocs
    $ vi resources/views/welcome.blade.php
    
  • Find the page title and change it. For example, change the default title “Laravel” to “Welcome to Twister!”.

  • Save the changes, commit and push:

    $ git commit -a -m "Changed title"
    $ git push test-server dev-master
    
  • Browse to the cloud server’s IP address and confirm that you see the modified welcome page, as shown below:

    Laravel modified welcome page

You now have a basic system in place which will allow you to develop and commit changes locally on the Bitnami LAMP virtual machine, then immediately make those changes visible on a public Bitnami LAMP cloud server that you or your clients can access for testing or review purposes.

To learn more about the topics discussed in this guide, consider visiting the following links:

The approach described in Steps 4 and 5 of this guide is based on information in the following tutorial:

Last modification August 30, 2019