
Docker Deployment
- 47 installs
- 82 repo stars
- Updated August 2, 2026
- aaaaqwq/claude-code-skills
docker-deployment is a Claude Code skill that deploys Docker web apps with Nginx HTTPS and Cloudflare Tunnel for secure external access.
About
This Claude Code skill covers deploying Docker web applications with an Nginx HTTPS reverse proxy and Cloudflare Tunnel for secure external access. It documents SSL certificate mounting, named-volume data persistence, and common HTTPS and data-loss troubleshooting. A developer uses it when containerizing and exposing a web app over HTTPS.
- Docker web-app deployment with Nginx HTTPS reverse proxy configuration
- Cloudflare Origin Certificate and Cloudflare Tunnel setup for secure external access
- Named-volume data persistence guidance and HTTP-to-HTTPS redirect troubleshooting
Docker Deployment by the numbers
- 47 all-time installs (skills.sh)
- Ranked #745 of 1,438 DevOps & CI/CD skills by installs in the Skillselion catalog
- Data as of Aug 3, 2026 (Skillselion catalog sync)
docker-deployment capabilities & compatibility
Free; requires a Cloudflare account and a domain you control
- Capabilities
- docker deploy · nginx config · https setup · cloudflare tunnel · data persistence
- Works with
- docker · cloudflare
- Use cases
- devops · ci cd
- Platforms
- Linux
- Pricing
- Free
What docker-deployment says it does
Docker container deployment with Nginx HTTPS configuration and Cloudflare Tunnel integration.
Internet → Cloudflare Edge (HTTPS) → Cloudflare Tunnel → Ubuntu/Docker (Nginx)
npx skills add https://github.com/aaaaqwq/claude-code-skills --skill docker-deploymentAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 47 |
|---|---|
| repo stars | ★ 82 |
| Last updated | August 2, 2026 |
| Repository | aaaaqwq/claude-code-skills ↗ |
What it does
Deploy a Dockerized web app behind Nginx HTTPS and a Cloudflare Tunnel with persistent named volumes.
Who is it for?
Developers deploying containerized web apps with HTTPS and Cloudflare Tunnel
Skip if: Kubernetes or cloud-managed container orchestration; this targets Docker Compose on a single host
When should I use this skill?
You are deploying a web app with Docker, configuring SSL/TLS, Nginx reverse proxy, or a Cloudflare Tunnel
What you get
A Dockerized web app served over HTTPS via Nginx and a Cloudflare Tunnel with persistent volumes
- Nginx HTTPS config
- docker-compose with certificate volumes
- Cloudflare Tunnel setup
By the numbers
- 4 documented tasks (Nginx HTTPS, CF Origin Cert, data persistence, CF Tunnel)
Files
Docker Deployment with Nginx HTTPS
Quick Start
For Docker web application deployment with HTTPS support:
1. Configure Nginx with SSL certificates (see nginx-https.md) 2. Set up docker-compose.yml with certificate volume mounting 3. Configure Cloudflare Tunnel to connect external domain to local container
Common Tasks
| Task | Reference |
|---|---|
| Nginx HTTPS configuration | nginx-https.md |
| Cloudflare Origin Certificate | cf-origin-cert.md |
| Docker data persistence | data-persistence.md |
| Cloudflare Tunnel setup | cf-tunnel.md |
Architecture Overview
Internet → Cloudflare Edge (HTTPS) → Cloudflare Tunnel → Ubuntu/Docker (Nginx)Key Principles
- Always use named Docker volumes for persistent data
- Nginx should redirect HTTP (80) to HTTPS (443) in production
- Cloudflare Origin Certificates are for CF-to-origin encryption only
- Tunnel connects to HTTP or HTTPS - configure based on nginx setup
Troubleshooting
HTTPS not working after enabling Cloudflare force HTTPS?
- Check if nginx listens on port 443
- Verify SSL certificates are mounted correctly
- Ensure Cloudflare Tunnel service URL matches (http:// or https://)
Data lost after container restart?
- Check docker-compose.yml uses named volumes, not bind mounts for critical data
- Verify database path points to mounted volume directory
See individual reference files for detailed solutions.
Cloudflare Origin Server Certificate
What is it?
Cloudflare Origin Server Certificate is a TLS certificate issued by Cloudflare specifically for encryption between Cloudflare's edge servers and your origin server.
Key Points
| Aspect | Detail |
|---|---|
| Browser Trust | NOT trusted by browsers (for CF→Origin only) |
| Valid For | Cloudflare to your server communication |
| Validity | Up to 15 years |
| Cost | Free |
| Requires | Cloudflare Proxy or Tunnel |
When to Use
- Your site is behind Cloudflare Proxy (orange cloud in DNS)
- Your site uses Cloudflare Tunnel
- You need end-to-end encryption from CF to origin
Download Steps
1. Cloudflare Dashboard → SSL/TLS → Origin Server 2. Click Create Certificate 3. Configure:
- Hostnames:
*.yourdomain.comandyourdomain.com - Validity: 15 years
- Key Type: RSA (2048)
4. Click Create 5. Copy two parts:
Origin Certificate (save as nginx.crt)
-----BEGIN CERTIFICATE-----
MIIEpDCCA4ygAwIBAgIUZK...
-----END CERTIFICATE-----Private Key (save as nginx.key)
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0B...
-----END PRIVATE KEY-----File Formats
- Certificate:
.crtor.pem(same content, different extension) - Private Key:
.key
Security Notes
- NEVER commit private keys to git
- Add
*.keyto.gitignore - Certificates can be public, but keys must be private
Cloudflare Tunnel 完整部署指南
What is Cloudflare Tunnel?
Cloudflare Tunnel 是一种安全的出站连接,从你的服务器到 Cloudflare,无需开放公网端口。
架构
用户浏览器 --HTTPS--> Cloudflare Edge --加密隧道--> 你的服务器(cloudflared) --> Docker容器
↑ ↑
全球分布节点 无需开放公网端口---
完整部署流程(端到端)
第一步:注册域名
1. 在域名注册商购买域名(如 Namecheap, GoDaddy, 阿里云等) 2. 重要:准备好访问域名管理后台的权限
第二步:源服务器安装 cloudflared
# Ubuntu/Debian
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
# 验证安装
cloudflared --version
# 或用 curl 安装
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb第三步:登录授权 Cloudflare
# 会弹出浏览器,登录你的 Cloudflare 账号并授权
cloudflared tunnel login授权成功后,证书会保存在 ~/.cloudflared/cert.pem
第四步:创建 Tunnel
# 创建命名隧道
cloudflared tunnel create <tunnel-name>
# 示例
cloudflared tunnel create xinzhixietong-tunnel
# 输出会包含:
# - Tunnel ID (保存这个!)
# - credentials file 位置第五步:配置 DNS 到 Cloudflare
# 将域名路由到 tunnel
cloudflared tunnel route dns <tunnel-name> yourdomain.com
cloudflared tunnel route dns <tunnel-name> www.yourdomain.com或者在 Cloudflare 后台手动添加 DNS 记录:
- 类型:CNAME
- 名称:www / @
- 目标:
<tunnel-id>.cfargotunnel.com
检查域名 NS 配置
重要:确认你的域名管理系统中,NS 记录指向 Cloudflare:
域名管理后台 → DNS 设置 → Nameservers
应该显示:
- lana.ns.cloudflare.com
- mark.ns.cloudflare.com
(具体以你的 CF 账号显示的为准)流量路径:
用户 → 域名DNS解析 → Cloudflare NS → Cloudflare Tunnel → 你的服务器第六步:创建 config.yml 配置
配置文件位置:~/.cloudflared/config.yml
# Tunnel 基本信息
tunnel: <YOUR_TUNNEL_ID> # 替换为你的 Tunnel ID
credentials-file: ~/.cloudflared/<TUNNEL_ID>.json
# 服务路由配置
ingress:
# 前端服务(HTTP 端口,推荐)
- hostname: www.yourdomain.com
service: http://localhost:5668
# 或者用 HTTPS(需要额外配置,见下文)
# service: https://localhost:5669
# originRequest:
# noTLSVerify: true # 本地 HTTPS 需要跳过证书验证
# 后端 API 服务
- hostname: api.yourdomain.com
service: http://localhost:5768
# 其他服务...
- hostname: admin.yourdomain.com
service: http://localhost:3000
# 默认规则(必须放在最后)
- service: http_status:404HTTPS 配置的坑(重要!)
坑1:400 Bad Request - The plain HTTP request was sent to HTTPS port
| 配置 | 结果 |
|---|---|
service: http://localhost:5669 | ❌ 错误!HTTP 协议访问 HTTPS 端口 |
service: https://localhost:5669 | ✅ 正确,但可能有证书问题 |
坑2:502 Bad Gateway
当使用 https://localhost:5669 时,cloudflared 会验证证书:
- 你的证书域名:
*.yourdomain.com - cloudflared 访问:
localhost - 域名不匹配,验证失败!
解决方案:
| 方案 | 配置 | 推荐度 |
|---|---|---|
| 方案A:用 HTTP | service: http://localhost:5668 | ⭐⭐⭐⭐⭐ 最简单 |
| 方案B:HTTPS + 跳过验证 | service: https://localhost:5669 + noTLSVerify: true | ⭐⭐⭐⭐ |
| 方案C:生成 localhost 证书 | 生成包含 localhost 的证书 | ⭐⭐⭐ |
方案A 示例(推荐):
ingress:
- hostname: www.yourdomain.com
service: http://localhost:5668 # 用户到CF仍是HTTPS方案B 示例:
ingress:
- hostname: www.yourdomain.com
service: https://localhost:5669
originRequest:
noTLSVerify: true # 跳过本地证书验证
keepAliveTimeout: 90s
connectTimeout: 30s第七步:启动 Tunnel
# 方式一:直接运行(测试用)
cloudflared tunnel run <tunnel-name>
# 方式二:安装为系统服务(推荐)
sudo cloudflared service install
# 启动服务
sudo systemctl start cloudflared
sudo systemctl enable cloudflared
# 查看状态
sudo systemctl status cloudflared
# 查看日志
sudo journalctl -u cloudflared -f---
服务管理
# 列出所有 tunnels
cloudflared tunnel list
# 查看 tunnel 信息
cloudflared tunnel info <tunnel-name>
# 删除 tunnel
cloudflared tunnel delete <tunnel-id>
# 清理 DNS 路由
cloudflared tunnel route dns <tunnel-name> yourdomain.com # 添加
cloudflared tunnel route dns <tunnel-name> yourdomain.com -d # 删除---
常见问题
1. 时好时坏 / 手机无法访问
可能原因:
- Cloudflare 某些 IP 在国内被限制
- 域名未备案(国内访问问题)
- DNS 传播延迟
解决方案:
- 等待 DNS 传播(5-10分钟)
- 国内用户建议使用 VPN 或备案后使用国内方案
2. 修改 config.yml 后不生效
# 必须重启服务
sudo systemctl restart cloudflared3. 502 Bad Gateway
检查:
# 本地服务是否运行
curl -k https://localhost:5669
# cloudflared 日志
sudo journalctl -u cloudflared -n 504. 400 Bad Request
检查 service 协议是否正确:
- HTTPS 端口必须用
https:// - HTTP 端口必须用
http://
---
安全说明
用户 --HTTPS(加密)--> Cloudflare --Tunnel(加密)--> cloudflared --HTTP/HTTPS--> 本地服务
↑ ↑ ↑
浏览器验证CF证书 隧道加密传输 本地回环,安全可控- 用户到 CF:全程 HTTPS,浏览器验证证书,完全安全
- CF 到 cloudflared:Cloudflare Tunnel 加密,不经过公网
- cloudflared 到本地服务:本地回环连接,即使 HTTP 也安全(因为不走公网)
---
Quick Start 快速模板
# 1. 安装
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
# 2. 登录
cloudflared tunnel login
# 3. 创建 tunnel
cloudflared tunnel create my-tunnel
# 4. 配置 DNS
cloudflared tunnel route dns my-tunnel www.yourdomain.com
# 5. 编辑配置
nano ~/.cloudflared/config.yml
# 复制上面的模板
# 6. 启动
sudo cloudflared service install
sudo systemctl start cloudflaredDocker Data Persistence
Problem
Data is lost when Docker containers are restarted.
Root Cause
Database file path doesn't point to mounted volume, or no volume is configured.
Solution
1. Use Named Volumes in docker-compose.yml
services:
backend:
volumes:
- backend-data:/app/data # Mount named volume
environment:
- DATABASE_URL=sqlite+aiosqlite:////app/data/auto_info.db
volumes:
backend-data:
driver: local2. Key Points
| Issue | Solution |
|---|---|
Relative path (./db.sqlite) | Use absolute path in mounted directory |
| Database URL | Point to mounted volume (////app/data/...) |
| Container rebuild | Named volumes persist independently |
3. SQLite Path Format
For SQLite in Docker with volume mount:
# Correct (4 slashes = absolute path)
DATABASE_URL = "sqlite+aiosqlite:////app/data/auto_info.db"
# Wrong (relative path, loses data)
DATABASE_URL = "sqlite+aiosqlite:///./auto_info.db"The //// format: sqlite:/// (3 slashes for SQLite protocol) + /app/data/... (absolute path)
4. Volume Management Commands
# List volumes
docker volume ls
# Inspect volume
docker volume inspect auto_info_backend-data
# Backup volume
docker run --rm -v auto_info_backend-data:/data -v $(pwd):/backup alpine tar czf /backup/backup.tar.gz /data
# Remove volume (WARNING: deletes data)
docker volume rm auto_info_backend-data5. Volume vs Bind Mount
| Type | Use When |
|---|---|
| Named Volume | Persistent data (database, uploads) |
| Bind Mount | Development (live code reload) |
6. .dockerignore
Don't let sensitive data be copied into images:
*.db
*.sqlite
certificates/Nginx HTTPS Configuration
Problem
Docker-deployed Nginx only listens on port 80 (HTTP). When Cloudflare force HTTPS is enabled, the site becomes inaccessible because the origin doesn't support HTTPS.
Root Cause
Nginx configuration only has listen 80; without listen 443 ssl;
Solution
1. Obtain SSL Certificate
For Cloudflare: Use Origin Server Certificate
1. Cloudflare Dashboard → SSL/TLS → Origin Server 2. Create Certificate (15 years validity recommended) 3. Save as nginx.crt (certificate) and nginx.key (private key)
2. Configure nginx.conf
# HTTP (80) - Redirect to HTTPS
server {
listen 80;
server_name localhost;
return 301 https://$host$request_uri;
}
# HTTPS (443)
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# ... rest of your config
}3. Update docker-compose.yml
services:
frontend:
ports:
- "5668:80"
- "5669:443" # Map HTTPS port
volumes:
- ./certificates:/etc/nginx/ssl:ro # Mount certificates4. Certificate Directory Structure
project/
├── docker-compose.yml
├── certificates/
│ ├── nginx.crt # SSL certificate
│ └── nginx.key # Private keyVerification
# Test HTTPS locally
curl -k https://localhost:5669
# Test HTTP redirect
curl -I http://localhost:5668
# Should return: HTTP/1.1 301 Moved PermanentlyCloudflare Tunnel Configuration
Update Tunnel service to use HTTPS:
Service: https://localhost:5669Or for container-to-container:
Service: https://container-name:443Related skills
FAQ
How does external traffic reach the container?
Through Cloudflare Edge over HTTPS to a Cloudflare Tunnel that connects to the local Docker/Nginx container.
How is data kept across restarts?
By always using named Docker volumes rather than bind mounts for critical data.