A web server can be healthy on the instance and still be unreachable from your browser. Apache, the guest operating system, the EC2 security group, subnet routing, public addressing, DNS, and TLS are separate layers. This guide verifies them in that order so “connection timed out” does not turn into random package reinstalls.
Quick install for Amazon Linux 2023
sudo dnf upgrade -y
sudo dnf install -y httpd
sudo systemctl enable --now httpdRisk level: caution. Review the command before running it.
What these commands change
dnf upgrade -yapplies available package updates without an interactive confirmation; review changes first in controlled production maintenance windows.dnf install httpdinstalls Apache and resolved dependencies from enabled AL2023 repositories.systemctl enable --nowboth starts the current service and creates boot-time enablement.Package and service changes are confined to the EC2 guest, but upgrading can restart components or require a reboot; snapshot/AMI and rollback planning should match workload risk.
Prerequisites and network model
An EC2 instance running Amazon Linux 2023 with a supported architecture and current repositories.
A safe administrative path: AWS Systems Manager Session Manager, EC2 Instance Connect, or SSH restricted to your trusted public IP/CIDR. Never expose SSH to
0.0.0.0/0or::/0for convenience.Outbound access to configured package repositories, directly or through appropriate VPC endpoints/NAT/proxy design.
For direct public browsing: a public IPv4/Elastic IP or IPv6 address, subnet route to an internet gateway, and matching security controls. A private instance normally sits behind a load balancer or other ingress tier.
Inbound TCP 80 for HTTP testing and TCP 443 for production HTTPS at the component that terminates those protocols.
Choose the ingress topology before opening ports
Direct public instance: simpler for a lab, but the instance owns public addressing, TLS, ingress rules, and availability concerns. Avoid making this the default production pattern.
Private instance behind an ALB: the load balancer owns public listeners/certificates while the instance accepts only the application port from the ALB security group.
CloudFront or another edge in front: DNS, certificate, origin policy, caching, and header behavior add another verification layer.
Document where TLS terminates and whether traffic from that tier to Apache is HTTP or HTTPS; otherwise redirects, secure cookies, and client-address handling are easy to misconfigure.
How a browser request reaches Apache
Browser / client
│ DNS resolves hostname
▼
Public IP or load balancer listener :80/:443
│ route table + internet gateway / load balancer path
▼
Security group + network ACL
│ allowed TCP connection
▼
EC2 network interface
│ guest firewall / SELinux policy where configured
▼
Apache httpd listener → virtual host → /var/www/html contentVerify inward from the internet and outward from Apache instead of changing all layers together.
Failure clues by layer
A timeout usually points to address, route, security-group, network-ACL, host-firewall, or listener reachability.
An immediate connection refusal usually means the address is reachable but nothing accepts that port, or a firewall actively rejects it.
An HTTP 403/404/500 proves the request reached an HTTP server; move to virtual-host, filesystem, application, and Apache log analysis.
A TLS certificate/name error occurs after network reachability and TLS negotiation begin; it is not fixed by opening more ports.
1. Confirm the operating system first
cat /etc/os-release
printf 'Kernel: '; uname -r
printf 'Architecture: '; uname -mWhy identification comes before installation
AL2023 reports an Amazon Linux 2023 identity and uses
dnf; AL2 reports Amazon Linux 2 and historically usesyum.Package names, repository versions, defaults, and lifecycle differ across Amazon Linux, Ubuntu, RHEL, and other AMIs.
The kernel/architecture record helps correlate repository, AMI, module, and vendor-support issues.
Capture the AMI ID and build provenance in infrastructure code or inventory;
/etc/os-releasealone cannot prove how the instance was launched.
2. Update and install only Apache
The old tutorial installed an entire LAMP stack and pinned PHP 7.2/MariaDB 10.2 Extras even when the goal was simply Apache. Those versions are obsolete. Start with httpd; add a current PHP runtime, database client/server, or application dependencies only when the workload actually requires them.
sudo dnf check-update || test $? -eq 100
sudo dnf upgrade -y
sudo dnf install -y httpdRisk level: caution. Review the command before running it.
Package-management takeaways
dnf check-updatereturns status 100 when updates are available; the conditional accepts that documented nonzero result without hiding other failures.upgradechanges installed packages, so use an AMI/snapshot, autoscaling replacement, or tested rollback strategy for production.Installing
httpddoes not automatically expose a network port through EC2 security groups.Do not run package managers concurrently through user data, SSM, configuration management, and an interactive shell; lock contention and partial orchestration are avoidable.
3. Validate configuration and start httpd
sudo httpd -t
sudo systemctl enable --now httpd
sudo systemctl status httpd --no-pager
sudo ss -ltnp | grep -E "(:80|:443)\b"What healthy output means
httpd -tparses configuration and should report syntax success before a restart; it cannot validate every upstream application dependency.enable --nowpersists startup and starts immediately; inspect the service result rather than assuming success from an empty shell response.systemctl statusshows recent state and log context. Full diagnostics may requirejournalctl -u httpd.ssconfirms a local listening socket. Port 443 appears only after an HTTPS listener is configured.A listener on
0.0.0.0:80or[::]:80is local evidence; it does not prove that the VPC path permits public traffic.
4. Publish a minimal static page safely
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>EC2 Apache check</title>
</head>
<body>
<h1>Apache is serving this EC2 instance</h1>
<p>Replace this test page during deployment.</p>
</body>
</html>A harmless page for distinguishing your server from a default test response.
What this page verifies
The doctype and viewport provide predictable modern rendering; there is no application runtime or database dependency.
A unique heading distinguishes deployed content from a cached response, load balancer default, or Apache distribution test page.
Do not publish
phpinfo()or similar environment dumps: they expose versions, modules, paths, variables, and configuration details.Keep source content in version control and deploy it reproducibly rather than editing production files as root.
sudo install -o root -g apache -m 0644 site/index.html /var/www/html/index.html
sudo restorecon -v /var/www/html/index.html 2>/dev/null || true
sudo httpd -t
sudo systemctl reload httpdRisk level: caution. Review the command before running it.
Permissions and reload behavior
installcopies one reviewed file with explicit owner, group, and mode; Apache only needs read access for static content.Avoid recursively making
/var/wwwgroup-writable or owned by the interactive user on production servers. Use a deployment identity and least privilege.restoreconrestores the configured SELinux label when SELinux tooling/policy is present; the fallback prevents an absent command from blocking this portable step. Investigate real label failures instead of disabling SELinux.A graceful
reloadapplies configuration without the abrupt connection impact of a stop/start, but only after syntax validation.
5. Configure the EC2 security group
Attach an inbound rule for TCP 80 to the instance security group for public HTTP testing, or to the load balancer security group when Apache is private behind an ALB. Public websites commonly allow 0.0.0.0/0 and, when IPv6 is configured, ::/0 on ports 80/443. Administrative ports should remain restricted.
Direct instance: instance security group accepts client CIDRs on 80/443; the subnet and public address must support internet routing.
Behind an Application Load Balancer: load balancer group accepts clients; instance group accepts the application port only from the load balancer security group.
Network ACL: stateless rules must permit the request and return traffic; default NACLs typically do, custom NACLs may not.
IPv6: an IPv6 DNS record requires IPv6 addressing, route, and
::/0security rule; an IPv4-only rule does not cover it.Security-group changes apply to every associated resource. Review association scope before widening a rule.
6. Verify from inside and outside
curl -fsS http://127.0.0.1/
curl -I http://127.0.0.1/
# From a separate client, replace the placeholder:
curl -I http://PUBLIC_DNS_NAME/Interpret the two vantage points
Loopback success proves Apache and local content routing work; it bypasses EC2 ingress, public DNS, and internet routing.
-ftreats HTTP 4xx/5xx as failure,-sSkeeps successful output quiet while showing errors, and-Irequests response headers.PUBLIC_DNS_NAMEis a placeholder. Test from outside the VPC path you intend users to take.A public IP can change after stop/start unless you use an Elastic IP, load balancer, or stable DNS design.
Do not confuse an HTTP redirect with HTTPS readiness; follow and validate the certificate, hostname, and final response separately.
Amazon Linux 2 compatibility path
For an existing AL2 instance that cannot be migrated immediately, Apache itself is installed with yum. Do not revive the original amazon-linux-extras ... php7.2 line: it pins obsolete application components and is unnecessary for a static Apache server. Establish an AL2023 migration deadline and isolate the legacy workload.
sudo yum update -y
sudo yum install -y httpd
sudo httpd -t
sudo systemctl enable --now httpdRisk level: caution. Review the command before running it.
Legacy-host takeaways
These commands are for an already-existing AL2 system; they do not restore vendor support after end of life.
yumon AL2 anddnfon AL2023 reflect different platform generations; do not mix Extras-era recipes into AL2023.Patch the instance as far as its repositories permit, reduce exposure, monitor it, back it up, and prioritize replacement over indefinite in-place accumulation.
Test application, PHP/runtime, database, SELinux, systemd, and package changes during migration; AL2023 is not an in-place major-version upgrade.
Troubleshooting ladder
Package not found: confirm OS/release, repository access, DNS/outbound path, time, and package-manager locks.
httpd fails to start: run
httpd -t, then inspectsystemctl status httpdandjournalctl -u httpd; look for syntax, port collision, missing files, and permission/label errors.Loopback works, public request times out: inspect public addressing/load balancer, route table, internet gateway, security groups, NACL, guest firewall, and correct DNS record.
403 Forbidden: inspect directory/file execute/read permissions,
Requiredirectives, virtual-host/document root, and SELinux audit evidence.404 Not Found: confirm the active virtual host and document root; the file may exist under a directory Apache is not serving.
503 through load balancer: inspect target-group port/protocol, health-check path, target health, instance group source, and application response.
Page shows old content: identify CDN/proxy/browser cache, DNS target, load-balancer target, and response headers before restarting Apache.
Production hardening checklist
Run AL2023 on a repeatable AMI or launch template and automate patching/replacement.
Keep instances private behind a load balancer where architecture permits; restrict SSH or replace it with Session Manager.
Use HTTPS with managed certificate renewal and redirect HTTP; validate headers, protocol policy, and application cookies.
Deploy immutable/versioned content with a non-interactive identity; keep
/var/wwwnon-writable by the web process unless explicitly required.Remove default/test/debug pages, directory listings, unused modules, sample apps, and exposed status endpoints.
Send access/error/system logs and metrics to durable monitoring; alert on health, latency, 5xx, disk, certificate, and resource pressure.
Back up application data/configuration, test restore and replacement, and avoid storing critical state only on an instance root volume.
Related AWS and Linux guides
Connect safely using SSH access to an AWS Linux instance.
Understand account setup in registering for AWS Free Tier.
Diagnose host pressure with Linux CPU and memory monitoring.
Primary references
AWS’s AL2023 LAMP tutorial provides the current Amazon Linux package and httpd workflow.
AWS’s Amazon Linux 2 release notes state the June 30, 2026 end-of-life and migration recommendation.
The EC2 security-group rules reference documents HTTP/HTTPS ingress patterns.
AWS’s AL2023 TLS tutorial covers HTTPS prerequisites and current protocol guidance.
Comments and corrections