diff --git a/.dockerignore b/.dockerignore
index ea8c4bf..730e8dc 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -1 +1,3 @@
 /target
+Dockerfile
+/data
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 93e9898..10def10 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 /target
 debug.log
-frontend/dist/
\ No newline at end of file
+frontend/dist/
+/data
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..4c4019e
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,56 @@
+FROM docker.io/library/rust:1-alpine AS chef 
+RUN apk add --no-cache musl-dev openssl-dev openssl-libs-static git pkgconf
+RUN cargo install cargo-chef
+RUN cargo install trunk
+RUN rustup target add wasm32-unknown-unknown
+WORKDIR /app
+
+FROM chef AS planner-peazyrsa
+RUN git clone https://gitea.b4tman.ru/b4tman/peazyrsa -b v0.1.0 --depth 1 .
+RUN cargo chef prepare  --recipe-path recipe.json
+
+FROM chef AS builder-peazyrsa
+COPY --from=planner-peazyrsa /app/recipe.json recipe.json
+RUN cargo chef cook --release --recipe-path recipe.json
+RUN git clone https://gitea.b4tman.ru/b4tman/peazyrsa -b v0.1.0 --depth 1 peazyrsa
+RUN cp -af peazyrsa/* . && rm -rf peazyrsa
+RUN cargo build --release
+
+FROM chef AS planner-peasyweb
+COPY . .
+RUN cargo chef prepare --recipe-path recipe.json
+
+FROM chef AS builder-peasyweb
+COPY --from=planner-peasyweb /app/recipe.json recipe.json
+RUN cargo chef cook --release --recipe-path recipe.json
+COPY . .
+ENV API_BASE_URL="/api/v1"
+RUN cargo build -p peazyweb-backend --release
+WORKDIR /app/frontend
+RUN trunk build --release --public-url "/frontend"
+
+WORKDIR /app
+
+FROM docker.io/library/alpine:3.21 AS runtime
+RUN apk add --no-cache openssl libssl3 libcrypto3
+RUN mkdir -p /app/frontend
+RUN mkdir /data
+WORKDIR /app
+COPY --from=builder-peazyrsa /app/target/release/peazyrsa /usr/local/bin/peazyrsa
+COPY --from=builder-peasyweb /app/target/release/peazyweb-backend /usr/local/bin/peazyweb-backend
+COPY --from=builder-peasyweb /app/frontend/dist/ /app/frontend
+
+VOLUME [ "/data" ]
+
+ENV GENERATION_BASE_DIRECTORY="/data"
+ENV GENERATION_BIN="/usr/local/bin/peazyrsa"
+ENV USE_OPENSSL="yes"
+ENV OPENSSL_BIN="/usr/bin/openssl"
+ENV FRONTEND_BASE="/app/frontend"
+
+ENV ROCKET_ADDRESS="0.0.0.0"
+ENV ROCKET_PORT=80
+
+EXPOSE 80
+
+ENTRYPOINT ["/usr/local/bin/peazyweb-backend"]
\ No newline at end of file
diff --git a/backend/src/main.rs b/backend/src/main.rs
index da280fd..e4544e7 100644
--- a/backend/src/main.rs
+++ b/backend/src/main.rs
@@ -210,10 +210,14 @@ async fn frontend(path: PathBuf) -> Option<NamedFile> {
     let frontend_base = env::var("FRONTEND_BASE").unwrap_or("../frontend/dist/".into());
     let frontend_path = Path::new(&frontend_base).join(path);
     let frontend_index_path = Path::new(&frontend_base).join("index.html");
-    NamedFile::open(frontend_path)
-        .await
-        .or(NamedFile::open(frontend_index_path).await)
-        .ok()
+
+    match tokio::fs::metadata(&frontend_path).await {
+        Ok(meta) if meta.is_file() => NamedFile::open(frontend_path)
+            .await
+            .or(NamedFile::open(frontend_index_path).await)
+            .ok(),
+        _ => NamedFile::open(&frontend_index_path).await.ok(),
+    }
 }
 
 #[launch]