RBCloud & DevOpsTHE PRACTICAL LEARNING LIBRARY
By Ravindra BagaleResources

CHAPTER 59 / 60

Project 4 — Deploy LEMP and test the reels interface

Install the included project with a private configuration and a public-only document root.

Concept + practical labBy Ravindra Bagale · ~5 min read · lab time additional

Install code and dependencies

Copy the project to /var/www/reels. Install Composer using its official verified installer instructions, then run as a deployment user rather than root:

bash
cd /var/www/reels
composer install --no-dev --optimize-autoloader
composer audit
php -l public/api.php

The supplied composer.json is a dependency constraint, not a pre-resolved lock. Resolve dependencies once in your build environment, review/audit them and retain composer.lock for reproducible future installs. Do not update dependencies separately on each production server.

Configure privately

Copy config.example.php to /etc/academy-reels.php. Replace bucket, Region, DB endpoint/user/password, CA path and admin hash. Generate an admin hash from a hidden password prompt rather than putting the password in a shell argument:

bash
read -rsp 'Admin password: ' reels_password
printf '%s' "$reels_password" | php -r 'echo password_hash(stream_get_contents(STDIN), PASSWORD_DEFAULT), PHP_EOL;'
unset reels_password

Use the printed hash in config, not the plaintext password. Set config ownership to root plus the PHP-FPM worker group and mode 640. Ubuntu commonly uses www-data; AL2023 commonly uses a different configured pool account. Inspect the actual pool instead of guessing.

PHP and Nginx settings

Set FPM's loaded php.ini to upload_max_filesize=20M, post_max_size=22M, and suitable execution/input timeouts for a small lab upload. Restart the actual FPM unit. Copy the supplied Nginx config into an included path, replace hostname and confirm its socket. It includes request-rate limiting and blocks arbitrary PHP file execution. The document root must be /var/www/reels/public, never /var/www/reels. Test nginx -t, reload and configure HTTPS using the domain/TLS chapter. Leave secure_cookie true. Restrict access to your class/lab if this is not intended as a public service.

Interface workflow

Open the feed: it should explain that no videos exist. Open Admin, sign in, upload a small supported video with a caption, and open the feed again. The card presents a vertical player with controls and text. Use the returned post ID in the caption-edit form and refresh the feed to verify the update.

Failure clues

413 means a web/PHP request-body limit; 422 means validation rejected input; 401 means missing/invalid admin; 403 means CSRF mismatch; 429 means request limiting. A generic 500 requires server-side investigation. Do not display raw SQL errors or secrets to fix a classroom problem.

Ravindra’s Tip

Document root को public folder तक सीमित रखो। Config और vendor को बाहर रखने से एक गलत URL आपके database password तक नहीं पहुँच पाएगा।

Official references

Composer download and verification Nginx request limiting

Interview and revision check

Why must the Nginx root end in public?

Only intended browser-facing files belong there. Configurations, dependencies and source support files must not become downloadable.

Ravindra Bagale · Cloud & DevOps Academy · Handbook and project downloads