aboutsummaryrefslogtreecommitdiff
path: root/content/blog/2024-04-08-docker-local-web-server.md
blob: e8925c7781e6c1680c25cc4c7c03731bbc60733c (plain) (blame)
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
+++
date = 2024-04-08
title = "Using Docker Desktop to Create a Development Web Server"
description = ""
draft = false
+++

When developing websites locally, I often use a simple Python web server
to observe the changes.

```sh
python3 -m http.server
```

However, this approach has its limitations. For example, this approach
does not enable logging or access controls. You also need to customize
`SimpleHTTPServer` if you have advanced needs from your web
server.

So, I went to find an alternative that is almost as easy and far more
extensible and found Docker Desktop to be a suitable replacement.

# Docker Desktop

## Installation

[Docker Desktop](https://www.docker.com/products/docker-desktop/) is a
desktop GUI for the phenomenal Docker container software. This allows
you to manage containers, images, volumes, environments, and extensions
via an easy-to-use GUI.

To install, open the link above and click the `Download`
button for your platform. I\'m going through this process on an M2
Macbook, so I downloaded the Mac - Apple Chip version.

Open the installer and follow the installation process until the
application finishes the installation process.

![Docker Desktop on
macOS](https://img.cleberg.net/blog/20240408-docker-local-web-server/docker-desktop.png)

## Creating an Nginx Container

I prefer to use the command line to create containers, so the following
commands will be input via the terminal.

The following command will create a container, using the
`nginx` image:

1.  `-d`: Run this container as a daemon (detach)
2.  `-p`: Allocate a port in the format
    `<external>:<internal>`
3.  `-i`: Keep STDIN open even if not attached
4.  `-t`: Allocate a pseudo-TTY
5.  `-p`: Allocate a port in the format
    `<external>:<internal>`
6.  `--rm`: Remove the container once it\'s done running

```sh
docker run -it --rm -d -p 8000:80 --name web nginx
```

You can navigate to <http://localhost:8000> to see the resulting page.

![Default Nginx
Container](https://img.cleberg.net/blog/20240408-docker-local-web-server/default-container.png)

## Customizing the Nginx Container

Now that I have a container running the Nginx web server, I need to link
some volumes so that I can modify the site configuration and provide the
web files to serve.

Let\'s start with the new command, which adds two volumes:

1.  `<your_content>:/usr/share/nginx/html`: This is the
    directory where you will provide the web pages for the server to
    serve.
2.  `<your_config>:/etc/nginx/conf.d/default.conf`: This is
    the Nginx configuration file for your site.

To see the updates, you can delete the previous container in the GUI or
run `docker stop web` to stop the container. Once stopped,
you can run the new `docker run` command below.

```sh
docker run -it -d -p 8000:80 --name web -v ~/Source/cleberg.net/.build:/usr/share/nginx/html -v ~/Source/cleberg.net/nginx-config.conf:/etc/nginx/conf.d/default.conf nginx
```

Here\'s an example of my development configuration file.

``` conf
# nginx-config.conf
server {
       server_name cleberg.net www.cleberg.net;

       root /usr/share/nginx/html;
       index index.html;
       autoindex on;

       access_log  /var/log/nginx/cleberg.net.access.log;
       error_log  /var/log/nginx/cleberg.net.error.log;

       location / {
                try_files $uri $uri/ =404;
       }

       listen [::]:80;
       listen 80;
}
```

![](https://img.cleberg.net/blog/20240408-docker-local-web-server/custom-container.png)

# Customizing Deployment Actions

I am currently blogging with [weblorg](https://emacs.love/weblorg/),
which uses a custom `publish.el` file to build the static
site. Within this file, I have configured my deployment process to check
for the `ENV` variable in thesh and if it\'s set to
`prod`, the script will set the base URLs to
`https://cleberg.net`. If not, it sets the base URLs to
`localhost:8000` (which matches the port used in the
container above).

Therefore, I have modified my `build.sh` script to build with
`localhost` URLs if `ENV` is not set to
`prod`. It also prevents the build process from sending the
built files to the production web server.

```sh
#!/bin/bash

if [ "$ENV" == "prod" ]; then
    echo "Environment = Production"              && \
    rm -rf .build/*                              && \
    emacs --script publish.el                    && \
    scp -r .build/* ubuntu:/var/www/cleberg.net/
else
    echo "Environment = Development"             && \
    rm -rf .build/*                              && \
    emacs --script publish.el
fi
```

You can modify the container in numerous ways and this approach allows
you to create complex scenarios for your web development purposes. I
highly recommend switching over to a container-based approach for
simple, local web development.