Hosting a website on Linux with Nginx and HTTPS involves more than installing a web server and requesting a certificate. Your domain must reach the right machine, Nginx must serve the right content, and certificate renewal must keep working after the initial setup.
The safest deployment order is straightforward: prepare the server, check DNS and network access, publish a basic HTTP site, enable HTTPS, then test renewal and recovery. Keep those stages separate. Otherwise, a certificate error can send you investigating TLS when the real problem is a firewall rule.
This guide follows that order for a public website on a single Linux server. It covers static files first, then the changes needed for an application behind Nginx. If the machine itself is not ready, start with setting up your first Linux server before exposing a website to the internet.
Decide What Nginx Will Serve
Start by choosing between a static website and an application. A static site consists of published HTML, CSS, JavaScript, images and other files. An application also needs a running program to generate responses, and may require a database, background workers or an upload directory.
For a brochure site, documentation project or exported blog, keep the first deployment static if that meets the requirements. Choose a document root containing only the published files. Avoid making a development checkout public just because it already contains an HTML file.
For an application, plan two separate services: Nginx as the public entry point and the application server behind it. Give each a clear owner, configuration location and recovery procedure. A website that depends on an application also depends on that application’s startup process.
Before making changes, record the domain names you intend to support. In this guide, example.com represents the main domain and www.example.com its optional alternative. Replace them with names you control; do not request certificates for names you have not configured.
Prepare Administrative Access
Use a supported Linux release, apply its pending security updates, and create an administrative account before publishing content. Keep the hosting provider’s recovery console available during network changes. A second route into the machine is worth arranging before you need it.
Set up SSH keys and access controls before tightening remote access. When changing authentication or firewall settings, leave the current session open and confirm that a new session succeeds before disconnecting.
Write down where you manage DNS, which account controls the server, and who receives operational alerts. For a shared project, store that information somewhere other than one person’s laptop. The deployment should remain manageable when its original administrator is unavailable.
Check DNS and Public Network Access
Work through network access before requesting a certificate. Check that the domain resolves to the intended public address, that inbound traffic can reach the server, and that Nginx will listen on the required interfaces.
Review the domain’s A records for IPv4 and any AAAA records for IPv6. Check the main domain and the www name separately. Do not assume that correcting one record corrects the other, or that every cached DNS answer changes immediately.
Pay particular attention to old IPv6 records. Let’s Encrypt initially prefers IPv6 when both address families are available; an incorrect response from an IPv6 server can fail validation without an IPv4 retry. Correct the address or remove the AAAA record if the site is not intended to support IPv6. The Let’s Encrypt IPv6 validation rules describe this behavior.
Allow inbound TCP traffic on port 80 for HTTP and port 443 for HTTPS. Review both the server’s firewall and any provider firewall or security group. If another device sits between the server and the internet, include its forwarding rules in the check.
Preserve administrative access while making these changes. Keep database ports and application backends out of the public rules unless the architecture requires otherwise. The separate guide to UFW, firewalld and nftables covers the mechanics of managing Linux firewall policies.
Test from outside the server’s network, such as a phone using mobile data. A successful request from the server itself is useful, but it does not prove that an external visitor can reach it.
Install Nginx and Check Its Service State
Choose one supported installation source and keep it consistent. For a first server, use the distribution’s maintained Nginx package unless you have a documented reason to choose another repository. Avoid mixing package sources simply to obtain a larger version number.
On Ubuntu, the official Nginx installation procedure covers package installation and initial checks. For another distribution, use its corresponding instructions rather than translating Ubuntu paths and package names by guesswork.
Before starting Nginx, check whether Apache, a container, a management panel or another service already owns the intended listening ports. Decide which service should handle public web traffic. Stopping an unfamiliar process without identifying its purpose can break another site on the same machine.
After installation, verify three things independently: the package is installed, the service is running, and startup at boot is enabled where required. These are different states. A process that works until the next reboot is not a finished deployment.
Use systemd service management to review startup behavior and service failures. Keep application services separate from Nginx so that you can diagnose or restart one without treating the entire website as a single process.
Create a Site Configuration and Document Root
Give the website its own content directory and configuration file. A useful arrangement separates published files, server configuration, logs and private application data. Choose names that make the site’s purpose obvious to the next administrator.
On Ubuntu, site configuration commonly uses /etc/nginx/sites-available/ for definitions and links in /etc/nginx/sites-enabled/ for enabled sites. Its packaged default site uses /var/www/html. These are packaging conventions, not directories that every Nginx installation must have; verify the active layout in Ubuntu’s Nginx configuration documentation.
Inspect which files the main configuration includes before adding another one. A correctly written site definition has no effect if Nginx never loads it. Conversely, an old enabled definition can continue matching requests after you have forgotten about it.
Choose the Site’s Basic Settings
For a static site, establish the following settings before adding redirects or TLS. Keep the initial configuration small enough that you can explain the purpose of every part.
| Setting | Purpose | Initial decision |
|---|---|---|
listen |
Selects the listening address and port. | HTTP on the intended IPv4 and IPv6 interfaces. |
server_name |
Identifies the site’s hostnames. | The main domain and any supported alternative. |
root |
Defines the base directory for published files. | A directory containing only public content. |
index |
Names the index files used for directory requests. | The site’s intended homepage file. |
try_files |
Checks file availability and selects a fallback. | A genuine missing-page response unless application routing requires otherwise. |
Nginx maps requests to files using the selected location and document root, then applies index or fallback behavior where configured. Check those relationships against the Nginx static content configuration reference, particularly if some sections use a different directory.
For a conventional static website, do not send every missing address to the homepage. That can hide broken links behind successful responses. A browser application may need a fallback to its entry page, but make that a deliberate routing decision rather than a universal repair.
Create a plain test homepage with an unmistakable site identifier. Once it appears through the domain, replace it with the published content. This small staging step makes it easier to distinguish your configuration from the packaged welcome page.
Set Permissions Without Making Everything Writable
Keep deployment access separate from web serving access. Let an administrative or deployment account manage published files, and give the Nginx worker account only the access it needs to serve them. Do not make the entire site writable by the web server as a routine convenience.
Review parent directories as well as the files themselves. Directory traversal permissions matter when a process tries to reach a document root. Our guide to Linux file permissions and ownership covers the distinction between file access, directory access and ownership.
Put private configuration, database exports, backups and credentials outside the public document root. For an application with a designated public directory, publish that directory rather than the whole project. Check deployment archives for forgotten copies of configuration files before uploading them.
On an SELinux system, ordinary ownership and permissions are only part of the check. Public content may need an appropriate label, such as httpd_sys_content_t, and reverse proxy connections may require an applicable policy setting. Use the procedures in Red Hat’s Nginx configuration and SELinux guidance rather than disabling SELinux to clear an error.
Where the application needs writable storage, identify those directories explicitly. Review upload handling separately from ordinary page delivery, and avoid granting write access to code or server configuration.
Verify HTTP Before Adding HTTPS
Test the initial HTTP site through its hostname. Check the homepage, one asset and an address that should not exist. Confirm that you receive your own content rather than a default page, another hosted site or a cached response from an intermediary.
Run Nginx’s configuration validation before applying edits. After a successful test, reload the service and check the result. Nginx reloads configuration by starting new workers and allowing old workers to finish existing requests; if it cannot apply the new configuration, it retains the old one. The Nginx configuration and reload documentation covers that behavior.
Keep a known working copy of the site configuration before each larger change. Apply one category of change at a time: routing, then TLS, then application integration. Combining them makes a failed deployment harder to reverse and harder to explain.
Do not collect login details or other sensitive submissions through the temporary HTTP site. Its job at this stage is to prove that the hostname, network path and content mapping work.
Obtain a Certificate with an ACME Client
Use an ACME client to manage certificate issuance and renewal. Certbot is one option with an Nginx integration. Decide whether you want it to modify the web server configuration or obtain certificates while you manage the configuration yourself.
Install Certbot through one maintained method appropriate to the server. Avoid leaving competing installations in place, especially when switching from distribution packages to a snap. Use the Certbot Nginx installation and issuance instructions for the snap route, including its prerequisites and renewal test.
Choose HTTP or DNS Validation
HTTP validation is a practical starting point for a public website already reachable on port 80. The client arranges a challenge response, and the certificate authority checks that response to validate control of the requested name.
Let’s Encrypt’s HTTP-01 challenge requires port 80 and does not issue wildcard certificates. DNS-01 instead validates a TXT record and supports wildcards. Choose between them using the Let’s Encrypt challenge requirements, not simply whichever method appears in the first tutorial you find.
For DNS validation, prefer an automated integration using narrowly scoped credentials. Do not place unrestricted registrar or DNS account credentials on the web server when a smaller permission set will do. Treat the validation credential as a secret and include its replacement procedure in your maintenance notes.
For a single public site without a wildcard requirement, keep the process simple. Check every requested hostname before issuance, and request only the names the site needs. Adding an unconfigured www name creates another failure to diagnose without making the deployment more complete.
Review the Result Before Redirecting Visitors
After issuance, inspect the configuration changes. Check which hostnames the certificate covers, where Nginx reads the certificate and private key, and whether the intended HTTPS site is enabled.
The certificate is public; the private key is not. Nginx needs access to the key through its privileged process, but that is not a reason to make the key broadly readable. The Nginx HTTPS configuration reference covers certificate loading, private key protection and certificate chains.
Do not copy certificate files into a convenient public folder. Keep certificate management in its designated location, and document any deployment step needed to make a renewed certificate available to Nginx.
Test HTTPS and Set the Canonical Address
Open the HTTPS site from an external device. Inspect the browser’s certificate details and confirm that the certificate matches the requested hostname. Check the validity period and test the main domain and its alternative separately.
Choose one public address as canonical: either the main domain or the www name. Test HTTPS on both before configuring permanent redirects. A visitor reaching the alternative HTTPS address needs a valid secure connection before receiving its redirect.
Then redirect ordinary HTTP page requests to the canonical HTTPS address. Preserve the path and query string where appropriate, and keep the certificate validation route working with the chosen ACME method. Avoid adding the same redirect independently in several layers without checking the combined result.
If a CDN or external proxy sits in front of Nginx, test that arrangement separately. Confirm which system terminates each connection, which certificate visitors receive, and whether the origin connection also has the protection your deployment requires.
Check More Than the Homepage
Load stylesheets, scripts, images, downloads and forms. HTTPS pages can still reference HTTP resources, producing mixed content. Browsers may upgrade some requests and block others; use the developer console to identify the actual failures. The Mozilla mixed content documentation describes these browser protections.
Test a realistic task rather than stopping at a successful page load. Submit a contact form, open a download, follow an internal link and visit a missing page. For an application, include a login and logout cycle with a test account.
Check redirect behavior in a fresh browser session as well. Previously cached redirects can make an old mistake appear fixed, or make a corrected setup appear broken.
Put an Application Behind Nginx
An application deployment needs more than a different document root. For an HTTP application server, Nginx forwards selected requests to a backend address. PHP applications commonly use a FastCGI connection to PHP-FPM instead. These connection types need different configuration.
For an HTTP backend, review the destination, request path handling and forwarded headers. Nginx changes some proxy headers by default, so the public host information should be an explicit decision. The Nginx reverse proxy reference documents these settings and the distinction between HTTP proxying and other upstream protocols.
Prefer a local socket or loopback listener when the application runs on the same machine. Avoid publishing the backend port just to make testing easier. Keep a documented method for testing the backend locally without bypassing the intended public access controls.
Configure the application to recognize the original scheme and client information only from trusted proxies. Review its allowed hostnames and public base address. If it repeatedly redirects an HTTPS visitor back to HTTPS, investigate how it detects secure requests before changing timeouts or certificate settings.
Give the application its own service account and startup configuration. Check what happens after a crash and after a server reboot. Keep databases, migration tools and background jobs within the application’s operating procedure rather than adding their responsibilities to Nginx.
If the backend runs in a container, review host port publishing and persistent data separately. The guide to Docker and Podman on Linux covers container concepts; do not assume a containerized service is private simply because it is inside a container.
Prove That Certificate Renewal Works
Certificate issuance is the first successful cycle, not the end of certificate management. Confirm that the installed renewal schedule exists, that validation still works, and that Nginx will use the replacement certificate.
Run the supported renewal simulation after setup and after changes to DNS, challenge routing or validation credentials. Check the scheduled task’s execution history as well. A successful manual test does not prove that an unattended task has the same environment and access.
Where you manage certificate installation yourself, arrange a validated reload after successful renewal. Certbot supports deployment hooks for this purpose, while manual validation needs automation before unattended renewal can work. The Certbot certificate management and renewal guide documents those distinctions.
Monitor the certificate actually served to visitors, not just a file on disk. Record the expected renewal method, alert destination and recovery steps. After a migration, check them again rather than assuming that copying the website also copied its automation.
Add Security Controls Without Breaking the Site
Build security around a small public surface: the required web ports, protected administration, controlled file access and maintained software. Keep deployment credentials separate from application credentials, and avoid using an administrator’s account as the application’s runtime identity.
For shared administration, assign access through named accounts and reviewed privileges. The guide to Linux users, groups and sudo access covers those controls without making every maintenance task a root login.
Consider HTTP Strict Transport Security only after HTTPS and renewal are dependable. HSTS tells browsers to use HTTPS for future connections; its subdomain option extends that policy to subdomains. Begin with a cautious policy and do not preload the domain casually. The Mozilla HSTS reference covers persistence, subdomain coverage and certificate error handling.
Treat other response headers as application decisions rather than a security checklist to paste wholesale. Test their effect on forms, embedded services and required scripts. Keep a record of why each restriction exists and how to verify it after an application update.
Troubleshoot the Failing Layer
Start with the observed failure and the request path. Check name resolution, connectivity, TLS, Nginx routing and the application in that order. Avoid changing several layers because the browser presents only one error message.
The Connection Times Out
Check the resolved address, listening interfaces, provider rules and host firewall. Compare an external request with a local request. If there is no matching access log entry, investigate whether the request reaches the intended Nginx instance before editing document paths.
The Wrong Site or Welcome Page Appears
Inspect enabled site definitions and hostname matching. Check that the new configuration was loaded and that DNS points to the expected server. Also consider a proxy cache or old deployment before deleting the packaged default configuration.
Nginx Returns a Forbidden or Missing Page
Check the document root, expected index file, directory access and security labels. Read the error associated with the request before changing permissions. A forbidden response is not an instruction to grant write access.
The Application Fails Behind the Proxy
Test the backend locally and review its service state. Verify the configured address or socket, the connection protocol and access controls. Investigate the application itself before extending proxy timeouts; a longer wait does not repair a stopped process.
Use request logs to connect the browser failure with the server event, then inspect service startup or runtime messages. The guide to troubleshooting services with journalctl covers the systemd side of that investigation.
Maintain a Website You Can Recover
Keep a short deployment record containing the active configuration locations, published content path, application services, certificate method, DNS account owner and recovery contact. Update it whenever the architecture changes.
Include Nginx, the operating system and the application runtime in a planned Linux security update process. After updates, verify the site and its dependencies rather than treating a successful package transaction as the final test.
Watch disk space, resource use, response failures and certificate expiry. Establish a normal baseline before changing worker settings or adding caching. The guide to monitoring Linux server resources helps separate capacity problems from configuration faults.
Back up the material needed to rebuild the service: configuration, published content, application data, database backups and required secrets. Protect sensitive backups and keep recovery access separate from the public server. Use offsite backups and recovery testing to verify that the saved material is usable.
Before calling the deployment complete, perform a controlled reboot and repeat the external checks. Confirm that Nginx starts, the application is available, HTTPS works, redirects behave correctly and renewal remains scheduled. The useful endpoint is not a homepage that loaded once. It is a website whose operation you can verify, maintain and restore.