Nginx 反向代理 Tomcat(HTTPS)
單一容器內同時跑 Nginx 與 Tomcat 7,Tomcat 以 HTTPS 監聽 8443,Nginx 把 /tomcat 路徑代理過去。
Dockerfile
FROM tomcat:7.0-jre7
# 產生自簽憑證放進 Java keystore
RUN $JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA \
-storepass changeit -keypass changeit \
-dname "CN=example.com,OU=,O=,L=,S=,C=SE"
# 在 server.xml 插入 8443 的 SSL Connector
RUN sed -i 's/<Service name="Catalina">/<Service name="Catalina"> \n\n <Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"\n maxThreads="150" SSLEnabled="true" scheme="https" secure="true"\n clientAuth="false" sslProtocol="TLS" \/>/' conf/server.xml
RUN apt-get update && apt-get upgrade && apt-get -y install \
curl wget git vim nginx tomcat7 software-properties-common
# Nginx 加上 /tomcat 反向代理
RUN sed -i '42 i\location /tomcat { \
proxy_pass https://127.0.0.1:8443/; \
}' /etc/nginx/sites-available/default
# 啟動 Tomcat 時順便啟動 Nginx
RUN sed -i '121 a\service nginx restart' /usr/local/tomcat/bin/catalina.sh
產生的設定
Tomcat 端多出一個 SSL Connector:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
Nginx 端多出一段 location:
location /tomcat {
proxy_pass https://127.0.0.1:8443/;
}
建置與執行
docker build -t nginx-tomcat-ssl:latest .
docker run -d -p 80:80 -p 8443:8443 --name web nginx-tomcat-ssl:latest
http://localhost/tomcat→ 由 Nginx 代理到 Tomcathttps://localhost:8443→ 直接連 Tomcat(自簽憑證,瀏覽器會警告)
已知問題與改進方向
這份 Dockerfile 有幾個實務上需要調整的地方:
sed使用固定行號(第 42、121 行)。上游套件版本一變就會插錯位置。改成COPY完整設定檔更穩定。- keystore 密碼寫死成
changeit,且憑證是自簽。正式環境請改用 Let’s Encrypt 或內部 CA 簽發,密碼用 build secret 傳入。 - 單一容器跑兩個服務,沒有 process supervisor。任一服務掛掉容器不會重啟。建議拆成兩個容器,用 Docker Compose 或 Kubernetes 編排。
proxy_pass走 HTTPS 到 localhost 會多一次 TLS 握手開銷。同一台機器內用 HTTP、只在對外那層做 TLS 終止會更有效率。- Tomcat 7 與 JRE 7 已終止支援,
sslProtocol="TLS"也會協商到已不安全的舊版協議。
相關資源
← 回到 Web 網頁伺服器