Helicopter View: Mixing Docker and Non-Docker Deployments
Let's linked LinkedIn


Helicopter View: Server Setup

You have an existing production setup where Nginx is serving a Hugo static site, and you want to deploy future applications (like Flask) using Docker containers. Here’s why and how this approach works, giving you flexibility, isolation, and scalability while maintaining your current architecture.

Why This Approach Works

The key idea is that Nginx serves as a reverse proxy, which allows it to route incoming traffic to different applications based on the URL path or subdomain. By running Hugo without Docker and newer applications (like Flask) inside Docker containers, you can keep your existing infrastructure intact while scaling with Dockerized apps.

Core Concepts

  1. Reverse Proxy: Nginx can act as a reverse proxy, meaning it can accept client requests (e.g., visiting a website) and forward those requests to different services (e.g., Flask apps running inside Docker, static files from Hugo). This is done based on the request URL path (like /hello-world) or even different subdomains (like app.rinji.id).

  2. Port Isolation with Docker: Each Docker container runs its services on a specific port (e.g., Flask on port 8000 inside the container). Docker containers are isolated, meaning that each application has its own dependencies and environment without affecting others. Nginx can proxy requests to these containers by directing traffic to the correct port.

  3. Retaining Non-Docker Hugo Site: Since Hugo is a static site, Nginx can continue serving it directly from the file system. This allows you to maintain your existing production Hugo site while integrating newer Dockerized applications.

  4. Gradual Transition: You’re not required to move everything to Docker. You can keep Hugo as it is and only deploy future apps using Docker, creating a mixed environment that gives you flexibility as your needs evolve.


Detailed Breakdown of Why This Approach Works

1. Nginx as a Reverse Proxy

  • Reverse Proxy Role: Nginx listens for incoming HTTP requests and forwards them to the correct application. This could be the Hugo site (served directly from the file system) or Docker containers running different apps. The routing is done based on the request path (e.g., /hello-world for your Flask app).

  • How it Works:

    • Hugo: Nginx serves static files directly from /var/www/html (your Hugo site).
    • Flask in Docker: Nginx proxies requests that start with /hello-world to the Flask app running inside a Docker container on port 8000.
  • Traffic Routing:

    • Nginx will continue serving Hugo when someone visits https://rinji.id.
    • When a user accesses https://rinji.id/hello-world, Nginx forwards that request to your Flask app running inside a Docker container.

2. Port Isolation in Docker

  • Why Use Docker: Docker containers isolate applications in their own environment. This is particularly useful for newer apps like Flask, which may have different dependencies or runtime requirements than Hugo.

  • Port Mapping: Each Docker container runs on its own isolated port (e.g., Flask runs on port 8000 inside the container). Docker makes it easy to manage these ports without conflicting with other applications on your server.

  • How Nginx Handles Docker Ports:

    • Nginx will route requests that come to /hello-world to the Flask Docker container running on port 8000.
    • You can run multiple containers on different ports (e.g., Flask on 8000, another app on 8001) and have Nginx proxy requests accordingly.

3. Keeping the Existing Hugo Site Untouched

  • Why Not Dockerize Hugo?: Since Hugo is a static site, there’s no need to Dockerize it unless you want to. Nginx can directly serve Hugo files from the file system, keeping the setup simple.

  • File System Access: Hugo’s static files are served directly by Nginx from /var/www/html, meaning there’s no need for Docker overhead when serving these files. This setup stays the same as it is now.

  • Hugo Stays as-is: No changes are needed to the current Hugo setup. It continues to serve your static site as usual, while newer apps can be deployed in Docker containers.

4. Gradual Migration and Scalability

  • No Immediate Overhaul: You don’t have to convert your entire production environment to Docker overnight. You can continue using the same Nginx and Hugo setup, adding Docker only for newer applications. This provides flexibility and reduces the risk of downtime.

  • Future-proofing: Over time, if you decide to move more apps to Docker, you can do so incrementally. New apps will run in isolated containers, keeping them separate from each other and from Hugo.

  • Scalability: With Docker, it’s easy to scale individual apps by increasing the number of containers for that app. You can run multiple instances of your Flask app in different containers, with Nginx load balancing between them.

5. SSL and Security

  • Let’s Encrypt: You can use Let’s Encrypt with Nginx to secure both your Hugo site and your Dockerized apps with SSL certificates.

  • Nginx Manages SSL: Since Nginx is the entry point for all traffic, you can easily configure SSL at the Nginx level. This means both https://rinji.id and https://rinji.id/hello-world can be secured with SSL, even though one is static (Hugo) and the other is dynamic (Flask in Docker).


Step-by-Step Process for Deploying Using This Approach

1. Keep Hugo as it is

Your existing Hugo setup stays untouched, and Nginx continues serving static files from /var/www/html. No changes are required for this part of the deployment.

2. Deploy Flask App in Docker

  1. Create and Build Docker Container:

    • Build the Flask app Docker image on your server.
    • Run the Flask app in a Docker container, mapping the app to port 8000 (or any other available port).
  2. Configure Nginx:

    • Modify Nginx to route requests for /hello-world to the Flask Docker container.
    • This way, https://rinji.id/hello-world will point to your Flask app running in Docker.

3. Manage Nginx for Both

  • Serve Hugo at the root (/): No changes are needed for this part. Nginx will continue to serve your static Hugo site at https://rinji.id.
  • Serve Dockerized Apps at different paths (e.g., /hello-world, /another-app): Nginx will proxy these requests to Docker containers running the apps.

4. Optional Future Apps in Docker

As you build new apps, you can continue to use Docker for each of them. Each app will be isolated in its own Docker container, and Nginx will proxy requests to the appropriate container based on the path.

5. Mixed SSL Configuration

Using Let’s Encrypt, you can easily secure both the Hugo site and the Flask app running in Docker. Since Nginx is handling all the traffic, it will also handle SSL certificates for both parts of your setup.


Benefits of This Approach

  1. Isolation: Docker allows you to isolate each application, keeping dependencies and environments separate. This avoids conflicts between your Hugo site and new apps (like Flask) that may have different requirements.

  2. Flexibility: You don’t have to overhaul your current setup. Hugo can stay as it is, while you gradually introduce Docker for future applications. This minimizes risk and downtime.

  3. Scalability: Docker makes it easy to scale applications. You can run multiple instances of your Flask app or other apps if needed, and Nginx can load balance between them.

  4. Maintainability: This approach gives you a clean, manageable deployment strategy. Your static Hugo site remains simple, while Docker manages more complex apps. Over time, you can transition other parts of your infrastructure to Docker if it becomes necessary.

  5. Security: Nginx handles SSL for all apps (whether they’re running in Docker or not), ensuring secure connections.


Conclusion

By using a combination of Nginx for reverse proxy and Docker for future app deployment, you gain flexibility, isolation, and scalability without disrupting your existing Hugo site. Nginx serves static Hugo content directly, while forwarding requests to Docker containers for dynamic applications. This mixed environment allows you to scale smoothly as you deploy new applications.