Skip to content

Commit

Permalink
Merge pull request #239 from RMoodsTeam/232-bug-setup-dev-database
Browse files Browse the repository at this point in the history
232: Dev database setup
  • Loading branch information
SebastianNowak01 authored Dec 9, 2024
2 parents a301037 + 1701642 commit b8c2ae5
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 12 deletions.
1 change: 1 addition & 0 deletions backend/.gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Environment variables
.env
.env.prod

# Generated by Cargo
# will have compiled files and executables
Expand Down
85 changes: 79 additions & 6 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,104 @@
# RMoods Backend

## Build

For deployment, append the `release` flag.

```sh
cargo build
```


## Run

To run in debug mode, using the `.env` file:

```sh
cargo run
```
### Environment
Your `.env` file should look like this:

To run in release mode, using the `.env.prod` file, just add the `--release` flag.
**Be careful! Using the production DB for development is forbidden**

```sh
cargo run --release
```

## Local Environment

Your `.env` file should have all the properties as listed in the `.env.example` file.
Don't worry, the server verifies the presence of these variables at startup.

[Docker Desktop](https://www.docker.com/products/docker-desktop/) is recommended, as it's really easy to manage
containers there.

### Database setup

You'll need a local PostgreSQL database to run the backend and not cause any trouble with the production DB.

First, download the image that matches our production database version.

```sh
docker pull postgres:15.10
```

Create a docker volume to persist the data between container runs.

```sh
docker volume create rmoods-dev-pgdata
```

Run the container with the volume mounted.

```sh
docker run --name rmoods-dev-db -p 8003:5432 -e POSTGRES_USER=rmoods-dev -e POSTGRES_PASSWORD=mypasswd -e POSTGRES_DB=rmoods -v rmoods-dev-pgdata:/var/lib/postgresql/data postgres:15.10
```

Add this to your `.env` file:

```sh
DATABASE_URL=postgres://rmoods-dev:mypasswd@localhost:8003/rmoods-db
```
CLIENT_ID=***
CLIENT_SECRET=***
DATABASE_URL=***

The production DB URL is kept only in `.env.prod`.

To restart the container afterward:

```sh
docker start rmoods-dev-db --attach
```

With that, you should have a local database running. Now you need to configure it to match our backend code and data
schema.

### SQLx CLI

To maintain your local database, you need to use the `sqlx` CLI tool from time to time.
Refer to the [SQLx CLI documentation](https://github.com/launchbadge/sqlx/blob/main/sqlx-cli/README.md).
Just to get you started:

```sh
sqlx database create
sqlx migrate run
```

Whenever we change the schema, you need to keep the local DB in sync. You can just drop the database and recreate it.

```sh
sqlx database drop
sqlx database create
sqlx migrate run
```

## Docker

Backend for RMoods can be run a Docker container.

```Dockerfile
docker build -t rmoods-backend .
```

After it's done building, run the container. You may want to map the default 8001 port to 9001 for differentiation.

```Dockerfile
docker run -p 9001:8001 rmoods-backend
```
11 changes: 5 additions & 6 deletions backend/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use crate::env::DATABASE_URL;
use crate::db::db_client::DbClient;
use crate::fetcher::fetcher::RMoodsFetcher;
use crate::fetcher::reddit::connection::RedditConnection;
use crate::nlp::nlp_client::NlpClient;
use crate::open_api::ApiDoc;
use crate::startup::{shutdown_signal, verify_environment};
use crate::startup::{setup_environment, shutdown_signal, verify_environment};
use crate::websocket::SystemMessage;
use axum::Router;
use log::{error, info, warn};
Expand Down Expand Up @@ -44,7 +45,7 @@ pub struct AppState {

/// Run the server, assuming the environment has been already validated.
async fn run() -> anyhow::Result<()> {
let url = std::env::var("DATABASE_URL").expect("DB_URL is set");
let url = std::env::var(DATABASE_URL).expect("DB_URL is set");
let pool = PgPoolOptions::new()
.max_connections(10)
.connect(&url)
Expand Down Expand Up @@ -116,16 +117,14 @@ async fn run() -> anyhow::Result<()> {
}

/// Entry point of the RMoods server.
/// Validates the environment, initializes the server and runs it.
/// Sets up and validates the environment, initializes the server and runs it.
#[tokio::main]
async fn main() {
std::env::set_var("RUST_LOG", "debug");
std::env::set_var("RUST_BACKTRACE", "0");
env_logger::init();

if dotenvy::dotenv().is_err() {
warn!(".env not found. Environment variables will have to be defined outside of .env");
}
setup_environment();

if !verify_environment() {
error!("Invalid environment, aborting.");
Expand Down
25 changes: 25 additions & 0 deletions backend/src/startup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,31 @@ pub fn verify_environment() -> bool {
is_ok
}

/// Sets up the environment for the application.
/// If we're in debug mode, we load the .env file.
/// Otherwise, we expect all environment variables to be defined.
pub fn setup_environment() {
#[cfg(debug_assertions)]
{
log::warn!("Running in debug mode.");
if dotenvy::dotenv().is_err() {
log::warn!(
"Failed to load .env file. Environment variables will have to be defined outside"
);
}
}

#[cfg(not(debug_assertions))]
{
log::warn!("Running in production mode.");
if dotenvy::from_filename_override(".env.prod").is_err() {
log::warn!(
"Failed to load .env.prod file. Environment variables will have to be defined outside"
);
}
}
}

pub async fn shutdown_signal(cancellation_token: CancellationToken) {
let ctrl_c = async {
signal::ctrl_c()
Expand Down

0 comments on commit b8c2ae5

Please sign in to comment.