diff --git a/.github/workflows/docker-deploy.yml b/.github/workflows/docker-deploy.yml new file mode 100644 index 0000000..e1fc09a --- /dev/null +++ b/.github/workflows/docker-deploy.yml @@ -0,0 +1,43 @@ +name: Build + +on: + push: + branches: ['ci/docker-integration'] + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + steps: + - name: Checkout repository + uses: actions/checkout@v3 + + - name: Docker Meta + id: meta + uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=semver,pattern={{major}} + type=sha,prefix= + + - name: Login to GitHub Container Registry + uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Build and Push + uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4 + with: + context: ./mailserver/ + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/README.md b/README.md index c5ffedb..5a6fd42 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,11 @@ Kmail is a lightweight mail server solution written in Kotlin. Instead of packin > Kmail is incomplete and under active development! ## Getting Started -Running from outside an IDE is not yet supported. Kmail will be dockerized soon. + +### Docker +`docker pull ghcr.io/lost-illusi0n/kmail:latest` +- map ports `143`, `110`, `587`, `25` +- add volumes that contain your `kmail.toml` and anything else used by Kmail (e.g., certificates) ### Prerequisites For a smooth experience, you will need to: diff --git a/mailserver/.gitignore b/mailserver/.gitignore index 7fa3a06..a5b7a23 100644 --- a/mailserver/.gitignore +++ b/mailserver/.gitignore @@ -1,2 +1,3 @@ .gradle **/build/ +mailserver/compose.yaml \ No newline at end of file diff --git a/mailserver/Dockerfile b/mailserver/Dockerfile new file mode 100644 index 0000000..9ee0e26 --- /dev/null +++ b/mailserver/Dockerfile @@ -0,0 +1,19 @@ +FROM azul/zulu-openjdk-alpine:17-latest AS BUILDER +WORKDIR /build/mailserver +COPY . . +RUN ./gradlew runner:installDist --stacktrace --no-daemon + +FROM azul/zulu-openjdk-alpine:17-jre-headless-latest +WORKDIR /mailserver +COPY --from=BUILDER /build/mailserver/runner/build/install/runner . + +# IMAP +EXPOSE 143 +# POP3 +EXPOSE 110 +# SUBMISSION +EXPOSE 587 +# SMTP +EXPOSE 25 + +ENTRYPOINT [ "/mailserver/bin/runner" ] \ No newline at end of file diff --git a/mailserver/compose.yaml b/mailserver/compose.yaml new file mode 100644 index 0000000..39197d3 --- /dev/null +++ b/mailserver/compose.yaml @@ -0,0 +1,12 @@ +services: + mailserver: + image: ghcr.io/lost-illusi0n/kmail:latest + container_name: kmail_mailserver + volumes: + - ../kmail.toml:/mailserver/kmail.toml + - ../certs:/mailserver/certs + ports: + - 25:25 + - 587:587 + - 110:110 + - 143:143 \ No newline at end of file diff --git a/mailserver/runner/build.gradle.kts b/mailserver/runner/build.gradle.kts index 9e076f7..af40d24 100644 --- a/mailserver/runner/build.gradle.kts +++ b/mailserver/runner/build.gradle.kts @@ -2,7 +2,8 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("multiplatform") + application + kotlin("jvm") kotlin("plugin.serialization") } @@ -12,26 +13,30 @@ repositories { maven("https://jitpack.io") } +application { + mainClass.set("dev.sitar.kmail.runner.LauncherJvmKt") +} + kotlin { - jvm() + jvmToolchain(17) +} - sourceSets["commonMain"].dependencies { - implementation("io.github.microutils:kotlin-logging:3.0.2") - implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.19.0") - implementation("org.apache.logging.log4j:log4j-core:2.19.0") - implementation("org.apache.logging.log4j:log4j-api:2.19.0") +dependencies { + implementation("io.github.microutils:kotlin-logging:3.0.2") + implementation("org.apache.logging.log4j:log4j-slf4j2-impl:2.19.0") + implementation("org.apache.logging.log4j:log4j-core:2.19.0") + implementation("org.apache.logging.log4j:log4j-api:2.19.0") - implementation("io.ktor:ktor-network-tls-certificates:2.1.3") + implementation("io.ktor:ktor-network-tls-certificates:2.1.3") - implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.15.2") - implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2") + implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-toml:2.15.2") + implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.2") - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") - implementation("aws.sdk.kotlin:s3:0.32.0-beta") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4") + implementation("aws.sdk.kotlin:s3:0.32.0-beta") - implementation(project(":smtp-agent")) - implementation(project(":smtp")) - implementation(project(":imap-agent")) - implementation(project(":pop3-agent")) - } + implementation(project(":smtp-agent")) + implementation(project(":smtp")) + implementation(project(":imap-agent")) + implementation(project(":pop3-agent")) } \ No newline at end of file diff --git a/mailserver/runner/src/commonMain/kotlin/config.kt b/mailserver/runner/src/main/kotlin/config.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/config.kt rename to mailserver/runner/src/main/kotlin/config.kt diff --git a/mailserver/runner/src/commonMain/kotlin/consts.kt b/mailserver/runner/src/main/kotlin/consts.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/consts.kt rename to mailserver/runner/src/main/kotlin/consts.kt diff --git a/mailserver/runner/src/commonMain/kotlin/imap.kt b/mailserver/runner/src/main/kotlin/imap.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/imap.kt rename to mailserver/runner/src/main/kotlin/imap.kt diff --git a/mailserver/runner/src/commonMain/kotlin/launcher.kt b/mailserver/runner/src/main/kotlin/launcher.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/launcher.kt rename to mailserver/runner/src/main/kotlin/launcher.kt diff --git a/mailserver/runner/src/jvmMain/kotlin/launcherJvm.kt b/mailserver/runner/src/main/kotlin/launcherJvm.kt similarity index 81% rename from mailserver/runner/src/jvmMain/kotlin/launcherJvm.kt rename to mailserver/runner/src/main/kotlin/launcherJvm.kt index db77d0c..ba16aac 100644 --- a/mailserver/runner/src/jvmMain/kotlin/launcherJvm.kt +++ b/mailserver/runner/src/main/kotlin/launcherJvm.kt @@ -1,13 +1,9 @@ package dev.sitar.kmail.runner -import dev.sitar.kmail.utils.connection.KtorConnectionFactory import dev.sitar.kmail.utils.connection.TlsCapableConnectionFactory import dev.sitar.kmail.utils.server.TlsCapableServerSocketFactory import io.ktor.network.tls.* import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.delay -import java.util.concurrent.Future -import javax.net.ssl.SSLContext suspend fun main(): Unit = coroutineScope { dns() diff --git a/mailserver/runner/src/commonMain/kotlin/pop3.kt b/mailserver/runner/src/main/kotlin/pop3.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/pop3.kt rename to mailserver/runner/src/main/kotlin/pop3.kt diff --git a/mailserver/runner/src/commonMain/kotlin/spam.kt b/mailserver/runner/src/main/kotlin/spam.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/spam.kt rename to mailserver/runner/src/main/kotlin/spam.kt diff --git a/mailserver/runner/src/jvmMain/kotlin/ssl.kt b/mailserver/runner/src/main/kotlin/sslJvm.kt similarity index 98% rename from mailserver/runner/src/jvmMain/kotlin/ssl.kt rename to mailserver/runner/src/main/kotlin/sslJvm.kt index 63c894b..475e43e 100644 --- a/mailserver/runner/src/jvmMain/kotlin/ssl.kt +++ b/mailserver/runner/src/main/kotlin/sslJvm.kt @@ -12,7 +12,6 @@ import java.security.cert.X509Certificate import java.security.spec.PKCS8EncodedKeySpec import javax.net.ssl.KeyManagerFactory import javax.net.ssl.SSLContext -import javax.net.ssl.TrustManager import javax.net.ssl.TrustManagerFactory import javax.net.ssl.X509TrustManager diff --git a/mailserver/runner/src/commonMain/kotlin/storage/Attributable.kt b/mailserver/runner/src/main/kotlin/storage/Attributable.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/Attributable.kt rename to mailserver/runner/src/main/kotlin/storage/Attributable.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/InMemoryStorageLayer.kt b/mailserver/runner/src/main/kotlin/storage/InMemoryStorageLayer.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/InMemoryStorageLayer.kt rename to mailserver/runner/src/main/kotlin/storage/InMemoryStorageLayer.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/KmailStorageLayer.kt b/mailserver/runner/src/main/kotlin/storage/KmailStorageLayer.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/KmailStorageLayer.kt rename to mailserver/runner/src/main/kotlin/storage/KmailStorageLayer.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/StorageLayer.kt b/mailserver/runner/src/main/kotlin/storage/StorageLayer.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/StorageLayer.kt rename to mailserver/runner/src/main/kotlin/storage/StorageLayer.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/filesystems/cached.kt b/mailserver/runner/src/main/kotlin/storage/filesystems/cached.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/filesystems/cached.kt rename to mailserver/runner/src/main/kotlin/storage/filesystems/cached.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/filesystems/filesystem.kt b/mailserver/runner/src/main/kotlin/storage/filesystems/filesystem.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/filesystems/filesystem.kt rename to mailserver/runner/src/main/kotlin/storage/filesystems/filesystem.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/filesystems/local.kt b/mailserver/runner/src/main/kotlin/storage/filesystems/local.kt similarity index 51% rename from mailserver/runner/src/commonMain/kotlin/storage/filesystems/local.kt rename to mailserver/runner/src/main/kotlin/storage/filesystems/local.kt index 8f6c0fe..5a953c9 100644 --- a/mailserver/runner/src/commonMain/kotlin/storage/filesystems/local.kt +++ b/mailserver/runner/src/main/kotlin/storage/filesystems/local.kt @@ -2,4 +2,4 @@ package dev.sitar.kmail.runner.storage.filesystems import dev.sitar.kmail.runner.KmailConfig -expect class LocalFileSystem(config: KmailConfig.Mailbox.Filesystem.Local): FileSystem \ No newline at end of file +//expect class LocalFileSystem(config: KmailConfig.Mailbox.Filesystem.Local): FileSystem \ No newline at end of file diff --git a/mailserver/runner/src/jvmMain/kotlin/storage/filesystems/local.kt b/mailserver/runner/src/main/kotlin/storage/filesystems/localJvm.kt similarity index 95% rename from mailserver/runner/src/jvmMain/kotlin/storage/filesystems/local.kt rename to mailserver/runner/src/main/kotlin/storage/filesystems/localJvm.kt index ed341b0..5394f73 100644 --- a/mailserver/runner/src/jvmMain/kotlin/storage/filesystems/local.kt +++ b/mailserver/runner/src/main/kotlin/storage/filesystems/localJvm.kt @@ -5,7 +5,7 @@ import dev.sitar.kmail.runner.storage.Attributable import dev.sitar.kmail.runner.storage.Attributes import java.io.File -actual class LocalFileSystem actual constructor(val config: KmailConfig.Mailbox.Filesystem.Local): FileSystem { +class LocalFileSystem(val config: KmailConfig.Mailbox.Filesystem.Local): FileSystem { val root = File(config.dir) override suspend fun init() { diff --git a/mailserver/runner/src/commonMain/kotlin/storage/filesystems/memory.kt b/mailserver/runner/src/main/kotlin/storage/filesystems/memory.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/filesystems/memory.kt rename to mailserver/runner/src/main/kotlin/storage/filesystems/memory.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/filesystems/s3.kt b/mailserver/runner/src/main/kotlin/storage/filesystems/s3.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/filesystems/s3.kt rename to mailserver/runner/src/main/kotlin/storage/filesystems/s3.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/formats/format.kt b/mailserver/runner/src/main/kotlin/storage/formats/format.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/formats/format.kt rename to mailserver/runner/src/main/kotlin/storage/formats/format.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/formats/maildir.kt b/mailserver/runner/src/main/kotlin/storage/formats/maildir.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/storage/formats/maildir.kt rename to mailserver/runner/src/main/kotlin/storage/formats/maildir.kt diff --git a/mailserver/runner/src/commonMain/kotlin/storage/storage.kt b/mailserver/runner/src/main/kotlin/storage/storage.kt similarity index 92% rename from mailserver/runner/src/commonMain/kotlin/storage/storage.kt rename to mailserver/runner/src/main/kotlin/storage/storage.kt index 1617388..af5baac 100644 --- a/mailserver/runner/src/commonMain/kotlin/storage/storage.kt +++ b/mailserver/runner/src/main/kotlin/storage/storage.kt @@ -19,14 +19,20 @@ import mu.KotlinLogging private val logger = KotlinLogging.logger { } suspend fun CoroutineScope.mailbox(incoming: Flow): StorageLayer { + logger.info { "initiating filesystem" } + val filesystem = when (Config.mailbox.filesystem) { is KmailConfig.Mailbox.Filesystem.InMemory -> InMemoryFileSystem() is KmailConfig.Mailbox.Filesystem.Local -> LocalFileSystem(Config.mailbox.filesystem) is KmailConfig.Mailbox.Filesystem.S3 -> S3FileSystem(Config.mailbox.filesystem) } + logger.info { "detected a ${Config.mailbox.filesystem} filesystem" } + filesystem.init() + logger.info { "initiated filesystem" } + val storage = KmailStorageLayer(CachedFileSystem(filesystem)) launch { diff --git a/mailserver/runner/src/commonMain/kotlin/submission.kt b/mailserver/runner/src/main/kotlin/submission.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/submission.kt rename to mailserver/runner/src/main/kotlin/submission.kt diff --git a/mailserver/runner/src/commonMain/kotlin/transfer.kt b/mailserver/runner/src/main/kotlin/transfer.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/transfer.kt rename to mailserver/runner/src/main/kotlin/transfer.kt diff --git a/mailserver/runner/src/commonMain/kotlin/verifications.kt b/mailserver/runner/src/main/kotlin/verifications.kt similarity index 100% rename from mailserver/runner/src/commonMain/kotlin/verifications.kt rename to mailserver/runner/src/main/kotlin/verifications.kt diff --git a/mailserver/runner/src/jvmMain/resources/log4j2.xml b/mailserver/runner/src/main/resources/log4j2.xml similarity index 100% rename from mailserver/runner/src/jvmMain/resources/log4j2.xml rename to mailserver/runner/src/main/resources/log4j2.xml