A historical Bash project for installing, configuring and testing an Apache–PHP–MySQL web stack through a terminal user interface.
Caution
This project was originally developed in 2013–2014 and has not been updated for current Linux distributions. Do not run the scripts on a production system or an important workstation.
The code targets the Apache, PHP 5 and MySQL conventions of its time. It also performs privileged, system-wide changes—including recursive permission changes—and handles database credentials in ways that are not acceptable for a modern deployment.
The repository is currently preserved for its educational and historical value. It shows how a guided shell application can break a LAMP deployment into installation, configuration, validation, sample-application deployment and log-inspection stages.
A secure modernization is proposed in the 2026 roadmap. Until that work is complete, the repository should be treated as reference code only.
The main entry point, menu.sh, uses dialog to expose eleven
operations:
| Step | Script | Original purpose |
|---|---|---|
| 1 | 1_Install_Apache.sh |
Install Apache and start the service |
| 2 | 2_Configure_Apache.sh |
Configure a local virtual host and enable SSL support |
| 3 | 3_Test_Apache.sh |
Inspect the process and listening ports, then open the test page |
| 4 | 4_Install_PHP.sh |
Install PHP 5 and its Apache/MySQL integration packages |
| 5 | 5_Configure_PHP.sh |
Verify or install the PHP–MySQL package |
| 6 | 6_Test_PHP.sh |
Create and inspect a phpinfo() test file |
| 7 | 7_Install_MYSQL.sh |
Install the MySQL server |
| 8 | 8_Configure_MYSQL.sh |
Create a database user and database through a form |
| 9 | 9_Test_MYSQL.sh |
Check whether MySQL is listening |
| 10 | 10_Install_App.sh |
Deploy the sample PHP application and import its SQL data |
| 11 | 11_Show_Logs.sh |
Browse Apache errors by date |
The log_printer/ directory contains the date-based log
filters and the ficheros/ directory contains the original PHP
and SQL demonstration application.
Despite its age, the repository captures several useful systems-programming ideas:
- decomposing server provisioning into small, ordered operations;
- building a terminal interface with
dialog; - checking installed packages and service state;
- enabling Apache modules and virtual hosts;
- combining Bash, SQL and PHP in one deployment workflow;
- carrying out basic post-installation health checks;
- collecting and filtering web-server logs.
The project is especially useful as a legacy-modernization exercise: each original design decision can be compared with present-day approaches to idempotence, least privilege, secret management, automated testing and infrastructure as code.
The following table summarizes the most important compatibility and security gaps found during a static review in July 2026.
| Area | Original assumption | Why it needs to change |
|---|---|---|
| PHP | php5, php5-mysql and libapache2-mod-php5 |
PHP 5 is end-of-life; supported PHP 8 releases and current distribution packages must be used |
| Apache | /etc/apache2/sites-available/default and /var/www |
Current Debian/Ubuntu layouts use different default paths and should use a dedicated virtual host and document root |
| Services | service, /etc/init.d/* and process-name matching |
Service health should be verified through systemctl, native configuration tests and explicit HTTP checks |
| Networking | netstat and manual confirmation dialogs |
ss, curl and deterministic exit codes provide automatable checks |
| Database accounts | GRANT ALL PRIVILEGES ON *.* ... IDENTIFIED BY ... |
Account creation and grants now use separate statements; the application should receive privileges only for its own schema |
| Secrets | Passwords are read visibly, passed on the command line and written to a PHP file under the web root | Secrets can appear in process listings, shell state or served files; they need protected storage outside the document root |
| Permissions | Recursive chmod 777 followed by chmod 755 |
This grants unnecessary access and does not restore the original ownership or modes |
| Logs | Apache log files are recursively made world-writable, copied and decompressed | Logs should be read through controlled group access or journalctl, without changing their permissions |
| PHP example | Unquoted array keys such as $row[nombre] |
This legacy syntax is incompatible with modern PHP and must become $row['nombre'] |
| Sample data | The SQL fixture contains identifiable names and contact details | Public examples should use synthetic or anonymized data |
| Reliability | Relative paths, unquoted variables and locale-dependent package/date parsing | Running from another directory, using spaces or changing locale can break the workflow |
| Repository hygiene | Temporary files, editor backups, generated output and development notes are tracked | Generated and local-only files should be removed from the index and covered by .gitignore |
The code also contains logic defects independent of its age. For example, the Apache configuration comparison is malformed, the MySQL installation check reuses its pre-installation state, and the PHP test opens a local file rather than requesting it through Apache.
The legacy scripts should be inspected without executing their privileged operations:
git clone https://github.com/jagumiel/Server_setup.git
cd Server_setup
# Syntax only; this does not install or configure anything.
find . -type f -name '*.sh' -print0 |
xargs -0 -n1 bash -nAt the time of the July 2026 review, all 24 tracked shell scripts passed
bash -n. This confirms only that Bash can parse them; it does not confirm
correctness, compatibility or safety.
Preserve the original implementation as a clearly labelled legacy/ snapshot
and develop a version 2 alongside it:
Server_setup/
├── legacy/ # Preserved 2013–2014 implementation
├── ansible/
│ ├── inventory/
│ ├── roles/
│ │ ├── apache/
│ │ ├── php/
│ │ ├── database/
│ │ ├── demo_app/
│ │ └── observability/
│ └── site.yml
├── scripts/ # Thin validation and helper commands
├── tests/
├── docs/
└── README.md
Ansible is the recommended provisioning engine
because it makes package, service, file and template operations declarative
and idempotent. A redesigned dialog interface could remain as an optional
front end, but it should call the same non-interactive automation used by CI.
- Tag the existing code as a legacy release.
- Move the original implementation under
legacy/without rewriting its history. - Keep the prominent unsupported-code warning.
- Credit both original authors and document the academic context.
- Replace the identifiable SQL records with synthetic fixtures.
- Remove editor backups, temporary files, captured output and experimental notes from the maintained source tree.
- Replace the generic
.gitignorewith rules specific to this project.
Exit criterion: the historical work remains available, but nobody can mistake it for a supported installer.
- Define and document the supported operating-system matrix. Initial candidates are Ubuntu 24.04 LTS, Ubuntu 26.04 LTS and Debian 13.
- Decide whether version 2 supports MySQL only or the distribution-default MySQL-compatible server as well.
- Add
ShellCheck,shfmtand Bats tests. - Enable strict error handling, quote expansions and replace predictable
temporary files with
mktempplus cleanup traps. - Add
--check/--dry-run,--non-interactiveand verbose diagnostic modes. - Make every operation safe to run repeatedly.
Exit criterion: static checks pass and rerunning a no-op deployment makes no system changes.
- Use current distribution package names instead of PHP 5-specific packages.
- Create a dedicated Apache virtual host and document root.
- Validate Apache with
apache2ctl configtestbefore every reload. - Manage services through
systemctland verify sockets withss. - Port the demonstration application to supported PHP 8 syntax.
- Add explicit database connection error handling and UTF-8 (
utf8mb4) throughout. - Separate
CREATE USERfromGRANTand grant access only to the application schema. - Make database creation non-destructive; never drop an existing database without explicit confirmation.
Exit criterion: a clean supported VM can be provisioned twice and returns a successful application health check after both runs.
- Eliminate every recursive
chmod 777; set explicit owners and minimum required modes for each managed path. - Store database credentials outside the document root in a root-owned configuration or secrets backend.
- Never place passwords in command-line arguments, generated source files or the repository.
- Create a dedicated, least-privileged application database account.
- Bind the database to localhost unless remote access is explicitly requested and protected.
- Configure TLS with a documented certificate workflow.
- Add an optional host firewall policy exposing only the intended ports.
- Remove
phpinfo()immediately after any diagnostic check.
Exit criterion: an automated scan finds no committed secrets, world-writable managed paths or unnecessary database privileges.
- Check Apache configuration, service state and HTTP/HTTPS responses.
- Verify PHP execution through HTTP rather than by opening a local file.
- Run a real database connection and least-privilege query from the sample application.
- Replace locale-dependent log parsing with
journalctl, structured timestamps or a dedicated parser. - Add tests for fresh installation, repeated execution, partial failure and recovery.
- Run CI checks on every pull request and VM-based integration tests on supported distributions.
Exit criterion: the full test suite produces a machine-readable report and requires no visual confirmation dialogs.
- Publish an architecture overview and configuration reference.
- Add migration notes from the legacy layout.
- Provide a minimal quick start for a disposable VM.
- Generate a software bill of materials where container images or bundled dependencies are introduced.
- Sign and publish a reproducible
v2.0.0release.
Exit criterion: the repository can once again describe itself as a maintained server-provisioning project, with an explicit support policy.
The roadmap intentionally targets supported operating systems and distribution-provided packages rather than pinning the README to one minor package release:
- Ubuntu release cycle
- Debian stable releases
- PHP supported versions
- Apache HTTP Server documentation
- MySQL 8.4 Reference Manual
Exact versions must be recorded in the automated test matrix before version 2 claims compatibility.
Originally developed by:
- Jose Ángel Gumiel
This project is available under the MIT License.