From 7438083a7c5426e213bbaeb2dbd4d9676021d307 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Thu, 12 Sep 2024 20:26:23 +0200 Subject: [PATCH 01/11] feat: create a Docker compose stack for production --- docker-compose-prod.yml | 20 ++++++++++++++++++++ docker/prod/app/Dockerfile | 22 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 docker/prod/app/Dockerfile diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index e69de29..9787294 100755 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -0,0 +1,20 @@ +services: + app: + build: + dockerfile: docker/prod/app/Dockerfile + restart: always + ports: [ "8000:8000" ] + depends_on: [ "db" ] + + db: + image: postgres:16.4-bookworm + volumes: [ "db_data:/var/lib/postgresql/data" ] + ports: [ "5432:5432" ] + environment: + POSTGRES_DB: todo_baggins + POSTGRES_USER: app + POSTGRES_PASSWORD: app + restart: always + +volumes: + db_data: diff --git a/docker/prod/app/Dockerfile b/docker/prod/app/Dockerfile new file mode 100644 index 0000000..972a08b --- /dev/null +++ b/docker/prod/app/Dockerfile @@ -0,0 +1,22 @@ +FROM rust:1.80-bookworm as builder + +RUN rustup target add wasm32-unknown-unknown && \ + cargo install dioxus-cli diesel_cli && \ + apt-get update && apt-get install -y nodejs=18.19.0+dfsg-6~deb12u2 npm=9.2.0~ds1-1 supervisor=4.2.5-1 + +COPY . /srv/app +WORKDIR /srv/app + +RUN npm install +RUN npm run build +RUN dx build --release + +FROM debian:bookworm-slim AS runner + +RUN apt-get update && apt-get install -y libpq5 + +COPY --from=builder /srv/app/dist /srv/app/dist +COPY ./.env /srv/app/.env + +WORKDIR /srv/app +CMD ["./dist/todo-baggins"] -- 2.47.1 From cccfc9671b168a26ff1120ea0332358796a14d62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:22:33 +0200 Subject: [PATCH 02/11] feat: connect the production Docker compose stack to the web server network --- docker-compose-prod.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index 9787294..bd39f65 100755 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -5,6 +5,8 @@ services: restart: always ports: [ "8000:8000" ] depends_on: [ "db" ] + networks: + - web-server-network db: image: postgres:16.4-bookworm @@ -18,3 +20,7 @@ services: volumes: db_data: + +networks: + web-server-network: + external: true -- 2.47.1 From bbda8a4eeac5f032adfb3cc7acd2b0ab46ca3b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 07:24:01 +0200 Subject: [PATCH 03/11] feat: do not map the local port to the production app Docker container --- docker-compose-prod.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index bd39f65..ec55b16 100755 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -3,7 +3,6 @@ services: build: dockerfile: docker/prod/app/Dockerfile restart: always - ports: [ "8000:8000" ] depends_on: [ "db" ] networks: - web-server-network -- 2.47.1 From 27148de77c40b0687fe4f4c1663f41d9b8d2ca6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 08:40:38 +0200 Subject: [PATCH 04/11] build: add diesel_migrations to dependencies --- Cargo.lock | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + 2 files changed, 86 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 4aeb4c6..59f64c8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -687,6 +687,17 @@ dependencies = [ "syn 2.0.74", ] +[[package]] +name = "diesel_migrations" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a73ce704bad4231f001bff3314d91dce4aba0770cee8b233991859abc15c1f6" +dependencies = [ + "diesel", + "migrations_internals", + "migrations_macros", +] + [[package]] name = "diesel_table_macro_syntax" version = "0.2.0" @@ -2028,6 +2039,27 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "migrations_internals" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" +dependencies = [ + "serde", + "toml", +] + +[[package]] +name = "migrations_macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb161cc72176cb37aa47f1fc520d3ef02263d67d661f44f05d05a079e1237fd" +dependencies = [ + "migrations_internals", + "proc-macro2", + "quote", +] + [[package]] name = "mime" version = "0.3.17" @@ -2575,6 +2607,15 @@ dependencies = [ "syn 2.0.74", ] +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2944,6 +2985,7 @@ dependencies = [ "async-std", "chrono", "diesel", + "diesel_migrations", "dioxus", "dioxus-logger", "dioxus-query", @@ -3028,6 +3070,40 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap 2.4.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -3625,6 +3701,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + [[package]] name = "xxhash-rust" version = "0.8.12" diff --git a/Cargo.toml b/Cargo.toml index b43ab51..3ba6c40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ time = "0.3.36" dioxus-sdk = { version = "0.5.0", features = ["i18n"] } unic-langid-impl = "0.9.5" voca_rs = "1.15.2" +diesel_migrations = { version = "2.2.0", features = ["postgres"] } [features] default = [] -- 2.47.1 From baa8ce6bab432c7b8560699105a3165675584a24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 08:41:25 +0200 Subject: [PATCH 05/11] feat: run pending migrations on app start --- src/main.rs | 9 ++++++--- src/migrations/mod.rs | 12 ++++++++++++ src/server/mod.rs | 2 +- 3 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 src/migrations/mod.rs diff --git a/src/main.rs b/src/main.rs index 7324db6..46b9f31 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,18 +7,21 @@ mod server; mod query; mod utils; mod internationalization; +mod migrations; use components::app::App; use dioxus::prelude::*; use dioxus_logger::tracing::{info, Level}; fn main() { - dioxus_logger::init(Level::INFO).expect("failed to initialize logger"); - info!("starting app"); + dioxus_logger::init(Level::INFO).expect("Failed to initialize the logger."); + info!("Running migrations."); + migrations::run_migrations().expect("Failed to run migrations."); + + info!("Starting app."); let cfg = server_only!( dioxus::fullstack::Config::new().addr(std::net::SocketAddr::from(([0, 0, 0, 0], 8000))) ); - LaunchBuilder::fullstack().with_cfg(cfg).launch(App); } diff --git a/src/migrations/mod.rs b/src/migrations/mod.rs new file mode 100644 index 0000000..9fadaae --- /dev/null +++ b/src/migrations/mod.rs @@ -0,0 +1,12 @@ +use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; +use std::error::Error; + +const MIGRATIONS: EmbeddedMigrations = embed_migrations!("migrations"); + +pub(crate) fn run_migrations() -> Result<(), Box> { + let mut connection = crate::server::database_connection::establish_database_connection()?; + + connection.run_pending_migrations(MIGRATIONS)?; + + Ok(()) +} diff --git a/src/server/mod.rs b/src/server/mod.rs index 50ad1c8..634d217 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -1,4 +1,4 @@ -mod database_connection; +pub(crate) mod database_connection; pub(crate) mod projects; pub(crate) mod tasks; pub(crate) mod subtasks; -- 2.47.1 From 16dad65ed78574b21e33aea3c4135a287d468a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:09:20 +0200 Subject: [PATCH 06/11] feat: do not map the local port to the production database Docker container --- docker-compose-prod.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index ec55b16..f63192b 100755 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -10,7 +10,6 @@ services: db: image: postgres:16.4-bookworm volumes: [ "db_data:/var/lib/postgresql/data" ] - ports: [ "5432:5432" ] environment: POSTGRES_DB: todo_baggins POSTGRES_USER: app -- 2.47.1 From 76dc47fcdbb8674b1c37648fc2e1377c04250fab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:10:20 +0200 Subject: [PATCH 07/11] fix: only run the pending migrations on server --- docker/dev/app/entrypoint.sh | 2 -- src/main.rs | 4 +++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/dev/app/entrypoint.sh b/docker/dev/app/entrypoint.sh index 3da5abe..5f92f1f 100755 --- a/docker/dev/app/entrypoint.sh +++ b/docker/dev/app/entrypoint.sh @@ -1,5 +1,3 @@ #!/bin/bash -diesel migration run - supervisord -c /etc/supervisor/conf.d/supervisord.conf diff --git a/src/main.rs b/src/main.rs index 46b9f31..bc47bdd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,7 +17,9 @@ fn main() { dioxus_logger::init(Level::INFO).expect("Failed to initialize the logger."); info!("Running migrations."); - migrations::run_migrations().expect("Failed to run migrations."); + server_only!( + migrations::run_migrations().expect("Failed to run migrations."); + ); info!("Starting app."); let cfg = server_only!( -- 2.47.1 From ba3c955b49a3b211a492b02a96e6740f84b5ae2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:11:04 +0200 Subject: [PATCH 08/11] build: optimize the production Dockerfile --- docker/prod/app/Dockerfile | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/docker/prod/app/Dockerfile b/docker/prod/app/Dockerfile index 972a08b..54b676f 100644 --- a/docker/prod/app/Dockerfile +++ b/docker/prod/app/Dockerfile @@ -1,4 +1,4 @@ -FROM rust:1.80-bookworm as builder +FROM rust:1.80-bookworm AS builder RUN rustup target add wasm32-unknown-unknown && \ cargo install dioxus-cli diesel_cli && \ @@ -16,7 +16,14 @@ FROM debian:bookworm-slim AS runner RUN apt-get update && apt-get install -y libpq5 COPY --from=builder /srv/app/dist /srv/app/dist -COPY ./.env /srv/app/.env +COPY .env /srv/app/.env + +RUN chown -R 1000:1000 /srv/app WORKDIR /srv/app + +HEALTHCHECK CMD curl --fail http://localhost:8000 || exit 1 + +USER 1000:1000 + CMD ["./dist/todo-baggins"] -- 2.47.1 From d868b6a14398466e04ca0ea9ae8a9d513be39281 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:13:10 +0200 Subject: [PATCH 09/11] build: connect the app and database Docker compose services in the production --- docker-compose-prod.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docker-compose-prod.yml b/docker-compose-prod.yml index f63192b..8c8fa7f 100755 --- a/docker-compose-prod.yml +++ b/docker-compose-prod.yml @@ -2,14 +2,17 @@ services: app: build: dockerfile: docker/prod/app/Dockerfile + networks: + - default + - web-server-network restart: always depends_on: [ "db" ] - networks: - - web-server-network db: image: postgres:16.4-bookworm volumes: [ "db_data:/var/lib/postgresql/data" ] + networks: + - default environment: POSTGRES_DB: todo_baggins POSTGRES_USER: app -- 2.47.1 From b98f3d00d6a487d76999137be1d90cb60470df15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 11:15:49 +0200 Subject: [PATCH 10/11] build: pin the package version in the production Dockerfile --- docker/prod/app/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/prod/app/Dockerfile b/docker/prod/app/Dockerfile index 54b676f..6b83d48 100644 --- a/docker/prod/app/Dockerfile +++ b/docker/prod/app/Dockerfile @@ -13,7 +13,7 @@ RUN dx build --release FROM debian:bookworm-slim AS runner -RUN apt-get update && apt-get install -y libpq5 +RUN apt-get update && apt-get install -y libpq5=15.8-0+deb12u1 COPY --from=builder /srv/app/dist /srv/app/dist COPY .env /srv/app/.env -- 2.47.1 From 0f3a691d29ce3e7f0b23dfa23352b9e8a504d5d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Volf?= <66163112+matous-volf@users.noreply.github.com> Date: Fri, 13 Sep 2024 12:34:52 +0200 Subject: [PATCH 11/11] build: optimize the production Dockerfile --- docker/prod/app/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/prod/app/Dockerfile b/docker/prod/app/Dockerfile index 6b83d48..3f538ef 100644 --- a/docker/prod/app/Dockerfile +++ b/docker/prod/app/Dockerfile @@ -7,9 +7,9 @@ RUN rustup target add wasm32-unknown-unknown && \ COPY . /srv/app WORKDIR /srv/app -RUN npm install -RUN npm run build -RUN dx build --release +RUN npm install && \ + npm run build && \ + dx build --release FROM debian:bookworm-slim AS runner -- 2.47.1