Background
A project includes a restaurant owner who wants to deploy our online ordering system with all his restaurants (total 8) to include online ordering features, currently, only a static page goldenthumb.com.hk is running (with https enabled), our target is to use a single AWS lightsail instance to serve for
1. Providing portal page (run by Gatsby JS), currently goldenthumb.com.hk, act as a portal page to allow user to quickly select different restaurants for ordering, reference site: https://www.maximsmx.com.hk/takeaway_promotion/?utm_source=eatizen
2. Use subdomain to distinguish different restaurants, e.g. lck.goldenthumb.com.hk is the ordering system of restaurant located at Lai Chi Kok
3. api.lck.goldenthumb.com.hk is the API URL served by loopback JS container to provide RESTful service to access database (mongoDB)'s data
4. Run in https and able to check and renew the cert automatically
5. Provide ftp access for the static goldenthumb.com.hk file updates for site maintenance
Problems
This project setup is very much similar to another post, but more complicated, as it includes 2 more containers, certbot and static portal page container which co-exists with the nginx, loopback, mongo express, mongoDB containers (the ordering web application formation) as well as the ftp container and another nginx container.
The following are the problems I have faced during the system configuration
1. The lck.goldenthumb.com.hk requests are not forwarded to the desired nginx container, showing "502 bad gateway"
Turns out I have wrongly restart the container that is never meant to be restarted, normally the static web container "goldenthumbStatic" is used as the main server to receive client requests, the proxy_server settings should be configured inside "goldenthumbStatic" as follows
server {
# Serving api url for internal use
server_name lck.goldenthumb.com.hk;
ssl_certificate /etc/letsencrypt/live/goldenthumb.com.hk/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/goldenthumb.com.hk/privkey.pem;
listen 80 ;
listen 443 ssl ;
# access_log /var/log/nginx/access.loopback.log;
# We redirect all outside request to appropriate loopback container
location / {
proxy_pass http://lck.goldenthumb.com.hk;
}
location /admin {
proxy_pass http://lck.goldenthumb.com.hk;
try_files $uri /index.html;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
The location / block is important, it tells the server when request comes as "lck.goldenthumb.com.hk", then forward the request to server block "http://lck.goldenthumb.com.hk", which is defined below
# Groups of server for proxy_pass usage in below server block
upstream lck.goldenthumb.com.hk {
# We put docker container service name (internal docker IP) for pointing to right API server (8082:80)
server frontend;
}
Here the upstream block is used to define blocks of server(s) for reference of proxy_pass directives, the value in proxy_pass is related to this upstream block and forward the request to frontend.
Although configurated correctly, I keep restarting the wrong docker container which the settings are therefore yet to apply
2. The api.lck.goldenthumb.com.hk requests are not forwarded to the desired loopback container, showing "Connection refused"
This is turn out a silly mistake which forgot to update loopback configuration file (config.json), 80 port should be configured to accept the API connections from other containers
3. The admin management page lck.goldenthumb.com.hk/admin is not working, showing "Connection refused"
The nginx conf is not configured correctly, below is the corrected config, the "try_files" is important to guide nginx server to query original index.html when api.lck.goldenthumb.com.hk/admin is navigated, and let react route to handle the rest of the routing tasks instead of the server itself
location /admin {
proxy_pass http://lck.goldenthumb.com.hk;
try_files $uri /index.html;
}
4. The APIs used in admin page all fired as "lck.goldenthumb.com.hk/xxx" which is different from expected "api.lck.goldenthumb.com.hk/xxx"
This is due to the wrongly configured dockerfile setup, missing a step to copy the compiled js files to the production docker container, causing the updated code not reflecting the changes.
5. The https certbot challenges for multiple subdomains
HTTPS needs to apply for every sub-domain, lck.goldenthumb.com.hk, api.lck.goldenthumb.com.hk needs to be applied separately, update the certbot script (init-letsencrypt.sh) first, with domain marked to all desired sub-domains
domains=(goldenthumb.com.hk www.goldenthumb.com.hk lck.goldenthumb.com.hk api.lck.goldenthumb.com.hk)
Then in docker compose file, configure the all container volumes which need https certificates by adding /var/www/certbot to accept the challenges
./app/certbot/www:/var/www/certbot