summaryrefslogtreecommitdiff
path: root/live/blog/a/website_with_nginx.html
blob: 5c50c4f2b0615aa09c20f790542ea32d9f230239 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
<!DOCTYPE html>
<html class="theme-dark" lang="en
"
  prefix="og: https://ogp.me/ns#">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="icon" href="https://static.luevano.xyz/images/icons/favicon.ico">
<title>Set up a website with Nginx and Certbot -- Luévano's Blog</title>
  <meta name="description" content="How to set up a website using Nginx for web server and Certbot for SSL certificates, on Arch. This is a base for future blog posts about similar topics."/>
<link rel="alternate" type="application/rss+xml" href="https://blog.luevano.xyz/rss.xml" title="Luévano's Blog RSS">
    <!-- general style -->
    <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/css/style.css">
    <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/fork-awesome/css/fork-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="https://static.luevano.xyz/font-awesome/css/all.min.css">
    <!-- theme related -->
    <script type="text/javascript" src="https://static.luevano.xyz/scripts/theme.js"></script>
    <link id="theme-css" rel="stylesheet" type="text/css" href="https://static.luevano.xyz/css/theme.css">
    <!-- misc functions-->
    <script type="text/javascript" src="https://static.luevano.xyz/scripts/return_top.js"></script>
    <!-- extra -->
    <!-- highlight support for code blocks -->
<script type="text/javascript" src="https://static.luevano.xyz/hl/highlight.min.js"></script>
<script type="text/javascript">
  hljs.initHighlightingOnLoad();
</script>
<link id="code-theme-css" rel="stylesheet" type="text/css" href="https://static.luevano.xyz/hl/styles/nord.min.css">






    <!-- og meta -->
  <meta property="og:title" content="Set up a website with Nginx and Certbot -- Luévano's Blog"/>
  <meta property="og:type" content="article"/>
  <meta property="og:url" content="https://blog.luevano.xyz/a/website_with_nginx.md"/>
  <meta property="og:image" content="https://static.luevano.xyz/images/b/default.png"/>
  <meta property="og:description" content="How to set up a website using Nginx for web server and Certbot for SSL certificates, on Arch. This is a base for future blog posts about similar topics."/>
  <meta property="og:locale" content="en"/>
  <meta property="og:site_name" content="Luévano's Blog"/>
  </head>

  <body>
    <header>
<nav>
  <ul>
    <li>
      <a href="https://luevano.xyz/"><i class="fas fa-home" alt="Home"></i><span>Home</span></a>
    </li>

    <li>
      <a href="https://blog.luevano.xyz/"><i class="fas fa-book-open" alt="Blog"></i><span>Blog</span></a>
    </li>

    <li>
      <a href="https://art.luevano.xyz/"><i class="fas fa-paint-brush" alt="Art"></i><span>Art</span></a>
    </li>

    <li><i class="fab fa-git" alt="Git"></i><span>Git</span>
      <ul>
        <li><a href="https://git.luevano.xyz/" target="_blank"><i class="fab fa-git-alt" alt="Git-alt"></i></a></li>

        <li><a href="https://github.com/luevano" target="_blank"><i class="fab fa-github" alt="Github"></i></a></li>

        <li><a href="https://gitlab.com/dluevano" target="_blank"><i class="fab fa-gitlab" alt="Gitlab"></i></a></li>
      </ul>
    </li>

    <li><i class="fas fa-box-open" alt="Stuff"></i><span>Stuff</span>
      <ul>
        <li><a href="https://gb.luevano.xyz/"><i class="fas fa-gamepad" alt="Gameboy"></i><span>Gameboy</span></a></li>
      </ul>
    </li>
  </ul>
</nav>

<button class="theme-switcher" onclick="toggleTheme()"><i class="fas fa-moon"></i><i class="fas fa-sun"></i></button>

    </header>

    <main>
      <div class="return-top">
        <button class="return-top" onclick="returnTop()" id="returnTopButton">
        <i class="fas fa-arrow-up" alt="Return to top"></i>
        </button>
      </div>
  <h1>Set up a website with Nginx and Certbot</h1>

  <p>These are general notes on how to setup a Nginx web server plus Certbot for SSL certificates, initially learned from <a href="https://www.youtube.com/watch?v=OWAqilIVNgE">Luke&rsquo;s video</a> and after some use and research I added more stuff to the mix. And, actually at the time of writing this entry, I&rsquo;m configuring the web server again on a new VPS instance, so this is going to be fresh.</p>
<p>As a side note, <mark>i use arch btw</mark> so everything here es aimed at an Arch Linux distro, and I&rsquo;m doing everything on a VPS. Also note that most if not all commands here are executed with root privileges.</p>
<h2 id="table-of-contents">Table of contents<a class="headerlink" href="#table-of-contents" title="Permanent link">&para;</a></h2>
<div class="toc">
<ul>
<li><a href="#table-of-contents">Table of contents</a></li>
<li><a href="#prerequisites">Prerequisites</a></li>
<li><a href="#nginx">Nginx</a></li>
<li><a href="#certbot">Certbot</a></li>
</ul>
</div>
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">&para;</a></h2>
<p>You will need two things:</p>
<ul>
<li>A domain name (duh!). I got mine on <a href="https://www.epik.com/?affid=da5ne9ru4">Epik</a> (affiliate link, btw).<ul>
<li>With the corresponding <strong>A</strong> and <strong>AAA</strong> records pointing to the VPS&rsquo; IPs. I have three records for each type: empty string, &ldquo;www&rdquo; and &ldquo;*&rdquo; for a wildcard, that way &ldquo;domain.name&rdquo;, &ldquo;www.domain.name&rdquo;, &ldquo;anythingelse.domain.name&rdquo; point to the same VPS (meaning that you can have several VPS for different sub-domains). These depend on the VPS provider.</li>
</ul>
</li>
<li>A VPS or somewhere else to host it. I&rsquo;m using <a href="https://www.vultr.com/?ref=8732849">Vultr</a> (also an affiliate link, btw).<ul>
<li>With <code>ssh</code> already configured both on the local machine and on the remote machine.</li>
<li>Firewall already configured to allow ports <code>80</code> (HTTP) and <code>443</code> (HTTPS). I use <code>ufw</code> so it&rsquo;s just a matter of doing <code>ufw allow 80,443/tcp</code> (for example) as root and you&rsquo;re golden.</li>
<li><code>cron</code> installed if you follow along (you could use <code>systemd</code> timers, or some other method you prefer to automate running commands every certain time).</li>
</ul>
</li>
</ul>
<h2 id="nginx">Nginx<a class="headerlink" href="#nginx" title="Permanent link">&para;</a></h2>
<p><a href="https://wiki.archlinux.org/title/Nginx">Nginx</a> is a web (HTTP) server and reverse proxy server.</p>
<p>You have two options: <code>nginx</code> and <code>nginx-mainline</code>. I prefer <code>nginx-mainline</code> because it&rsquo;s the &ldquo;up to date&rdquo; package even though <code>nginx</code> is labeled to be the &ldquo;stable&rdquo; version. Install the package and enable/start the service:</p>
<pre><code class="language-sh">pacman -S nginx-mainline
systemctl enable nginx.service
systemctl start nginx.service
</code></pre>
<p>And that&rsquo;s it, at this point you can already look at the default initial page of Nginx if you enter the IP of your server in a web browser. You should see something like this:</p>
<figure id="__yafg-figure-3">
<img alt="Nginx welcome page" src="https://static.luevano.xyz/images/b/nginx/nginx_welcome_page.png" title="Nginx welcome page">
<figcaption>Nginx welcome page</figcaption>
</figure>
<p>As stated in the welcome page, configuration is needed, head to the directory of Nginx:</p>
<pre><code class="language-sh">cd /etc/nginx
</code></pre>
<p>Here you have several files, the important one is <code>nginx.conf</code>, which as its name implies, contains general configuration of the web server. If you peek into the file, you will see that it contains around 120 lines, most of which are commented out and contains the welcome page server block. While you can configure a website in this file, it&rsquo;s common practice to do it on a separate file (so you can scale really easily if needed for mor websites or sub-domains).</p>
<p>Inside the <code>nginx.conf</code> file, delete the <code>server</code> blocks and add the lines <code>include sites-enabled/*;</code> (to look into individual server configuration files) and <code>types_hash_max_size 4096;</code> (to get rid of an ugly warning that will keep appearing) somewhere inside the <code>http</code> block. The final <code>nginx.conf</code> file would look something like (ignoring the comments just for clarity, but you can keep them as side notes):</p>
<pre><code class="language-nginx">worker_processes 1;

events {
    worker_connections 1024;
}

http {
    include sites-enabled/*;
    include mime.types;
    default_type application/octet-stream;

    sendfile on;

    keepalive_timeout 65;

    types_hash_max_size 4096;
}
</code></pre>
<p>Next, inside the directory <code>/etc/nginx/</code> create the <code>sites-available</code> and <code>sites-enabled</code> directories, and go into the <code>sites-available</code> one:</p>
<pre><code class="language-sh">mkdir sites-available
mkdir sites-enabled
cd sites-available
</code></pre>
<p>Here, create a new <code>.conf</code> file for your website and add the following lines (this is just the sample content more or less):</p>
<pre><code class="language-nginx">server {
    listen 80;
    listen [::]:80;

    root /path/to/root/directory;
    server_name domain.name another.domain.name;
    index index.html anotherindex.otherextension;

    location /{
        try_files $uri $uri/ =404;
    }
}
</code></pre>
<p>That could serve as a template if you intend to add more domains.</p>
<p>Note some things:</p>
<ul>
<li><code>listen</code>: we&rsquo;re telling Nginx which port to listen to (IPv4 and IPv6, respectively).</li>
<li><code>root</code>: the root directory of where the website files (<code>.html</code>, <code>.css</code>, <code>.js</code>, etc. files) are located. I followed Luke&rsquo;s directory path <code>/var/www/some_folder</code>.</li>
<li><code>server_name</code>: the actual domain to &ldquo;listen&rdquo; to (for my website it is: <code>server_name luevano.xyz www.luevano.xyz;</code> and for this blog is: <code>server_name blog.luevano.xyz www.blog.luevano.xyz;</code>).</li>
<li><code>index</code>: what file to serve as the index (could be any <code>.html</code>, <code>.htm</code>, <code>.php</code>, etc. file) when just entering the website.</li>
<li><code>location</code>: what goes after <code>domain.name</code>, used in case of different configurations depending on the URL paths (deny access on <code>/private</code>, make a proxy on <code>/proxy</code>, etc).<ul>
<li><code>try_files</code>: tells what files to look for.</li>
</ul>
</li>
</ul>
<p>Then, make a symbolic link from this configuration file to the <code>sites-enabled</code> directory:</p>
<pre><code class="language-sh">ln -s /etc/nginx/sites-available/your_config_file.conf /etc/nginx/sites-enabled
</code></pre>
<p>This is so the <code>nginx.conf</code> file can look up the newly created server configuration. With this method of having each server configuration file separate you can easily &ldquo;deactivate&rdquo; any website by just deleting the symbolic link in <code>sites-enabled</code> and you&rsquo;re good, or just add new configuration files and keep everything nice and tidy.</p>
<p>All you have to do now is restart (or enable and start if you haven&rsquo;t already) the Nginx service (and optionally test the configuration):</p>
<pre><code class="language-sh">nginx -t
systemctl restart nginx
</code></pre>
<p>If everything goes correctly, you can now go to your website by typing <code>domain.name</code> on a web browser. But you will see a &ldquo;404 Not Found&rdquo; page like the following (maybe with different Nginx version):</p>
<figure id="__yafg-figure-4">
<img alt="Nginx 404 Not Found page" src="https://static.luevano.xyz/images/b/nginx/nginx_404_page.png" title="Nginx 404 Not Found page">
<figcaption>Nginx 404 Not Found page</figcaption>
</figure>
<p>That&rsquo;s no problem, because it means that the web server it&rsquo;s actually working. Just add an <code>index.html</code> file with something simple to see it in action (in the <code>/var/www/some_folder</code> that you decided upon). If you keep seeing the 404 page make sure your <code>root</code> line is correct and that the directory/index file exists.</p>
<p>I like to remove the <code>.html</code> and trailing <code>/</code> on the URLs of my website, for that you need to add the following <code>rewrite</code> lines and modify the <code>try_files</code> line (for more: <a href="https://www.seancdavis.com/blog/remove-html-extension-and-trailing-slash-in-nginx-config/">Sean C. Davis: Remove HTML Extension And Trailing Slash In Nginx Config</a>):</p>
<pre><code class="language-nginx">server {
    ...
    rewrite ^(/.*)\.html(\?.*)?$ $1$2 permanent;
    rewrite ^/(.*)/$ /$1 permanent;
    ...
    try_files $uri/index.html $uri.html $uri/ $uri =404;
    ...
</code></pre>
<h2 id="certbot">Certbot<a class="headerlink" href="#certbot" title="Permanent link">&para;</a></h2>
<p><a href="https://wiki.archlinux.org/title/Certbot">Certbot</a> is what provides the SSL certificates via <a href="https://letsencrypt.org/">Let&rsquo;s Encrypt</a>.</p>
<p>The only &ldquo;bad&rdquo; (bloated) thing about Certbot, is that it uses <code>python</code>, but for me it doesn&rsquo;t matter too much. You may want to look up another alternative if you prefer. Install the packages <code>certbot</code> and <code>certbot-nginx</code>:</p>
<pre><code class="language-sh">pacman -S certbot certbot-nginx
</code></pre>
<p>After that, all you have to do now is run <code>certbot</code> and follow the instructions given by the tool:</p>
<pre><code class="language-sh">certbot --nginx
</code></pre>
<p>It will ask you for some information, for you to accept some agreements and the names to activate HTTPS for. Also, you will want to &ldquo;say yes&rdquo; to the redirection from HTTP to HTTPS. And that&rsquo;s it, you can now go to your website and see that you have HTTPS active.</p>
<p>Now, the certificate given by <code>certbot</code> expires every 3 months or something like that, so you want to renew this certificate every once in a while. I did this before using <code>cron</code> or manually creating a <code>systemd</code> timer and service, but now it&rsquo;s just a matter of enabling the <code>certbot-renew.timer</code>:</p>
<pre><code class="language-sh">systemctl start certbot-renew.timer
</code></pre>
<p>The <code>deploy-hook</code> is not needed anymore, only for plugins. For more, visit the <a href="https://wiki.archlinux.org/title/Certbot#Automatic_renewal">Arch Linux Wiki</a>.</p>

  <div class="page-nav">
    <span class="next">
      <a href="https://blog.luevano.xyz/a/mail_server_with_postfix.html" alt="Next">
        <i class="fas fa-arrow-left" alt="Arrow left"></i>
        <span>Next</span>
      </a>
    </span>

    <span class="index">
      <a href="https://blog.luevano.xyz" alt="Index">
        <i class="fas fa-home" alt="Home"></i>
        <span>Index</span>
      </a>
    </span>

    <span class="previous">
      <a href="https://blog.luevano.xyz/a/el_blog_ya_tiene_timestamps.html" alt="Previous">
        <i class="fas fa-arrow-right" alt="Arrow right"></i>
        <span>Previous</span>
      </a>
    </span>
</div>


  <hr>
  <div class="article-info">
    <p>By David Luévano</p>
    <p>Created: Fri, Mar 19, 2021 @ 02:58 UTC</p>
      <p>Modified: Wed, Jun 21, 2023 @ 00:18 UTC</p>
    <div class="article-tags">
  <p>Tags:
<a href="https://blog.luevano.xyz/tag/@code.html">code</a>, <a href="https://blog.luevano.xyz/tag/@english.html">english</a>, <a href="https://blog.luevano.xyz/tag/@server.html">server</a>, <a href="https://blog.luevano.xyz/tag/@tools.html">tools</a>, <a href="https://blog.luevano.xyz/tag/@tutorial.html">tutorial</a>  </p>
</div>

  </div>
    </main>

    <footer>
<span>
  <i class="fas fa-address-card" alt="Contact"></i>
  <a href="https://blog.luevano.xyz/contact.html">Contact</a>
</span>

<span>
  <i class="fas fa-donate" alt="Donate"></i>
  <a href="https://blog.luevano.xyz/donate.html">Donate</a>
</span>

<span>
  <i class="fas fa-rss" alt="RSS"></i>
  <a target="_blank" href="https://blog.luevano.xyz/rss.xml">RSS</a>
</span>

<br>
<span class="created-with">
  <i class="fas fa-hammer" alt="Hammer"></i>
  Created with <a href="https://github.com/luevano/pyssg">pyssg</a>
</span>

<br>
<span class="copyright">
  Copyright <i class="far fa-copyright" alt="Copyright"></i> 2023 David Luévano Alvarado
</span>

    </footer>
  </body>
</html>