aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docker/auto-certbot/Dockerfile5
-rwxr-xr-xdocker/auto-certbot/daemon.bash29
-rw-r--r--template/docker-compose.yaml.template17
-rwxr-xr-xtool/aio.py40
-rwxr-xr-xtool/modules/nginx.py52
5 files changed, 103 insertions, 40 deletions
diff --git a/docker/auto-certbot/Dockerfile b/docker/auto-certbot/Dockerfile
index 345682c..655197d 100644
--- a/docker/auto-certbot/Dockerfile
+++ b/docker/auto-certbot/Dockerfile
@@ -1,5 +1,6 @@
FROM certbot/certbot:latest
ARG CRUPEST_DOMAIN
-ARG CRUPEST_CERTBOT_RENEW_COMMAND
+ARG CRUPEST_CERTBOT_RENEW_COMMAND=""
COPY daemon.bash /daemon.bash
-CMD [ "/daemon.bash" ]
+VOLUME ["/var/www/certbot", "/etc/letsencrypt", "/var/lib/letsencrypt"]
+ENTRYPOINT [ "/daemon.bash" ]
diff --git a/docker/auto-certbot/daemon.bash b/docker/auto-certbot/daemon.bash
index 8927c4a..de21ba8 100755
--- a/docker/auto-certbot/daemon.bash
+++ b/docker/auto-certbot/daemon.bash
@@ -8,8 +8,11 @@ fi
# Check CRUPEST_CERTBOT_RENEW_COMMAND is defined.
if [ -z "$CRUPEST_CERTBOT_RENEW_COMMAND" ]; then
- echo "CRUPEST_CERTBOT_RENEW_COMMAND must be defined."
- exit 1
+ echo "CRUPEST_CERTBOT_RENEW_COMMAND is not defined or empty"
+ CRUPEST_CERTBOT_RENEW_COMMAND="certbot renew --webroot -w /var/www/certbot"
+ printf "Will use:\n%s\n" "$CRUPEST_CERTBOT_RENEW_COMMAND"
+else
+ printf "CRUPEST_CERTBOT_RENEW_COMMAND is defined as:\n%s\n" "$CRUPEST_CERTBOT_RENEW_COMMAND"
fi
# Check CRUPEST_CERT_PATH, default to /etc/letsencrypt/live/$CRUPEST_DOMAIN/fullchain.pem
@@ -17,7 +20,7 @@ if [ -z "$CRUPEST_CERT_PATH" ]; then
CRUPEST_CERT_PATH="/etc/letsencrypt/live/$CRUPEST_DOMAIN/fullchain.pem"
fi
-function check_and_renew_cert() {
+function check_and_renew_cert {
expire_info=$(openssl x509 -enddate -noout -in "$CRUPEST_CERT_PATH")
# Get ssl certificate expire date.
@@ -33,21 +36,15 @@ function check_and_renew_cert() {
echo "Renew SSL certificate at: $(date -d @$renew_timestamp)"
# Get rest time til renew.
- rest_time="$((renew_timestamp - $(date +%s)))"
- echo "Rest time til renew: $rest_time seconds"
+ rest_time_in_second="$((renew_timestamp - $(date +%s)))"
+ rest_time_in_day=$((rest_time_in_second / 86400))
+ echo "Rest time til renew: $rest_time_in_second seconds, aka, about $rest_time_in_day days"
# Do we have rest time?
- if [ "$rest_time" -gt 0 ]; then
- # Check CRUPEST_GREEDY_CHECK is defined.
- if [ -z "$CRUPEST_GREEDY_CHECK" ]; then
- # Sleep til renew.
- echo "Sleeping til renew..."
- sleep "$rest_time"
- else
- # Sleep 1 hour.
- echo "Seems like CRUPEST_GREEDY_CHECK is defined, sleep 1 day and check again..."
- sleep 86400
- fi
+ if [ $rest_time_in_second -gt 0 ]; then
+ # Sleep 1 hour.
+ echo "I'm going to sleop for 1 day to check again."
+ sleep 1d
else
# No, renew now.
echo "Renewing now..."
diff --git a/template/docker-compose.yaml.template b/template/docker-compose.yaml.template
index acabf5a..6da2c3c 100644
--- a/template/docker-compose.yaml.template
+++ b/template/docker-compose.yaml.template
@@ -75,6 +75,23 @@ services:
- external
- internal
+ auto-certbot:
+ image: crupest/auto-certbot:latest
+ build:
+ context: ./docker/auto-certbot
+ dockerfile: Dockerfile
+ pull: true
+ args:
+ - CRUPEST_DOMAIN=$CRUPEST_DOMAIN
+ container_name: auto-certbot
+ volumes:
+ - "./data/certbot/certs:/etc/letsencrypt"
+ - "./data/certbot/data:/var/lib/letsencrypt"
+ - "./data/certbot/webroot:/var/www/certbot"
+ restart: on-failure:3
+ networks:
+ - internal
+
mailserver:
image: docker.io/mailserver/docker-mailserver:latest
pull_policy: always
diff --git a/tool/aio.py b/tool/aio.py
index 94e4460..cdb616c 100755
--- a/tool/aio.py
+++ b/tool/aio.py
@@ -408,21 +408,35 @@ if to_gen_nginx_conf:
domain = config["CRUPEST_DOMAIN"]
generate_nginx_config(domain)
-
-if not os.path.exists(os.path.join(data_dir, "code-server")):
- os.mkdir(os.path.join(data_dir, "code-server"))
+if not os.path.exists(data_dir):
console.print(
- "I also create data dir for code-server. Because letting docker create it would result in permission problem.", style="green")
-else:
- code_server_stat = os.stat(os.path.join(data_dir, "code-server"))
- if code_server_stat.st_uid == 0 or code_server_stat.st_gid == 0:
+ "Looks like you haven't generated data dir. I'll create it for you.", style="green")
+ os.mkdir(data_dir)
+elif not os.path.isdir(data_dir):
+ console.print(
+ "ERROR: data dir is not a dir! Everything will be broken! Please delete it manually", style="red")
+
+if os.path.isdir(data_dir):
+ if not os.path.exists(os.path.join(data_dir, "certbot")):
+ console.print(
+ "Looks like you haven't run certbot to get the init ssl certificates. You may want to run following code to get one:", style="cyan")
+ console.print(certbot_command_gen(domain, "create"),
+ soft_wrap=True, highlight=False)
+
+ if not os.path.exists(os.path.join(data_dir, "code-server")):
+ os.mkdir(os.path.join(data_dir, "code-server"))
console.print(
- "WARNING: The owner of data dir for code-server is root. This may cause permission problem. You had better change it.", style="yellow")
- to_fix = Confirm.ask(
- "Do you want me to help you fix it?", console=console, default=True)
- if to_fix:
- os.system(
- f"sudo chown -R {os.getuid()}:{os.getgid()} {os.path.join(data_dir, 'code-server')}")
+ "I also create data dir for code-server. Because letting docker create it would result in permission problem.", style="green")
+ else:
+ code_server_stat = os.stat(os.path.join(data_dir, "code-server"))
+ if code_server_stat.st_uid == 0 or code_server_stat.st_gid == 0:
+ console.print(
+ "WARNING: The owner of data dir for code-server is root. This may cause permission problem. You had better change it.", style="yellow")
+ to_fix = Confirm.ask(
+ "Do you want me to help you fix it?", console=console, default=True)
+ if to_fix:
+ os.system(
+ f"sudo chown -R {os.getuid()}:{os.getgid()} {os.path.join(data_dir, 'code-server')}")
console.print(":beers: All done!", style="green")
to_download_tools = Confirm.ask(
diff --git a/tool/modules/nginx.py b/tool/modules/nginx.py
index 422a823..3ec9fb8 100755
--- a/tool/modules/nginx.py
+++ b/tool/modules/nginx.py
@@ -76,19 +76,53 @@ def list_domains(domain: str) -> list:
return [domain, *list_subdomains(domain)]
-def certbot_command_gen(domain: str, action, test=False) -> str:
+def certbot_command_gen(domain: str, action, /, test=False, no_docker=False, *, standalone=None, email=None, agree_tos=False) -> str:
domains = list_domains(domain)
+
+ add_domain_option = True
if action == 'create':
- # create with standalone mode
- return f'docker run -it --rm --name certbot -v "{project_abs_path}/data/certbot/certs:/etc/letsencrypt" -v "{project_abs_path}/data/certbot/data:/var/lib/letsencrypt" -p "0.0.0.0:80:80" certbot/certbot certonly --standalone -d {" -d ".join(domains)}{ " --test-cert --dry-run" if test else "" }'
+ if standalone == None:
+ standalone = True
+ certbot_action = "certonly"
elif action == 'expand':
- # expand with webroot mode
- return f'docker run -it --rm --name certbot -v "{project_abs_path}/data/certbot/certs:/etc/letsencrypt" -v "{project_abs_path}/data/certbot/data:/var/lib/letsencrypt" -v "{project_abs_path}/data/certbot/webroot:/var/www/certbot" certbot/certbot certonly --webroot -w /var/www/certbot -d {" -d ".join(domains)}{ " --test-cert --dry-run" if test else "" }'
+ if standalone == None:
+ standalone = False
+ certbot_action = "certonly"
elif action == 'renew':
- # renew with webroot mode
- return f'docker run -it --rm --name certbot -v "{project_abs_path}/data/certbot/certs:/etc/letsencrypt" -v "{project_abs_path}/data/certbot/data:/var/lib/letsencrypt" -v "{project_abs_path}/data/certbot/webroot:/var/www/certbot" certbot/certbot renew --webroot -w /var/www/certbot{ " --test-cert --dry-run" if test else "" }'
- raise ValueError('Invalid action')
-
+ if standalone == None:
+ standalone = False
+ add_domain_option = False
+ certbot_action = "renew"
+ else:
+ raise ValueError('Invalid action')
+
+ if no_docker:
+ command = "certbot "
+ else:
+ expose_segment = ' -p "0.0.0.0:80:80"'
+ web_root_segment = ' -v "{project_abs_path}/data/certbot/webroot:/var/www/certbot"'
+ command = f'docker run -it --rm --name certbot -v "{project_abs_path}/data/certbot/certs:/etc/letsencrypt" -v "{project_abs_path}/data/certbot/data:/var/lib/letsencrypt"{ expose_segment if standalone else web_root_segment} certbot/certbot '
+
+ command += certbot_action
+
+ if standalone:
+ command += " --standalone"
+ else:
+ command += ' --webroot -w /var/www/certbot'
+
+ if add_domain_option:
+ command += f' -d {" -d ".join(domains)}'
+
+ if email is not None:
+ command += f' --email {email}'
+
+ if agree_tos:
+ command += ' --agree-tos'
+
+ if test:
+ command += " --test-cert --dry-run"
+
+ return command
def nginx_config_dir_check(dir_path: str, domain: str) -> list:
good_files = [*non_template_files, "ssl.conf", *