diff --git a/.dockeringore b/.dockeringore
new file mode 100644
index 0000000..3598c30
--- /dev/null
+++ b/.dockeringore
@@ -0,0 +1 @@
+tests
\ No newline at end of file
diff --git a/.gitattributes b/.gitattributes
index 52f5301..c94f078 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,4 +1,5 @@
* text=auto
*.sh eol=lf
**/run eol=lf
-*/services.d/* eol=lf
\ No newline at end of file
+*/services.d/* eol=lf
+cron-tick eol=lf
\ No newline at end of file
diff --git a/.github/settings.yml b/.github/settings.yml
index f980fff..56e93fc 100644
--- a/.github/settings.yml
+++ b/.github/settings.yml
@@ -21,7 +21,7 @@ branches:
protection:
required_status_checks:
strict: true
- contexts: [ ".github/workflows/ci.yml" ]
+ contexts: [ "build" ]
required_pull_request_reviews: null
enforce_admins: false
restrictions:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 25d8109..55d36be 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -6,7 +6,7 @@ on:
pull_request:
env:
- IMAGE_NAME: "homecentr/$$IMAGE_NAME$$"
+ IMAGE_NAME: "homecentr/certbot"
jobs:
build:
@@ -30,7 +30,7 @@ jobs:
run: docker build . -t ${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.docker_tag }}
- name: Test Docker image
- run: cd tests && sudo gradle test --info -Dimage_tag=${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.docker_tag }}
+ run: cd tests && sudo gradle test --info -Ddocker_image_tag=${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.docker_tag }} -Droot_domain=${{ secrets.ROOT_DOMAIN }} -Dacme_email=${{ secrets.ACME_EMAIL }} -Dcloudflare_token=${{ secrets.CLOUDFLARE_TOKEN }}
- name: Scan with Phonito Security
uses: phonito/phonito-scanner-action@master
diff --git a/.github/workflows/ci_cd.yml b/.github/workflows/ci_cd.yml
index f85445f..4bd25e4 100644
--- a/.github/workflows/ci_cd.yml
+++ b/.github/workflows/ci_cd.yml
@@ -5,7 +5,7 @@ on:
- master
env:
- IMAGE_NAME: "homecentr/$$IMAGE_NAME$$"
+ IMAGE_NAME: "homecentr/certbot"
jobs:
build:
@@ -40,7 +40,7 @@ jobs:
- name: Test Docker image
if: env.RELEASE_VERSION != ''
- run: cd tests && sudo gradle test -Dimage_tag=${{ env.IMAGE_NAME }}:${{ env.RELEASE_VERSION }}
+ run: cd tests && sudo gradle test -Ddocker_image_tag=${{ env.IMAGE_NAME }}:${{ env.RELEASE_VERSION }} -Droot_domain=${{ secrets.ROOT_DOMAIN }} -Dacme_email=${{ secrets.ACME_EMAIL }} -Dcloudflare_token=${{ secrets.CLOUDFLARE_TOKEN }}
- name: Scan with Phonito Security
if: env.RELEASE_VERSION != ''
diff --git a/.gitignore b/.gitignore
index 79cc10f..1f7244f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
+*.tmp
*.class
*.jar
*.war
diff --git a/Dockerfile b/Dockerfile
index c3c78df..7c1974f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1 +1,41 @@
-FROM alpine
\ No newline at end of file
+FROM certbot/certbot:v1.4.0 as certbot
+
+FROM homecentr/cron-base:1.2.0
+
+ARG CERTBOT_PIP_VERSION="1.4.0"
+
+ENV CERTBOT_ARGS=""
+ENV CRON_SCHEDULE="30 * * * *"
+ENV S6_BEHAVIOUR_IF_STAGE2_FAILS=2
+
+COPY --from=certbot /usr/local/bin/certbot /usr/local/bin/certbot
+
+RUN apk add --no-cache python3=3.8.2-r0 && \
+ apk add --no-cache --virtual deps \
+ python3-dev=3.8.2-r0 \
+ gcc=9.2.0-r4 \
+ libffi-dev=3.2.1-r6 \
+ openssl-dev=1.1.1g-r0 \
+ musl-dev=1.1.24-r2 && \
+ pip3 install --upgrade pip==20.1.1 && \
+ pip3 install \
+ setuptools==46.4.0 \
+ acme==${CERTBOT_PIP_VERSION} \
+ certbot==${CERTBOT_PIP_VERSION} \
+ certbot-dns-cloudflare==${CERTBOT_PIP_VERSION} \
+ certbot-dns-cloudxns==${CERTBOT_PIP_VERSION} \
+ certbot-dns-digitalocean==${CERTBOT_PIP_VERSION} \
+ certbot-dns-dnsimple==${CERTBOT_PIP_VERSION} \
+ certbot-dns-dnsmadeeasy==${CERTBOT_PIP_VERSION} \
+ certbot-dns-google==${CERTBOT_PIP_VERSION} \
+ certbot-dns-linode==${CERTBOT_PIP_VERSION} \
+ certbot-dns-luadns==${CERTBOT_PIP_VERSION} \
+ certbot-dns-nsone==${CERTBOT_PIP_VERSION} \
+ certbot-dns-ovh==${CERTBOT_PIP_VERSION} \
+ certbot-dns-rfc2136==${CERTBOT_PIP_VERSION} \
+ certbot-dns-route53==${CERTBOT_PIP_VERSION} && \
+ apk del deps
+
+COPY ./fs/ /
+
+VOLUME "/etc/letsnecrypt"
\ No newline at end of file
diff --git a/README.md b/README.md
index 80482d2..c7dbce3 100644
--- a/README.md
+++ b/README.md
@@ -1,47 +1,56 @@
-[![Project status](https://badgen.net/badge/project%20status/stable%20%26%20actively%20maintaned?color=green)](https://github.com/homecentr/docker-$$IMAGE_NAME$$/graphs/commit-activity) [![](https://badgen.net/github/label-issues/homecentr/docker-$$IMAGE_NAME$$/bug?label=open%20bugs&color=green)](https://github.com/homecentr/docker-$$IMAGE_NAME$$/labels/bug) [![](https://badgen.net/github/release/homecentr/docker-$$IMAGE_NAME$$)](https://hub.docker.com/repository/docker/homecentr/$$IMAGE_NAME$$)
-[![](https://badgen.net/docker/pulls/homecentr/$$IMAGE_NAME$$)](https://hub.docker.com/repository/docker/homecentr/$$IMAGE_NAME$$)
-[![](https://badgen.net/docker/size/homecentr/$$IMAGE_NAME$$)](https://hub.docker.com/repository/docker/homecentr/$$IMAGE_NAME$$)
+[![Project status](https://badgen.net/badge/project%20status/stable%20%26%20actively%20maintaned?color=green)](https://github.com/homecentr/docker-certbot/graphs/commit-activity) [![](https://badgen.net/github/label-issues/homecentr/docker-certbot/bug?label=open%20bugs&color=green)](https://github.com/homecentr/docker-certbot/labels/bug) [![](https://badgen.net/github/release/homecentr/docker-certbot)](https://hub.docker.com/repository/docker/homecentr/certbot)
+[![](https://badgen.net/docker/pulls/homecentr/certbots://hub.docker.com/repository/docker/homecentr/certbot
+[![](https://badgen.net/docker/size/homecentr/certbots://hub.docker.com/repository/docker/homecentr/certbot
-![CI/CD on master](https://github.com/homecentr/docker-$$IMAGE_NAME$$/workflows/CI/CD%20on%20master/badge.svg)
-![Regular Docker image vulnerability scan](https://github.com/homecentr/docker-$$IMAGE_NAME$$/workflows/Regular%20Docker%20image%20vulnerability%20scan/badge.svg)
+![CI/CD on master](https://github.com/homecentr/docker-certbot/CI/CD%20on%20master/badge.svg)
+![Regular Docker image vulnerability scan](https://github.com/homecentr/docker-certbot/Regular%20Docker%20image%20vulnerability%20scan/badge.svg)
-# HomeCentr - $$IMAGE_NAME$$
+# HomeCentr - certbot
+The image contains [Certbot](https://certbot.eff.org/) compliant with the HomeCenter docker images standard (S6 overlay, privilege drop etc.). All DNS plugins endorsed by Certbot are installed ([list](https://certbot.eff.org/docs/using.html#dns-plugins)).
+
+This image is supposed to be used as a single purpose certificate manager. It does not include any reverse proxy. The proxy should be running in a separate container and read the certificates from a mounted volume.
## Usage
```yml
version: "3.7"
services:
- $$IMAGE_NAME$$:
+ certbot
build: .
- image: homecentr/$$IMAGE_NAME$$
+ image: homecentr/certbot
+ # Example uses Cloudflare dns verification, if you use a different provider, you need to adjust the arguments
+ environment:
+ CERTBOT_ARGS: "--email john@doe.com --dns-cloudflare --dns-cloudflare-credentials /secrets/cloudflare.ini"
+ volumes:
+ - cloudflare.ini:/secrets/cloudflare.ini
```
+> If you are just testing/are not 100% sure the arguments are correct, add the `--dry-run` which will not actually make the request to Let's encrypt or `--staging` argument which will use [Let's encrypts staging servers](https://letsencrypt.org/docs/staging-environment/) instead of the production ones. The production servers have low rate limits and running too many unsuccessful requests could **block you out for a week**.
+
## Environment variables
| Name | Default value | Description |
|------|---------------|-------------|
-| PUID | 7077 | UID of the user $$IMAGE_NAME$$ should be running as. |
-| PGID | 7077 | GID of the user $$IMAGE_NAME$$ should be running as. |
+| PUID | 7077 | UID of the user certbot be running as. |
+| PGID | 7077 | GID of the user certbot be running as. |
+| CERTBOT_ARGS | | Additional arguments passed to certbot's `certonly` command. The argument `--agree-tos` is passed automatically, but you have to provide the `--email` argument. |
## Exposed ports
-| Port | Protocol | Description |
-|------|------|-------------|
-| 80 | TCP | Some useful details |
+This image does not expose any ports.
## Volumes
| Container path | Description |
|------------|---------------|
-| /config | Some useful details |
+| /etc/letsencrypt | Contains the provisioned certificates. Please note that the "files" in the `/etc/letsencrypt/*` are just symlinks and therefore when mounting, you need to mount either the whole `/etc/letsencrypt/` directory or mount both `/etc/letsencrypt/live` and `/etc/letsencrypt/archive` on same relative levels. |
## Security
-The container is regularly scanned for vulnerabilities and updated. Further info can be found in the [Security tab](https://github.com/homecentr/docker-$$IMAGE_NAME$$/security).
+The container is regularly scanned for vulnerabilities and updated. Further info can be found in the [Security tab](https://github.com/homecentr/docker-certbot).
### Container user
-The container supports privilege drop. Even though the container starts as root, it will use the permissions only to perform the initial set up. The $$IMAGE_NAME$$ process runs as UID/GID provided in the PUID and PGID environment variables.
+The container supports privilege drop. Even though the container starts as root, it will use the permissions only to perform the initial set up. The certbots runs as UID/GID provided in the PUID and PGID environment variables.
:warning: Do not change the container user directly using the `user` Docker compose property or using the `--user` argument. This would break the privilege drop logic.
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
index 980a102..f82a2d3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,6 +1,6 @@
version: "3.7"
services:
- $$IMAGE_NAME$$:
+ certbot:
build: .
- image: homecentr/$$IMAGE_NAME$$
+ image: homecentr/certbot
restart: unless-stopped
\ No newline at end of file
diff --git a/fs/cron/cron-tick b/fs/cron/cron-tick
new file mode 100644
index 0000000..f5f8bca
--- /dev/null
+++ b/fs/cron/cron-tick
@@ -0,0 +1,3 @@
+#!/usr/bin/env ash
+
+certbot certonly --agree-tos --non-interactive --no-permissions-check $CERTBOT_ARGS
\ No newline at end of file
diff --git a/fs/etc/cont-init.d/98-verify-args.sh b/fs/etc/cont-init.d/98-verify-args.sh
new file mode 100644
index 0000000..9d867f1
--- /dev/null
+++ b/fs/etc/cont-init.d/98-verify-args.sh
@@ -0,0 +1,5 @@
+#!/usr/bin/with-contenv ash
+
+if [[ "$CERTBOT_ARGS" != *"--email"* ]]; then
+ echo "The CERTBOT_ARGS variable must contain '--email' as certbot is executed in a non-interactive way."
+fi
\ No newline at end of file
diff --git a/fs/etc/cont-init.d/99-first-execution.sh b/fs/etc/cont-init.d/99-first-execution.sh
new file mode 100644
index 0000000..78d1415
--- /dev/null
+++ b/fs/etc/cont-init.d/99-first-execution.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/with-contenv ash
+
+echo "Executing the certbot immediately to ensure the certificate exists..."
+cron-tick-execute
\ No newline at end of file
diff --git a/package.json b/package.json
index 753e3e2..3b8ac48 100644
--- a/package.json
+++ b/package.json
@@ -1,15 +1,15 @@
{
- "name": "homecentr-$$IMAGE_NAME$$",
+ "name": "homecentr-certbot",
"version": "1.0.0",
"description": "",
"repository": {
"type": "git",
- "url": "git+https://github.com/homecentr/docker-$$IMAGE_NAME$$.git"
+ "url": "git+https://github.com/homecentr/docker-certbot"
},
"author": "",
"license": "MIT",
"bugs": {
- "url": "https://github.com/homecentr/docker-$$IMAGE_NAME$$/issues"
+ "url": "https://github.com/homecentr/docker-certbot"
},
- "homepage": "https://github.com/homecentr/docker-$$IMAGE_NAME$$#readme"
+ "homepage": "https://github.com/homecentr/docker-certbot"
}
diff --git a/tests/.idea/compiler.xml b/tests/.idea/compiler.xml
index 098cf64..c35d1b0 100644
--- a/tests/.idea/compiler.xml
+++ b/tests/.idea/compiler.xml
@@ -2,8 +2,8 @@
-
-
+
+
\ No newline at end of file
diff --git a/tests/.idea/dictionaries/lholota.xml b/tests/.idea/dictionaries/lholota.xml
new file mode 100644
index 0000000..6798fcb
--- /dev/null
+++ b/tests/.idea/dictionaries/lholota.xml
@@ -0,0 +1,7 @@
+
+
+
+ cloudflare
+
+
+
\ No newline at end of file
diff --git a/tests/.idea/jarRepositories.xml b/tests/.idea/jarRepositories.xml
index fdc392f..5060e6b 100644
--- a/tests/.idea/jarRepositories.xml
+++ b/tests/.idea/jarRepositories.xml
@@ -16,5 +16,10 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/.project b/tests/.project
index 215fa44..08f8891 100644
--- a/tests/.project
+++ b/tests/.project
@@ -1,6 +1,6 @@
- docker-$$IMAGE_NAME$$-tests
+ docker-certbot-tests
Project tests created by Buildship.
diff --git a/tests/.settings/org.eclipse.buildship.core.prefs b/tests/.settings/org.eclipse.buildship.core.prefs
index e889521..836b833 100644
--- a/tests/.settings/org.eclipse.buildship.core.prefs
+++ b/tests/.settings/org.eclipse.buildship.core.prefs
@@ -1,2 +1,13 @@
+arguments=
+auto.sync=false
+build.scans.enabled=false
+connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
connection.project.dir=
eclipse.preferences.version=1
+gradle.user.home=
+java.home=C\:/Program Files/Java/jdk1.8.0_231
+jvm.arguments=
+offline.mode=false
+override.workspace.settings=true
+show.console.view=true
+show.executions.view=true
diff --git a/tests/build.gradle b/tests/build.gradle
index 6e9f6cc..4aae5e7 100644
--- a/tests/build.gradle
+++ b/tests/build.gradle
@@ -9,17 +9,25 @@ sourceCompatibility = 1.8
repositories {
mavenCentral()
+ maven {
+ url "https://dl.bintray.com/homecentr/maven"
+ }
}
dependencies {
testImplementation group: 'junit', name: 'junit', version: '4.13'
- testImplementation "org.testcontainers:testcontainers:1.14.2"
+ testImplementation 'org.testcontainers:testcontainers:1.14.2'
+ testImplementation 'io.homecentr:testcontainers-extensions:1.3.1'
testImplementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.30'
testImplementation group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.30'
}
test {
- systemProperty 'image_tag', System.getProperty('image_tag')
+ systemProperty 'docker_image_tag', System.getProperty('docker_image_tag')
+ systemProperty 'root_domain', System.getProperty('root_domain')
+ systemProperty 'acme_email', System.getProperty('acme_email')
+ systemProperty 'cloudflare_token', System.getProperty('cloudflare_token')
+
afterTest { desc, result ->
logger.quiet "Executing test ${desc.name} [${desc.className}] with result: ${result.resultType}"
}
diff --git a/tests/src/test/java/CertbotContainerShould.java b/tests/src/test/java/CertbotContainerShould.java
new file mode 100644
index 0000000..4b2a5fc
--- /dev/null
+++ b/tests/src/test/java/CertbotContainerShould.java
@@ -0,0 +1,70 @@
+import helpers.CertbotDockerTagResolver;
+import io.homecentr.testcontainers.containers.GenericContainerEx;
+import io.homecentr.testcontainers.containers.wait.strategy.WaitEx;
+import io.homecentr.testcontainers.images.PullPolicyEx;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+
+import java.io.IOException;
+import java.time.Duration;
+
+import static io.homecentr.testcontainers.WaitLoop.waitFor;
+import static org.junit.Assert.assertTrue;
+
+public class CertbotContainerShould {
+ private static final Logger logger = LoggerFactory.getLogger(CertbotContainerShould.class);
+
+ private static GenericContainerEx _certbotContainer;
+ private static TestConfiguration _testConfig;
+
+ @BeforeClass
+ public static void before() throws Exception {
+ _testConfig = TestConfiguration.create();
+ _testConfig.createCredentialsSecretFile();
+
+ _certbotContainer = new GenericContainerEx<>(new CertbotDockerTagResolver())
+ .withEnv("CRON_SCHEDULE", "* * * * *")
+ .withEnv("CERTBOT_ARGS", _testConfig.getCertbotArgs())
+ .withFileSystemBind(TestConfiguration.cloudflareCredentialsHostPath, TestConfiguration.cloudflareCredentialsContainerPath)
+ .withImagePullPolicy(PullPolicyEx.never())
+ .waitingFor(WaitEx.forS6OverlayStart());
+
+ _certbotContainer.start();
+ _certbotContainer.followOutput(new Slf4jLogConsumer(logger));
+
+ waitFor(Duration.ofSeconds(80), () -> _certbotContainer.getLogsAnalyzer().contains("Execution finished"));
+ }
+
+ @AfterClass
+ public static void after() {
+ _certbotContainer.close();
+ }
+
+ @Test
+ public void createCertificateFullChainFile() throws IOException, InterruptedException {
+ assertTrue(fileExists(String.format("/etc/letsencrypt/live/%s/fullchain.pem", _testConfig.getDomain())));
+ }
+
+ @Test
+ public void createCertificateChainFile() throws IOException, InterruptedException {
+ assertTrue(fileExists(String.format("/etc/letsencrypt/live/%s/chain.pem", _testConfig.getDomain())));
+ }
+
+ @Test
+ public void createPrivateKeyFile() throws IOException, InterruptedException {
+ assertTrue(fileExists(String.format("/etc/letsencrypt/live/%s/privkey.pem", _testConfig.getDomain())));
+ }
+
+ @Test
+ public void createPublicKeyFile() throws IOException, InterruptedException {
+ assertTrue(fileExists(String.format("/etc/letsencrypt/live/%s/cert.pem", _testConfig.getDomain())));
+ }
+
+ private boolean fileExists(String fileNamePattern) throws IOException, InterruptedException {
+ return _certbotContainer.execInContainer("ls", fileNamePattern).getExitCode() == 0;
+ }
+}
diff --git a/tests/src/test/java/CertbotContainerWithoutEmailShould.java b/tests/src/test/java/CertbotContainerWithoutEmailShould.java
new file mode 100644
index 0000000..8ce425b
--- /dev/null
+++ b/tests/src/test/java/CertbotContainerWithoutEmailShould.java
@@ -0,0 +1,50 @@
+import helpers.CertbotDockerTagResolver;
+import io.homecentr.testcontainers.containers.GenericContainerEx;
+import io.homecentr.testcontainers.containers.wait.strategy.WaitEx;
+import io.homecentr.testcontainers.images.PullPolicyEx;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testcontainers.containers.output.Slf4jLogConsumer;
+
+import java.time.Duration;
+
+import static io.homecentr.testcontainers.WaitLoop.waitFor;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class CertbotContainerWithoutEmailShould {
+ private static final Logger logger = LoggerFactory.getLogger(CertbotContainerWithoutEmailShould.class);
+
+ private static GenericContainerEx _certbotContainer;
+
+ @BeforeClass
+ public static void before() {
+ _certbotContainer = new GenericContainerEx<>(new CertbotDockerTagResolver())
+ .withEnv("CRON_SCHEDULE", "* * * * *")
+ .withEnv("CERTBOT_ARGS", "")
+ .withFileSystemBind(TestConfiguration.cloudflareCredentialsHostPath, TestConfiguration.cloudflareCredentialsContainerPath)
+ .withImagePullPolicy(PullPolicyEx.never())
+ .waitingFor(WaitEx.forS6OverlayStart());
+
+ _certbotContainer.start();
+ _certbotContainer.followOutput(new Slf4jLogConsumer(logger));
+ }
+
+ @AfterClass
+ public static void after() {
+ _certbotContainer.close();
+ }
+
+ @Test
+ public void printWarning() {
+ assertTrue(_certbotContainer.getLogsAnalyzer().contains("The CERTBOT_ARGS variable must contain '--email'"));
+ }
+
+ @Test
+ public void exitContainer() throws Exception {
+ waitFor(Duration.ofSeconds(20), () -> _certbotContainer.isRunning());
+ }
+}
diff --git a/tests/src/test/java/TestConfiguration.java b/tests/src/test/java/TestConfiguration.java
new file mode 100644
index 0000000..9dfb743
--- /dev/null
+++ b/tests/src/test/java/TestConfiguration.java
@@ -0,0 +1,53 @@
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.UUID;
+
+public class TestConfiguration {
+ private final String _randomPrefix;
+
+ public static final String cloudflareCredentialsContainerPath = "/config/cloudflare.init.tmp";
+ public static final String cloudflareCredentialsHostPath = Paths.get(System.getProperty("user.dir"), "..", "cloudflare.init.tmp").normalize().toString();
+
+ public static TestConfiguration create() {
+ String prefix = UUID.randomUUID().toString();
+
+ return new TestConfiguration(prefix);
+ }
+
+
+ private TestConfiguration(String randomPrefix) {
+ _randomPrefix = randomPrefix;
+ }
+
+ public String getDomain() {
+ return String.format("%s.%s", _randomPrefix, getRootDomain());
+ }
+
+ public String getCertbotArgs() {
+ return String.format("--email %s --staging --dns-cloudflare --dns-cloudflare-credentials %s -d %s",
+ getEmail(),
+ cloudflareCredentialsContainerPath,
+ getDomain());
+ }
+
+ public void createCredentialsSecretFile() throws IOException {
+ try (BufferedWriter writer = new BufferedWriter(new FileWriter(cloudflareCredentialsHostPath))) {
+ writer.write("dns_cloudflare_api_token = " + getCloudflareToken());
+ writer.flush();
+ }
+ }
+
+ private String getCloudflareToken() {
+ return System.getProperty("cloudflare_token");
+ }
+
+ private String getEmail() {
+ return System.getProperty("acme_email");
+ }
+
+ private String getRootDomain() {
+ return System.getProperty("root_domain");
+ }
+}
diff --git a/tests/src/test/java/helpers/CertbotDockerTagResolver.java b/tests/src/test/java/helpers/CertbotDockerTagResolver.java
new file mode 100644
index 0000000..67d12ca
--- /dev/null
+++ b/tests/src/test/java/helpers/CertbotDockerTagResolver.java
@@ -0,0 +1,9 @@
+package helpers;
+
+import io.homecentr.testcontainers.images.EnvironmentImageTagResolver;
+
+public class CertbotDockerTagResolver extends EnvironmentImageTagResolver {
+ public CertbotDockerTagResolver() {
+ super("homecentr/certbot:local");
+ }
+}