---
title: "Auto-Renewing Let's Encrypt HTTPS Certificates with nginx-certbot on QNAP Container Station"
description: "How to set up an nginx-certbot container on QNAP NAS Container Station to automatically check and renew free Let's Encrypt HTTPS certificates every week."
canonical_url: "https://blog.markkulab.net/en/post/nginx-certbot"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/en/author/mark-ku"
site: "Mark Ku's Tech Notes"
date_published: "2022-01-24 01:01:01 +0800"
category: "Infra"
tags: ["nginx", "certbot", "https", "letsencrypt", "docker", "qnap", "infra", "ssl"]
language: "en"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "when reusing or quoting, credit the author and link back to the original"
---

# Auto-Renewing Let's Encrypt HTTPS Certificates with nginx-certbot on QNAP Container Station

## Problem

[I previously used Windows Certbot](https://blog.markkulab.net/2021/12/26/ssl-certbot/) to obtain a free HTTPS certificate, but it had to be renewed manually every three months — which was tedious. The nginx-certbot Docker container solves this by renewing the certificate automatically.

## Environment

- QNAP TS-253D running Container Station

## Installation

### 1. Create > Search for "staticfloat/nginx-certbot" on Docker Hub > Install

![QNAP Container Station displaying staticfloat/nginx-certbot Docker image for ins](https://blog.markkulab.net/content/markku/posts/nginx-certbot/images/t7W0TX1.png)

### 2. Mount the following folders (Docker Volumes)

| Purpose | NAS path | Container path |
| -------- | -------- | -------- |
| nginx config files     | /share/Container/data/proxy-protocol   | /etc/nginx/conf.d      |
| Let's Encrypt logs | /share/Container/data/proxy-protocol/log  | /var/log/letsencrypt |
| Existing Let's Encrypt certificate directory     | Container/data/proxy-protocol/letsencrypt| /etc/letsencrypt   |
| nginx web root  | /usr/share/nginx/html | Container/data/proxy-Container/data/proxy-protocol/web  |

![QNAP Container Station UI showing container creation with Let's Encrypt director](https://blog.markkulab.net/content/markku/posts/nginx-certbot/images/z8q03u2.jpg)

### 3. Set environment variables

`CERTBOT_EMAIL` — the email address you used when originally requesting the HTTPS certificate.

![QNAP Container Station creating container with Certbot email variable](https://blog.markkulab.net/content/markku/posts/nginx-certbot/images/sPLMPLG.png)

### 4. Copy your existing certificate to the designated path

![Windows File Explorer showing Let's Encrypt certificate files for www.letgo.com.](https://blog.markkulab.net/content/markku/posts/nginx-certbot/images/ZMFyy5i.png)

### 5. Write the nginx config file

```
upstream frp {
	server 34.80.106.95:80;  # 这个是frp_server的内网ip和http监听端口
}

server
	{
	
	listen 443 ssl http2 proxy_protocol;
	listen [::]:443 ssl http2;
	server_name www.letgo.com.tw; # local server ip

	set_real_ip_from 172.31.0.1; # frp client ip
	real_ip_recursive on;
	real_ip_header  proxy_protocol;


	    ssl_certificate     /etc/letsencrypt/live/www.letgo.com.tw/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.letgo.com.tw/privkey.pem;
	
	ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;

	ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
	ssl_prefer_server_ciphers on;
	ssl_session_cache shared:SSL:10m;
	ssl_session_timeout 10m;
	add_header Strict-Transport-Security "max-age=31536000";	

	location / {
		proxy_set_header Host $host;
		proxy_set_header X-Real-IP $remote_addr;
		proxy_set_header X-Forwarded-For $proxy_protocol_addr;		
		proxy_set_header X-Forwarded-Proto $scheme;
		proxy_pass http://192.168.50.52:8890/; # your local application ip
	}
}
```
![QNAP Container Station proxy-protocol folder with letsencrypt and nginx.conf](https://blog.markkulab.net/content/markku/posts/nginx-certbot/images/7eMOn4S.png)

### 6. Start the container — it will check weekly and automatically renew your free HTTPS certificate.

## Notes

- Do not delete the `letsencrypt` folder; doing so will cause the next renewal to fail.
- My network setup uses frp. Since frp cannot distinguish between HTTP and HTTPS and automatically upgrades to HTTPS, I handled the initial HTTP-01 challenge by temporarily routing traffic through IIS for verification.

---

## About this article and its author

Originally published on [Mark Ku's Tech Notes](https://blog.markkulab.net/en/post/nginx-certbot)

License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — when reusing or quoting, credit the author and link back to the original

### About the author

**[Mark Ku](https://blog.markkulab.net/en/author/mark-ku)** — Software Solution Provider

- 10+ years senior software engineer, now an AI Builder
- Focused on large-platform architecture — North-American e-commerce, AI SaaS subscription billing
- Combining AI Agents and automation to build evolvable product foundations

### Free tools built by the author

All of these are free to use:

- [Free PDF Sign Tool](https://blog.markkulab.net/en/tools/pdf-sign): Online PDF sign tool — draw, type, or upload a signature, then drag, resize, and download. Everything runs in your browser; nothing is uploaded.
- [VS Code Refactory](https://blog.markkulab.net/en/tools/refactory): Refactory is a VS Code refactoring extension: 34 actions plus a 37-rule code-smell inspection layer with a Code Health dashboard, across 18 languages, backed by 534 tests. It learns your repo's conventions: where interfaces live, where DI is registered, whether 'use client' belongs. It ranks files by git churn × complexity so you know what to fix first, and hands any smell to the Claude Code already on your machine. Free to use, and your source never leaves your computer.
- [DB-Kit Database Manager](https://blog.markkulab.net/en/tools/db-kit): DB-Kit is a lightweight, cross-platform database manager built with Tauri + Rust + React. Manage MySQL, MariaDB, PostgreSQL, SQL Server, Oracle, SQLite, MongoDB, Redis, Kafka, Elasticsearch and RabbitMQ from one consistent interface: passwords encrypted in the OS keychain, SSH tunnels, full CRUD, a visual query builder, stacked multi-statement result sets, cross-connection data transfer and compare/sync, Excel / CSV import & export, visualized execution plans, ER diagrams, scheduled backups, SQL stress testing with p50–p99 latency percentiles, a 15-rule SQL review engine, Kafka message browsing with monitoring & alerts, a bilingual UI (Traditional Chinese / English), a built-in AI assistant (natural-language SQL, AI review and tuning advice) and the dbk CLI. Free and open source (MIT), with installers for Windows, macOS and Linux.
- [VS Code Super Mermaid](https://blog.markkulab.net/en/tools/super-mermaid): Super Mermaid is a VS Code extension for beautiful Mermaid diagrams out of the box: auto-colored live preview, mouse pan & zoom, high-res PNG / SVG export, 21 templates and multiple themes. Free and open source (MIT).
- [React Super Mermaid](https://blog.markkulab.net/en/tools/react-super-mermaid): react-super-mermaid is an open-source React component library: render beautiful Mermaid diagrams with a single <MermaidViewer>, with built-in colorful / sketch themes, pan & zoom, in-diagram search, and high-res SVG / PNG export. Lightweight, SSR-safe, fully typed. Free and open source (MIT).
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/en/tools/jira-super-mermaid): An Atlassian Forge app: write Mermaid syntax directly inside a Jira issue or a Confluence page and get flowcharts, sequence diagrams, state machines and Gantt charts. 11 diagram types, SVG / PNG export, light and dark themes, full CJK support. Runs on Atlassian: your diagrams live in your own site and the app calls no third-party service. Free, coming soon to the Atlassian Marketplace.
- [Mermaid Live Preview](https://blog.markkulab.net/en/tools/mermaid-preview): Write Mermaid in your browser, see it render instantly, and share the whole diagram as a single link. No sign-up, nothing uploaded to a server, and mermaid.live share links work as-is.
- [React Intl Phone Number](https://blog.markkulab.net/en/tools/react-intl-phone-number): react-intl-phone-number is an open-source React component: framework-agnostic and antd-free, with E.164 in/out, a searchable flag / country-code dropdown, configurable validation levels (strict / mobile-strict / loose), themeable CSS, and i18n — phone logic powered by google-libphonenumber. Lightweight and fully typed. Free and open source (MIT).
- [Uptime Kuma Cluster](https://blog.markkulab.net/en/tools/uptime-kuma-cluster): Turn single-node Uptime Kuma into a highly available cluster: OpenResty + Lua smart load balancing, shared MariaDB state, health checks and automatic failover, plus cluster-management REST APIs. One Docker Compose command to start. Free and open source (MIT).
- [Special Education](https://blog.markkulab.net/en/education): Learning materials crafted for special education students

### Daily podcasts

- [Mark's Tech Insights — Daily AI News](https://blog.markkulab.net/en/category/tech-news): Daily curated AI and tech trends. Catch the latest developments via audio summaries — covering AI applications, software architecture, DevOps, and engineering practice. — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/en/category/ai-stock-chat): Every trading day, an AI-analyzed take on the Taiwan stock market, delivered as a two-host conversation covering the session and the next-day outlook. — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml
- [開源好物週報](https://blog.markkulab.net/en/category/open-source-weekly): A weekly two-host pick of free open-source tools surfaced from real Hacker News, GitHub, and Reddit buzz — what pain they solve and the fastest way to get started. — RSS: https://blog.markkulab.net/open-source-weekly/feed.xml

### Newsletter

[Subscribe to the newsletter](https://blog.markkulab.net/en/subscribe) — Be the first to know about new posts. No spam, unsubscribe anytime.
