Mailing List App: Development Environment(Part II)
I present the second post from The Serverless Mailing App series. So far, we’ve seen how to define a simple project using user stories and sketches. Also, we select the main technological stack for our application based on the Aws Lambda stack for PHP and JS. Also, we define the required API endpoints and commands to make a minimum viable product.
In the current chapter, we will prepare the Mailing application development environment using docker within docker-compose, and we will create an initial local Continuous Integration Pipeline for the PHP Backend.
In the next chapter, we will end adding the frontend to the development environment and configure the initial deploy to production infrastructure.
To easily follow the tutorial, I have just created a new repository in Github. Here you can find all the actions we are going to do step by step.
1.3 Setting Up Development Environment
Hands-on, we’ll start creating an empty Github repository. We need to add a minimum readme with installation instructions for the current stage, MIT License file, community files, and the .gitignore.
For the development environment, we have the following services: An Nginx HTTP server to act as API Gateway, an Antidot Framework Starter as backend API and Admin, and a Nuxt App as frontend. Although, we will need a MySql database and a queue worker to simulate SQS we get on these topics in future posts.
1.3.1 Installing Backend Development Environment
Let’s start from the beginning. We will create the backend API first. Create a “backend” directory and a docker-compose.yml file in the root path of the project.
In the above code, I define the docker-compose syntax version, in the “services” key, a “backend” volume definition, and an entry describing the API gateway implemented by a custom Nginx build. Then I define the ports to map between the docker daemon and host machine. At last, I include the “backend” folder mapped as “/opt/backend” inside the Nginx machine.
Now, we have to create a build config for the API gateway service. Add a folder named “nginx/” in the root path of the project, and create a “Dockerfile” inside it.
In this docker file, I get the stable Nginx official image, installing SSL dependencies and certificate to it, then I copy Nginx config files from the host machine to dockerized Nginx.
Now in the “nginx/nginx.conf” file we have to put the Nginx default config like the number of workers the mime-types config, process name, connection limit, the log path, and format, and the inclusion of any file with the “.conf” extension placed in “/etc/nginx/conf.d” the directory inside the Nginx docker.
Define the backend API dev environment in the same docker-compose file, don’t miss creating an empty “backend” directory in the project root path.
As when defining the Nginx fake API gateway, I am using a custom build from PHP image that exposes the port 9000 to the docker network, I create a volume linking local development folder(here is where we go to code the application). And I set the linked folder as Docker image working dir.
Let see the PHP Dockerfile:
In the file above, I get an official PHP-FPM 7.4.3 image, and I enable some extensions with its dependencies on the machine. After that, I copy the composer image to the PHP docker bin path, and I install the Prestissimo composer plugin to speed up package installation.
To make this stuff functional, we need to enable the Backend API endpoint inner Nginx config. I use “nginx/backend-api.conf”, for now, we put it accessible from “/” path.
In the backend API Nginx config file, I added the docker backend_php using an upstream, listening to the port 9000, remember that I exposed t the network before.
Then I define a default PHP-FPM runtime for the server and enable it. If you want to dig in more depth on Nginx configuration options, you can see its official documentation.
If you don’t have docker and docker-compose installed yet, I recommend following the official documentation.
The next step is to build our docker infrastructure running the following command:
docker-compose build
Wait some minutes while downloading docker images and compiling all dependencies, after that, you will have PHP and composer available to use from docker, let’s see.
docker-compose run --rm backend_php php -v
docker-compose run --rm backend_php composer --version
Everything ready to install our preferred framework, I will use the Antidot framework. If you don’t know it, you can check this article.
I want to tell you that the framework choice can be something very personal, thinking whichever one you are most comfortable with, or what you know better.
Maybe the decision may fall in more pragmatic arguments, like a company using some tooling, will have more options to contract talent, a tool having Long term support policies, etc.
In this case, because of a personal project, I choose a young framework like Antidot, take in mind that every case or code that I will write is functional in most market professional frameworks like Laminas, Mezzio, Symfony, or Laravel to comment on the main of them.
Let’s install the framework:
docker-compose run --rm backend_php composer create-project antidot-fw/antidot-framework-starter .
After installing all dependencies, we can check if everything works correctly by check the framework CLI tool.
docker-compose run --rm backend_php bin/console config:show:container
It will show all dependencies added to the DI-container. Great!
The console work well, now we will check our server. Run the server by docker-compose:
docker-compose up -d
Open a browser window at 127.0.0.1, and you will see the Antidot Framework Starter default homepage.
We will add the development domain name to the “/etc/hosts” file to access thought dev.mailing.antidotfw.io.
# /etc/hosts
127.0.0.1 localhost
127.0.0.1 dev.mailing.antidotfw.io
Now open the browser again and type the new domain name, you will continue watching the default page.
In the current project stage, we don’t have any code related to application yet, but we have a stable development environment to start coding the backend API.
Before the end, we will define a minimum local CI pipeline, we will use a simple bash script that we will go extending since we need to add more functionality to the CI pipeline.
For the backend API, Antidot frameworks goes with out of the box local CI configuration let’s see “backend/composer.json” file’s scripts section:
Create the script at the project root directory named “ci-check.sh” as follows:
Give execution permissions and test it.
sudo chmod +x ./ci-checks.sh
./ci-checks.sh
Conclusion:
In this chapter, we saw a lot of concepts related to docker like managing official images to fit our requirements, or setting up execution user to avoid permission issues. On the other side we saw how to add a minimum Nginx config to run a PHP web server.
In the next delivery, we’ll end setting up the development environment adding the Fronted Nuxt app, and we will start testing production deployments.
Thank you very much for reading to the end. It is an honor for me to maintain your interest. Greetings and Happy Coding;-D.