我在运行Amazon Linux 2的AWS上有一个EC2实例。
在其上,我安装了Git,docker和docker-compose。完成后,我克隆了存储库并运行docker-compose up
以启动生产环境。我去了公共DNS,就可以了。
我现在要在网站上启用HTTPS。
我的项目有一个使用React在Nginx-alpine服务器上运行的前端。后端是NodeJS服务器。
这是我的nginx.conf文件:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /index.html;
}
location /api/ {
proxy_pass http://${PROJECT_NAME}_backend:${NODE_PORT}/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
这是我的docker-compose.yml文件:
version: "3.7"
services:
##############################
# Back-End Container
##############################
backend: # Node-Express backend that acts as an API.
container_name: ${PROJECT_NAME}_backend
init: true
build:
context: ./backend/
target: production
restart: always
environment:
- NODE_PATH=${EXPRESS_NODE_PATH}
- AWS_REGION=${AWS_REGION}
- NODE_ENV=production
- DOCKER_BUILDKIT=1
- PORT=${NODE_PORT}
networks:
- client
##############################
# Front-End Container
##############################
nginx:
container_name: ${PROJECT_NAME}_frontend
build:
context: ./frontend/
target: production
args:
- NODE_PATH=${REACT_NODE_PATH}
- SASS_PATH=${SASS_PATH}
restart: always
environment:
- PROJECT_NAME=${PROJECT_NAME}
- NODE_PORT=${NODE_PORT}
- DOCKER_BUILDKIT=1
command: /bin/ash -c "envsubst '$$PROJECT_NAME $$NODE_PORT' < /etc/nginx/conf.d/nginx.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
expose:
- "80"
ports:
- "80:80"
depends_on:
- backend
networks:
- client
##############################
# General Config
##############################
networks:
client:
我知道有一个用于certbot的Docker映像,但是我不确定如何使用它。我也担心通过HTTP将请求/api/
代理到服务器的方式。那还会给我带来任何问题吗?
答案 0 :(得分:1)
通过遵循Nginx and Let's Encrypt with Docker in Less Than 5 Minutes上的教程来启用SSL。我在遵循它时遇到了一些问题,因此我将在这里尝试澄清一些事情。
这些步骤包括将以下内容添加到docker-compose.yml
:
##############################
# Certbot Container
##############################
certbot:
image: certbot/certbot:latest
volumes:
- ./frontend/data/certbot/conf:/etc/letsencrypt
- ./frontend/data/certbot/www:/var/www/certbot
对于docker-compose.yml
的 Nginx容器部分,应进行修改,以包括添加到 Certbot容器的相同卷,以及添加端口并公开配置:
service_name:
container_name: container_name
image: nginx:alpine
command: /bin/ash -c "exec nginx -g 'daemon off;'"
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
expose:
- "80"
- "443"
ports:
- "80:80"
- "443:443"
networks:
- default
data
文件夹可以保存在其他任何地方,但是请确保知道它在哪里,并确保以后再使用时正确引用它。在此示例中,我只是将其保存在docker-compose.yml
文件所在的目录中。
完成上述配置后,将采取几个步骤来初始化证书的颁发。
首先,将更改您的Nginx配置(default.conf
)以适应域验证请求:
server {
listen 80;
server_name example.com www.example.com;
server_tokens off;
location / {
return 301 https://$server_name$request_uri;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
server {
listen 443 ssl;
server_name example.com www.example.com;
server_tokens off;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /index.html;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
修改Nginx配置文件后,将创建一个虚拟证书以允许进行我们的加密验证。有一个脚本可以自动执行所有这些操作,可以在使用CURL进行修改以适应环境之前,将其下载到项目的根目录中。还需要使用chmod
命令使脚本可执行:
curl -L https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh > init-letsencrypt.sh && chmod +x init-letsencrypt.sh
下载脚本后,将对其进行如下修改:
#!/bin/bash
if ! [ -x "$(command -v docker-compose)" ]; then
echo 'Error: docker-compose is not installed.' >&2
exit 1
fi
-domains=(example.org www.example.org)
+domains=(example.com www.example.com)
rsa_key_size=4096
-data_path="./data/certbot"
+data_path="./data/certbot"
-email="" # Adding a valid address is strongly recommended
+email="admin@example.com" # Adding a valid address is strongly recommended
staging=0 # Set to 1 when testing setup to avoid hitting request limits
if [ -d "$data_path" ]; then
read -p "Existing data found for $domains. Continue and replace existing certificate? (y/N) " decision
if [ "$decision" != "Y" ] && [ "$decision" != "y" ]; then
exit
fi
fi
if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
echo "### Downloading recommended TLS parameters ..."
mkdir -p "$data_path/conf"
curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
curl -s https://raw.githubusercontent.com/certbot/certbot/master/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
echo
fi
echo "### Creating dummy certificate for $domains ..."
path="/etc/letsencrypt/live/$domains"
mkdir -p "$data_path/conf/live/$domains"
-docker-compose run --rm --entrypoint "\
+docker-compose -f docker-compose.yml run --rm --entrypoint "\
openssl req -x509 -nodes -newkey rsa:1024 -days 1\
-keyout '$path/privkey.pem' \
-out '$path/fullchain.pem' \
-subj '/CN=localhost'" certbot
echo
echo "### Starting nginx ..."
-docker-compose up --force-recreate -d nginx
+docker-compose -f docker-compose.yml up --force-recreate -d service_name
echo
echo "### Deleting dummy certificate for $domains ..."
-docker-compose run --rm --entrypoint "\
+docker-compose -f docker-compose.yml run --rm --entrypoint "\
rm -Rf /etc/letsencrypt/live/$domains && \
rm -Rf /etc/letsencrypt/archive/$domains && \
rm -Rf /etc/letsencrypt/renewal/$domains.conf" certbot
echo
echo "### Requesting Let's Encrypt certificate for $domains ..."
#Join $domains to -d args
domain_args=""
for domain in "${domains[@]}"; do
domain_args="$domain_args -d $domain"
done
# Select appropriate email arg
case "$email" in
"") email_arg="--register-unsafely-without-email" ;;
*) email_arg="--email $email" ;;
esac
# Enable staging mode if needed
if [ $staging != "0" ]; then staging_arg="--staging"; fi
-docker-compose run --rm --entrypoint "\
+docker-compose -f docker-compose.yml run --rm --entrypoint "\
certbot certonly --webroot -w /var/www/certbot \
$staging_arg \
$email_arg \
$domain_args \
--rsa-key-size $rsa_key_size \
--agree-tos \
--force-renewal" certbot
echo
echo "### Reloading nginx ..."
-docker-compose exec nginx nginx -s reload
+docker-compose exec service_name nginx -s reload
我已确保在-f
命令中始终包含docker-compose
标志,以防万一有人拥有名为docker-compose.yml
的自定义文件不知道要更改什么。与教程不同,我还确保将服务名称设置为service_name
,以确保区分服务名称和Nginx命令。
注意::如果不确定安装程序是否正常运行,请确保将登台设置为1
,以避免达到请求限制。重要的是要记住,测试完成后将其设置回0
并重做修改init-letsencrypt.sh
文件的所有步骤。完成测试并将阶段设置为0
后,停止先前运行的容器并删除数据文件夹以确保进行适当的初始认证很重要:
$ docker-compose -f docker-compose.yml down && yes | docker system prune -a --volumes && sudo rm -rf ./data
一旦准备好初始化证书,就可以使用sudo
运行脚本;使用sudo非常重要,因为如果不使用sudo,容器内部的权限就会出现问题。
$ sudo ./init-letsencrypt.sh
颁发证书后,存在自动续订证书的问题;需要完成两件事:
service_name:
...
- command: /bin/ash -c "exec nginx -g 'daemon off;'"
+ command: /bin/ash -c "while :; do sleep 6h & wait $${!}; nginx -s reload; done & exec nginx -g 'daemon off;'"
...
certbot:
...
+ entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew --webroot -w /var/www/certbot; sleep 12h & wait $${!}; done;'"
在运行docker-compose -f docker-compose.yml up
之前,应将data
的所有权更改为ec2-user
的文件夹;这是为了避免在运行docker-compose -f docker-compose.yml up
或以sudo模式运行时出现权限错误:
sudo chown ec2-user:ec2-user -R /path/to/data/
不要忘记在您的DNS提供商中为让我们加密添加CAA记录。您可以阅读here,以获取更多有关这样做的信息。
如果由于替换变量而导致Nginx容器出现任何问题,并且$server_name
和$request_uri
的显示不正确,则可以参考this issue。
答案 1 :(得分:0)
最简单的方法是设置ALB并将其用于HTTPS。
请求将使用带有https的ALB服务