diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 000000000..37bfc1ab4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,30 @@ +# Generated by Cargo +# will have compiled files and executables +**/target/ +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk + +# node +**/node_modules/ + +# IDE configurations +.idea +.vscode +.zed + +# Mac +.DS_Store + +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. +.VSCodeCounter + +# zmt agent data file +ztm_agent.db +ztm_agent_db* + +# buck2 out +buck-out \ No newline at end of file diff --git a/common/src/config.rs b/common/src/config.rs index 6424b46f9..7663ed716 100644 --- a/common/src/config.rs +++ b/common/src/config.rs @@ -8,7 +8,7 @@ use std::collections::HashMap; use std::path::PathBuf; use std::rc::Rc; -#[derive(Serialize, Deserialize, Debug, Default, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Config { pub base_dir: PathBuf, pub log: LogConfig, @@ -38,6 +38,25 @@ impl Config { } } +impl Default for Config { + fn default() -> Self { + let base_dir = PathBuf::from( + std::env::var("MEGA_BASE_DIR").unwrap_or_else(|_| "/tmp/.mega".to_string()), + ); + std::fs::create_dir_all(&base_dir).unwrap(); + + // use mega/config.toml because mega use sqlite as default db + let default_config = include_str!("../../mega/config.toml"); + let default_config = default_config.replace("/tmp/.mega", base_dir.to_str().unwrap()); + + let config_path = base_dir.join("config.toml"); + std::fs::write(&config_path, default_config).unwrap(); + eprintln!("create default config.toml in {:?}", &config_path); + + Config::new(config_path.to_str().unwrap()).unwrap() + } +} + /// supports braces-delimited variables (i.e. ${foo}) in config. /// ### Example: /// ```toml diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 000000000..01b348c7f --- /dev/null +++ b/docker/README.md @@ -0,0 +1,68 @@ +# build images + +```bash + +# cd root of the project + +# build postgres image +docker buildx build -t mega-db:1.0 -f ./docker/mega_pg_dockerfile . + +# build backend mono image +docker buildx build -t mega-mono:1.0 -f ./docker/mega_mono_dockerfile . + +# build frontend moon image +docker buildx build -t mega-moon:1.0 -f ./docker/mega_moon_dockerfile . +``` + +# test mono and moon + + +## test without postgres +```bash +# create network +docker network create mega-network + +docker run --rm -it -d --network mega-network --name mega-mono -v ./mega_base:/etc/mega mega-mono:1.0 +docker run --rm -it -d --network mega-network -e NEXT_PUBLIC_API_URL=http://mega-mono:8000 -p 3000:3000 mega-moon:1.0 +``` + +visit http://localhost:3000 to see the frontend + +## test with sqlite + +1. start postgres + +```bash +# create network +docker network create mega-network + +# run postgres +docker run --rm -it -d --network mega-network --name mega-db mega-db:1.0 +``` + +2. create default config + +```bash +docker run --rm -it -d --network mega-network --name mega-mono -v ./mega_base:/etc/mega mega-mono:1.0 +docker stop mega-mono +``` + +3. edit `mega_base/config.toml`, change `db_type` to `postgres` and db_url to `postgres://mega:mega@mega-db:5432/mega` + +```toml +[database] +db_type = "postgres" + +# used for sqlite +db_path = "${base_dir}/mega.db" + +# database connection url +db_url = "postgres://mega:mega@mega-db:5432/mega" +``` + +4. Start the mono again, and run the frontend. + +```bash +docker run --rm -it -d --network mega-network --name mega-mono -v ./mega_base:/etc/mega mega-mono:1.0 +docker run --rm -it -d --network mega-network -e NEXT_PUBLIC_API_URL=http://mega-mono:8000 -p 3000:3000 mega-moon:1.0 +``` \ No newline at end of file diff --git a/docker/mega_mono_dockerfile b/docker/mega_mono_dockerfile new file mode 100644 index 000000000..2e82d09f1 --- /dev/null +++ b/docker/mega_mono_dockerfile @@ -0,0 +1,38 @@ +FROM debian:bookworm-slim + +WORKDIR /opt/mega + +# set mirror for apt +# RUN echo "deb http://mirrors.ustc.edu.cn/debian bookworm main contrib non-free" > /etc/apt/sources.list && \ +# echo "deb http://mirrors.ustc.edu.cn/debian-security bookworm-security main contrib non-free" >> /etc/apt/sources.list && \ +# echo "deb http://mirrors.ustc.edu.cn/debian bookworm-updates main contrib non-free" >> /etc/apt/sources.list + +RUN apt-get update && apt-get install -y \ + cmake \ + clang \ + nodejs \ + npm \ + build-essential \ + curl \ + wget \ + file \ + libssl-dev \ + libgtk-3-dev \ + libayatana-appindicator3-dev \ + librsvg2-dev \ + ca-certificates \ + && curl https://sh.rustup.rs -sSf | sh -s -- -y \ + && . $HOME/.cargo/env + +ENV PATH=/root/.cargo/bin:$PATH! + +# copy the source code, the context must be the root of the project +COPY . . +RUN chmod +x /opt/mega/docker/start_mono.sh + +# build +RUN cargo build -p mono + +VOLUME /etc/mega + +CMD ["bash", "-c", "/opt/mega/docker/start_mono.sh"] \ No newline at end of file diff --git a/docker/mega_moon_dockerfile b/docker/mega_moon_dockerfile new file mode 100644 index 000000000..743dbb89f --- /dev/null +++ b/docker/mega_moon_dockerfile @@ -0,0 +1,22 @@ +FROM node:22-alpine + +WORKDIR /app + +# set mirror for npm +# RUN npm config set registry https://registry.npmmirror.com + +COPY ./moon/package*.json ./ + +RUN npm install + +COPY ./moon . + +RUN npm run build + +COPY ./docker/start_moon.sh /app/start_moon.sh + +RUN chmod +x /app/start_moon.sh + +EXPOSE 3000 + +ENTRYPOINT ["/bin/sh", "/app/start_moon.sh"] \ No newline at end of file diff --git a/docker/mega_pg_dockerfile b/docker/mega_pg_dockerfile new file mode 100644 index 000000000..43349ba94 --- /dev/null +++ b/docker/mega_pg_dockerfile @@ -0,0 +1,14 @@ +FROM postgres:16 + +ENV POSTGRES_DB=mega +ENV POSTGRES_USER=mega +ENV POSTGRES_PASSWORD=mega + +EXPOSE 5432 + +# Add the database initialization script to the container +# When the container starts, PostgreSQL will automatically execute all .sql files in the docker-entrypoint-initdb.d/ directory +COPY ./sql/postgres/pg_20240205__init.sql /docker-entrypoint-initdb.d/ + +CMD ["postgres"] + diff --git a/docker/start_mono.sh b/docker/start_mono.sh new file mode 100755 index 000000000..883946a86 --- /dev/null +++ b/docker/start_mono.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +CONFIG_FILE="/etc/mega" +MEGA_BASE_DIR="/etc/mega" +# check if config file exists +if [ -f "$CONFIG_FILE" ]; then + exec /opt/mega/target/debug/mono -c "$CONFIG_FILE" service http --host 0.0.0.0 +else + exec /opt/mega/target/debug/mono service http --host 0.0.0.0 +fi \ No newline at end of file diff --git a/docker/start_moon.sh b/docker/start_moon.sh new file mode 100755 index 000000000..135b6ccdb --- /dev/null +++ b/docker/start_moon.sh @@ -0,0 +1,15 @@ +#!/bin/bash +NEXT_PUBLIC_CALLBACK_URL=http://0.0.0.0:3000/auth/github/callback + +# user must set the NEXT_PUBLIC_API_URL +if [ -z "$NEXT_PUBLIC_API_URL" ]; then + echo "NEXT_PUBLIC_API_URL is not set" + exit 1 +fi + +# write the environment variables to a file +echo "NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL" > .env.local +echo "NEXT_PUBLIC_CALLBACK_URL=$NEXT_PUBLIC_CALLBACK_URL" >> .env.local + +# TODO: run `npm run s start` didn't work, use `npm run dev` temporarily +exec npm run dev \ No newline at end of file diff --git a/mono/config.toml b/mono/config.toml index 8da1b7aec..c5454dd0d 100644 --- a/mono/config.toml +++ b/mono/config.toml @@ -1,5 +1,5 @@ # the directory where the data files is located, such as logs, database, etc. -# can be overrided by environment variable `MONO_BASE_DIR` +# can be overrided by environment variable `MEGA_BASE_DIR` base_dir = "/tmp/.mega" # Filling the following environment variables with values you set