mirror of
https://github.com/mvvasilev/findtheti.me.git
synced 2025-04-11 18:15:01 +03:00
Add Dockerfile
This commit is contained in:
parent
fe035c3dc3
commit
817c742d09
13 changed files with 497 additions and 1 deletions
64
.sqlx/query-1db35e76adcb0ed4de84b8296efe9b2a8409e92eebee83150ee8f57fa20728f4.json
generated
Normal file
64
.sqlx/query-1db35e76adcb0ed4de84b8296efe9b2a8409e92eebee83150ee8f57fa20728f4.json
generated
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT * FROM events.event\n WHERE id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "event_type",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "description",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "snowflake_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "from_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "to_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "duration",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "1db35e76adcb0ed4de84b8296efe9b2a8409e92eebee83150ee8f57fa20728f4"
|
||||
}
|
27
.sqlx/query-2aac7a200b3c65e8d406e4844c14418eeb22faa0bc9cb7e2877a1407a242afe0.json
generated
Normal file
27
.sqlx/query-2aac7a200b3c65e8d406e4844c14418eeb22faa0bc9cb7e2877a1407a242afe0.json
generated
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO events.availability (event_id, from_date, to_date, user_email, user_ip, user_name)\n VALUES ($1, $2, $3, $4, $5, $6)\n RETURNING id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8",
|
||||
"Timestamp",
|
||||
"Timestamp",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "2aac7a200b3c65e8d406e4844c14418eeb22faa0bc9cb7e2877a1407a242afe0"
|
||||
}
|
28
.sqlx/query-4437b6962ab26de280e4aecc39db5817581f05528ced1856b2a974e7767b8af7.json
generated
Normal file
28
.sqlx/query-4437b6962ab26de280e4aecc39db5817581f05528ced1856b2a974e7767b8af7.json
generated
Normal file
|
@ -0,0 +1,28 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n INSERT INTO events.event (snowflake_id, name, description, from_date, to_date, event_type, duration)\n VALUES ($1, $2, $3, $4, $5, $6, $7)\n RETURNING id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Varchar",
|
||||
"Timestamp",
|
||||
"Timestamp",
|
||||
"Varchar",
|
||||
"Int4"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "4437b6962ab26de280e4aecc39db5817581f05528ced1856b2a974e7767b8af7"
|
||||
}
|
58
.sqlx/query-44fb63d566bb22d02ef6a0583fc1b7289f16549b24aeb49af2632f3c743a5076.json
generated
Normal file
58
.sqlx/query-44fb63d566bb22d02ef6a0583fc1b7289f16549b24aeb49af2632f3c743a5076.json
generated
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT a.*\n FROM events.availability AS a\n JOIN events.event AS e ON e.id = a.event_id\n WHERE e.snowflake_id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "event_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "from_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "to_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "user_email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "user_name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "user_ip",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "44fb63d566bb22d02ef6a0583fc1b7289f16549b24aeb49af2632f3c743a5076"
|
||||
}
|
64
.sqlx/query-761513e437e36f444040e6f375e867ebeaf9a921f0e95e8ade09f14899409c58.json
generated
Normal file
64
.sqlx/query-761513e437e36f444040e6f375e867ebeaf9a921f0e95e8ade09f14899409c58.json
generated
Normal file
|
@ -0,0 +1,64 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT * FROM events.event\n WHERE snowflake_id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "event_type",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "description",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "snowflake_id",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "from_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "to_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 7,
|
||||
"name": "duration",
|
||||
"type_info": "Int4"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Text"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "761513e437e36f444040e6f375e867ebeaf9a921f0e95e8ade09f14899409c58"
|
||||
}
|
58
.sqlx/query-d13c89523084d914be6e6250b2738e835447bd3478ec50245eca833e476fd9bf.json
generated
Normal file
58
.sqlx/query-d13c89523084d914be6e6250b2738e835447bd3478ec50245eca833e476fd9bf.json
generated
Normal file
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"db_name": "PostgreSQL",
|
||||
"query": "\n SELECT *\n FROM events.availability\n WHERE event_id = $1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"ordinal": 0,
|
||||
"name": "id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 1,
|
||||
"name": "event_id",
|
||||
"type_info": "Int8"
|
||||
},
|
||||
{
|
||||
"ordinal": 2,
|
||||
"name": "from_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 3,
|
||||
"name": "to_date",
|
||||
"type_info": "Timestamp"
|
||||
},
|
||||
{
|
||||
"ordinal": 4,
|
||||
"name": "user_email",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 5,
|
||||
"name": "user_name",
|
||||
"type_info": "Varchar"
|
||||
},
|
||||
{
|
||||
"ordinal": 6,
|
||||
"name": "user_ip",
|
||||
"type_info": "Varchar"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Left": [
|
||||
"Int8"
|
||||
]
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "d13c89523084d914be6e6250b2738e835447bd3478ec50245eca833e476fd9bf"
|
||||
}
|
109
Cargo.lock
generated
109
Cargo.lock
generated
|
@ -30,6 +30,15 @@ dependencies = [
|
|||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "allocator-api2"
|
||||
version = "0.2.16"
|
||||
|
@ -363,6 +372,19 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
|
||||
dependencies = [
|
||||
"humantime",
|
||||
"is-terminal",
|
||||
"log",
|
||||
"regex",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
|
@ -409,6 +431,7 @@ dependencies = [
|
|||
"axum",
|
||||
"chrono",
|
||||
"dotenv",
|
||||
"env_logger",
|
||||
"futures",
|
||||
"rand",
|
||||
"serde",
|
||||
|
@ -715,6 +738,12 @@ version = "1.0.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "1.1.0"
|
||||
|
@ -795,6 +824,17 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"rustix",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.0"
|
||||
|
@ -1197,6 +1237,35 @@ dependencies = [
|
|||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "rsa"
|
||||
version = "0.9.6"
|
||||
|
@ -1659,6 +1728,15 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.56"
|
||||
|
@ -1975,6 +2053,37 @@ version = "1.4.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.52.0"
|
||||
|
|
|
@ -9,6 +9,7 @@ edition = "2021"
|
|||
axum = { version = "0.7.3", features = ["macros", "tokio"] }
|
||||
chrono = { version = "0.4.31", features = ["serde"] }
|
||||
dotenv = "0.15.0"
|
||||
env_logger = "0.10.1"
|
||||
futures = "0.3.30"
|
||||
rand = "0.8.5"
|
||||
serde = { version = "1.0.195", features = ["derive"] }
|
||||
|
|
62
Dockerfile
Normal file
62
Dockerfile
Normal file
|
@ -0,0 +1,62 @@
|
|||
### Build Back-End ###
|
||||
|
||||
FROM rust:1.73-slim-buster as rustbuild
|
||||
|
||||
WORKDIR /findtheti-me
|
||||
|
||||
COPY ./Cargo.lock ./Cargo.lock
|
||||
COPY ./Cargo.toml ./Cargo.toml
|
||||
COPY ./src ./src
|
||||
COPY ./.sqlx ./.sqlx
|
||||
COPY ./migrations ./migrations
|
||||
|
||||
RUN cargo build --release
|
||||
|
||||
### Build Front-End ###
|
||||
|
||||
FROM node:lts as nodebuilder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY ./frontend/package*.json ./
|
||||
COPY ./frontend/tsconfig*.json ./
|
||||
|
||||
RUN yarn install --prefer-offline --frozen-lockfile --non-interactive --production=true
|
||||
|
||||
COPY ./frontend ./
|
||||
|
||||
RUN yarn build
|
||||
|
||||
RUN rm -rf node_modules
|
||||
|
||||
### Combine Both Into Running Image ###
|
||||
|
||||
FROM rust:1.73-slim-buster
|
||||
|
||||
RUN adduser \
|
||||
--disabled-password \
|
||||
--gecos "" \
|
||||
--home "/nonexistent" \
|
||||
--shell "/sbin/nologin" \
|
||||
--no-create-home \
|
||||
--uid "10001" \
|
||||
appuser
|
||||
|
||||
COPY --from=rustbuild /findtheti-me/target/release/findtheti-me ./findtheti-me/
|
||||
|
||||
RUN chown appuser ./findtheti-me/findtheti-me
|
||||
|
||||
COPY --from=nodebuilder /app/dist ./findtheti-me/frontend/dist
|
||||
|
||||
RUN chown -R appuser ./findtheti-me
|
||||
|
||||
USER appuser
|
||||
|
||||
ENV RUST_LOG="findtheti-me=debug,info"
|
||||
ENV EVENT_UID_SIZE=20
|
||||
|
||||
WORKDIR ./findtheti-me
|
||||
|
||||
ENTRYPOINT ["./findtheti-me"]
|
||||
|
||||
EXPOSE 8080/tcp
|
15
README.md
Normal file
15
README.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Setup For Development
|
||||
## Backend
|
||||
1. Create a PostgreSQL database
|
||||
2. Configure a `.env` in the project root directory ( following `.env.example` )
|
||||
3. Run `cargo sqlx migrate run` to run all migrations ( ensure you've created the database beforehand )
|
||||
4. `cargo run`
|
||||
|
||||
## Frontend
|
||||
1. `yarn install`
|
||||
2. `yarn dev` ( or `yarn build`/`yarn preview` )
|
||||
|
||||
## Docker Build Image
|
||||
1. Do Backend and Frontend setups first
|
||||
2. Run `cargo sqlx prepare` ( ensure .sqlx directory has been created. The one included in this git repo may be out of date. )
|
||||
3. `docker build .` ( or `podman build .` ) in root directory
|
2
migrations/20240111111901_ChangeIpColumnSize.sql
Normal file
2
migrations/20240111111901_ChangeIpColumnSize.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
ALTER TABLE events.availability
|
||||
ALTER COLUMN user_ip TYPE VARCHAR(15);
|
|
@ -2,7 +2,7 @@ use std::net::SocketAddr;
|
|||
|
||||
use axum::{
|
||||
extract::{Path, State, ConnectInfo},
|
||||
Json, http::StatusCode, Extension,
|
||||
Json, http::StatusCode,
|
||||
};
|
||||
use chrono::{DateTime, TimeZone, Utc};
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
|
|
|
@ -12,6 +12,8 @@ mod entity;
|
|||
|
||||
#[tokio::main(flavor = "multi_thread")]
|
||||
async fn main() {
|
||||
println!("Starting findtheti.me...");
|
||||
|
||||
dotenv().ok();
|
||||
|
||||
let api_routes = api::routes().await.expect("Unable to create api routes");
|
||||
|
@ -22,14 +24,20 @@ async fn main() {
|
|||
|
||||
// If in release mod, serve static files
|
||||
if !cfg!(debug_assertions) {
|
||||
println!("Initializing frontend routes...");
|
||||
|
||||
routes = routes.nest_service("/", ServeDir::new("./frontend/dist"))
|
||||
.fallback_service(ServeDir::new("./frontend/dist"));
|
||||
}
|
||||
|
||||
println!("Routes initialized...");
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
|
||||
|
||||
let listener = TcpListener::bind(addr).await.unwrap();
|
||||
|
||||
println!("Starting server...");
|
||||
|
||||
axum::serve(listener, routes.into_make_service_with_connect_info::<SocketAddr>())
|
||||
.await
|
||||
.unwrap();
|
||||
|
|
Loading…
Add table
Reference in a new issue