content/blog/2024-04-08-docker-local-web-server.org

0b2895a90c7751ce06e4b26d4db41005ea2f40a9
cleberg.net/content/blog/2024-04-08-docker-local-web-server.org rendered · source · history · blame · raw

137 lines · 5142 bytes

  1#+date:        <2024-04-08 Mon 00:00:00>
  2#+title:       Configuration Procedure for Local Web Development Server Using Docker Desktop
  3#+description: Instructions for setting up a local web development environment employing Docker Desktop and Nginx web server to facilitate development and testing workflows.
  4#+slug:        docker-local-web-server
  5#+filetags:    :docker:nginx:webserver:
  6
  7When developing websites locally, I often use a simple Python web server to
  8observe the changes.
  9
 10#+begin_src sh
 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 sh
 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 sh
 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 thesh and if it's set to =prod=, the script
113will set the base URLs to =https://cleberg.net=. If not, it sets the base URLs
114to =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 sh
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.