Commit d67c36e5d6

d67c36e5d61790b5d53a841b2bd27519b333c24b

parent: 580d2d6a33

Unsigned

cmc <hello@cleberg.net> · 2024-04-08 16:20 UTC

add docker local web server post

Layout: unified · split

content/blog/2024-04-08-docker-local-web-server.org added +137
@@ -0,0 +1,137 @@
1#+title: Using Docker Desktop to Create a Development Web Server
2#+date: <2024-04-08 Mon 10:05:45>
3#+description: Learn how to launch local web servers with Docker Desktop.
4#+filetags: dev, nginx
5#+slug: docker-local-web-server
6
7When developing websites locally, I often use a simple Python web server to
8observe the changes.
9
10#+begin_src shell
11python3 -m http.server
12#+end_src
13
14However, this approach has its limitations. For example, this approach does not
15enable logging or access controls. You also need to customize =SimpleHTTPServer=
16if you have advanced needs from your web server.
17
18So, I went to find an alternative that is almost as easy and far more extensible
19and found Docker Desktop to be a suitable replacement.
20
21* Docker Desktop
22
23** Installation
24
25[[https://www.docker.com/products/docker-desktop/][Docker Desktop]] is a desktop GUI for the phenomenal Docker container software.
26This allows you to manage containers, images, volumes, environments, and
27extensions via an easy-to-use GUI.
28
29To install, open the link above and click the =Download= button for your
30platform. I'm going through this process on an M2 Macbook, so I downloaded the
31Mac - Apple Chip version.
32
33Open the installer and follow the installation process until the application
34finishes the installation process.
35
36#+caption: Docker Desktop on macOS
37[[https://img.cleberg.net/blog/20240408-docker-local-web-server/docker-desktop.png]]
38
39** Creating an Nginx Container
40
41I prefer to use the command line to create containers, so the following commands
42will be input via the terminal.
43
44The following command will create a container, using the =nginx= image:
45
461. =-d=: Run this container as a daemon (detach)
472. =-p=: Allocate a port in the format =<external>:<internal>=
483. =-i=: Keep STDIN open even if not attached
494. =-t=: Allocate a pseudo-TTY
505. =-p=: Allocate a port in the format =<external>:<internal>=
516. =--rm=: Remove the container once it's done running
52
53#+begin_src shell
54docker run -it --rm -d -p 8000:80 --name web nginx
55#+end_src
56
57You can navigate to [[http://localhost:8000]] to see the resulting page.
58
59#+caption: Default Nginx Container
60[[https://img.cleberg.net/blog/20240408-docker-local-web-server/default-container.png]]
61
62** Customizing the Nginx Container
63
64Now that I have a container running the Nginx web server, I need to link some
65volumes so that I can modify the site configuration and provide the web files to
66serve.
67
68Let's start with the new command, which adds two volumes:
69
701. =<your_content>:/usr/share/nginx/html=: This is the directory where you will
71 provide the web pages for the server to serve.
722. =<your_config>:/etc/nginx/conf.d/default.conf=: This is the Nginx
73 configuration file for your site.
74
75To see the updates, you can delete the previous container in the GUI or run
76=docker stop web= to stop the container. Once stopped, you can run the new
77=docker run= command below.
78
79#+begin_src shell
80docker 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
81#+end_src
82
83Here's an example of my development configuration file.
84
85#+begin_src conf
86# nginx-config.conf
87server {
88 server_name cleberg.net www.cleberg.net;
89
90 root /usr/share/nginx/html;
91 index index.html;
92 autoindex on;
93
94 access_log /var/log/nginx/cleberg.net.access.log;
95 error_log /var/log/nginx/cleberg.net.error.log;
96
97 location / {
98 try_files $uri $uri/ =404;
99 }
100
101 listen [::]:80;
102 listen 80;
103}
104#+end_src
105
106[[https://img.cleberg.net/blog/20240408-docker-local-web-server/custom-container.png]]
107
108* Customizing Deployment Actions
109
110I am currently blogging with [[https://emacs.love/weblorg/][weblorg]], which uses a custom =publish.el= file to
111build the static site. Within this file, I have configured my deployment process
112to check for the =ENV= variable in the shell and if it's set to =prod=, the
113script will set the base URLs to =https://cleberg.net=. If not, it sets the base
114URLs to =localhost:8000= (which matches the port used in the container above).
115
116Therefore, I have modified my =build.sh= script to build with =localhost= URLs
117if =ENV= is not set to =prod=. It also prevents the build process from sending
118the built files to the production web server.
119
120#+begin_src shell
121#!/bin/bash
122
123if [ "$ENV" == "prod" ]; then
124 echo "Environment = Production" && \
125 rm -rf .build/* && \
126 emacs --script publish.el && \
127 scp -r .build/* ubuntu:/var/www/cleberg.net/
128else
129 echo "Environment = Development" && \
130 rm -rf .build/* && \
131 emacs --script publish.el
132fi
133#+end_src
134
135You can modify the container in numerous ways and this approach allows you to
136create complex scenarios for your web development purposes. I highly recommend
137switching over to a container-based approach for simple, local web development.