mirror of
https://github.com/ForFarmTeam/ForFarm.git
synced 2025-12-18 13:34:08 +01:00
284 lines
13 KiB
Markdown
284 lines
13 KiB
Markdown
# ForFarm Project Setup Guide
|
|
|
|
This guide provides instructions for setting up and running the ForFarm project using different methods.
|
|
|
|
## Prerequisites
|
|
|
|
Ensure you have the following tools installed:
|
|
|
|
- **Go:** Version 1.23 or later (see `backend/go.mod`).
|
|
- **Node.js:** Version 20 or later (see `frontend/next.dockerfile`).
|
|
- **pnpm:** Node package manager (`npm install -g pnpm`).
|
|
- **Docker:** Latest version.
|
|
- **Docker Compose:** Latest version (often included with Docker Desktop).
|
|
- **kubectl:** Kubernetes command-line tool.
|
|
- **gcloud:** Google Cloud SDK (if deploying to GKE).
|
|
|
|
## Configuration
|
|
|
|
Environment variables are used for configuration.
|
|
|
|
1. **Backend:**
|
|
|
|
- Copy `backend/sample.env` to `backend/.env`.
|
|
- Fill in the required values in `backend/.env`:
|
|
- `DATABASE_URL`: Connection string for your PostgreSQL database. (e.g., `postgres://postgres:@Password123@localhost:5433/postgres?sslmode=disable` for local Docker Compose setup).
|
|
- `RABBITMQ_URL`: Connection string for RabbitMQ (e.g., `amqp://user:password@localhost:5672/` for local Docker Compose).
|
|
- `JWT_SECRET_KEY`: A strong, random secret key (at least 32 characters).
|
|
- `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`: For Google OAuth.
|
|
- `OPENWEATHER_API_KEY`: Your OpenWeatherMap API key.
|
|
- `GEMINI_API_KEY`: Your Google AI Gemini API key.
|
|
- `GCS_BUCKET_NAME`: Your Google Cloud Storage bucket name.
|
|
- `GCS_SERVICE_ACCOUNT_KEY_PATH`: (Optional) Path to your GCS service account key JSON file if _not_ using Application Default Credentials (ADC). Leave empty if using ADC (recommended for GKE with Workload Identity).
|
|
|
|
2. **Frontend:**
|
|
- Copy `frontend/sample.env` to `frontend/.env`.
|
|
- Fill in the required values in `frontend/.env`:
|
|
- `NEXT_PUBLIC_BACKEND_URL`: URL of the running backend API (e.g., `http://localhost:8000` for local/Compose).
|
|
- `NEXT_PUBLIC_GOOGLE_CLIENT_ID`: Your Google Client ID for OAuth on the frontend.
|
|
- `NEXT_PUBLIC_GOOGLE_MAPS_API_KEY`: Your Google Maps API Key.
|
|
- (Other `NEXTAUTH_*` variables might be needed if you integrate `next-auth` fully).
|
|
|
|
## Running Locally (Manual Setup)
|
|
|
|
This method requires running services like Postgres and RabbitMQ separately.
|
|
|
|
1. **Start Database:** Run PostgreSQL (e.g., using Docker: `docker run --name some-postgres -e POSTGRES_PASSWORD=yourpassword -p 5432:5432 -d postgres:16-alpine`). Ensure the `DATABASE_URL` in `backend/.env` points to it.
|
|
2. **Start RabbitMQ:** Run RabbitMQ (e.g., using Docker: `docker run --name some-rabbit -p 5672:5672 -p 15672:15672 -d rabbitmq:3-management-alpine`). Ensure `RABBITMQ_URL` in `backend/.env` points to it.
|
|
3. **Backend Migrations:**
|
|
```bash
|
|
cd backend
|
|
go run cmd/forfarm/main.go migrate
|
|
```
|
|
4. **Run Backend API:**
|
|
```bash
|
|
cd backend
|
|
# For live reloading (requires air - go install github.com/cosmtrek/air@latest)
|
|
# air
|
|
# Or run directly
|
|
go run cmd/forfarm/main.go api
|
|
```
|
|
The backend should be running on `http://localhost:8000`.
|
|
5. **Run Frontend:**
|
|
|
|
```bash
|
|
cd frontend
|
|
pnpm install
|
|
pnpm dev
|
|
```
|
|
|
|
The frontend should be running on `http://localhost:3000`.
|
|
|
|
6. (Optional) Add dummy data in /backend/dummy directory to database
|
|
|
|
- Do it manually or `make seed`
|
|
|
|
## Installation Steps (In detailed)
|
|
|
|
1. **Clone the Repository:**
|
|
|
|
```bash
|
|
git clone https://github.com/your-username/ForFarm.git # Replace with your repo URL
|
|
cd ForFarm
|
|
```
|
|
|
|
2. **Environment Variables:**
|
|
|
|
- Copy the example environment file:
|
|
```bash
|
|
cp .env.example .env
|
|
```
|
|
- **Edit the `.env` file:** Fill in the required values, especially for:
|
|
- `POSTGRES_USER`, `POSTGRES_PASSWORD`, `POSTGRES_DB` (you can keep defaults for local setup)
|
|
- `JWT_SECRET_KEY` (generate a strong, random secret)
|
|
- `GOOGLE_CLIENT_ID` (if using Google OAuth)
|
|
- `NEXT_PUBLIC_GOOGLE_CLIENT_ID` (Frontend Google Client ID)
|
|
- `NEXT_PUBLIC_GOOGLE_MAPS_API_KEY` (Required for maps)
|
|
- `OPENWEATHER_API_KEY` (Required for weather features)
|
|
- `GEMINI_API_KEY` (Required for AI chatbot features)
|
|
- `RABBITMQ_URL` (Keep default if using the docker-compose setup)
|
|
- (Optionally adjust `RATE_LIMIT_*` variables)
|
|
|
|
3. **Build and Run Services:**
|
|
Use Docker Compose to build the images and start the backend, frontend, and database containers.
|
|
|
|
```bash
|
|
docker compose up --build -d
|
|
```
|
|
|
|
- `--build`: Forces Docker to rebuild images if Dockerfiles have changed.
|
|
- `-d`: Runs containers in detached mode (in the background).
|
|
|
|
4. **Run Backend Database Migrations:**
|
|
Apply the necessary database schema changes. Open a **new terminal** in the project root and navigate to the backend directory:
|
|
|
|
```bash
|
|
cd backend
|
|
make migrate
|
|
cd ..
|
|
```
|
|
|
|
- This command uses Go to connect to the database (running in Docker) and applies migrations located in `backend/migrations`.
|
|
|
|
5. **Install Frontend Dependencies:**
|
|
Navigate to the frontend directory and install its dependencies using pnpm.
|
|
|
|
```bash
|
|
cd frontend
|
|
pnpm install
|
|
cd ..
|
|
```
|
|
|
|
_(Docker Compose might handle this during build if configured in `next.dockerfile`, but running it explicitly ensures dependencies are up-to-date)_
|
|
|
|
6. **Access the Application:**
|
|
|
|
- **Frontend:** Open your browser and navigate to [http://localhost:3000](http://localhost:3000) (or the port specified by `FRONTEND_PORT` in your `.env`).
|
|
- **Backend API:** The API is accessible at [http://localhost:8000](http://localhost:8000) (or the port specified by `BACKEND_PORT`). You can use tools like Postman or `curl` to interact with it.
|
|
|
|
7. (Optional) Add dummy data in /backend/dummy directory to database
|
|
|
|
- Do it manually or `make seed`
|
|
|
|
## Running with Docker Compose
|
|
|
|
This is the recommended way for local development and testing the containerized setup.
|
|
|
|
1. **Ensure `.env` files are configured** as described in the Configuration section. Use `localhost` for hostnames in URLs (e.g., `DATABASE_URL='postgres://postgres:@Password123@db:5432/postgres?sslmode=disable'`, `RABBITMQ_URL=amqp://user:password@rabbitmq:5672/` - note the service names `db` and `rabbitmq`).
|
|
2. **Build and Start:**
|
|
```bash
|
|
docker compose up --build -d # -d runs in detached mode
|
|
```
|
|
3. **Run Migrations (First time or after changes):**
|
|
```bash
|
|
docker compose exec backend /app/api migrate
|
|
# Or if using source mount and go is available:
|
|
# docker compose exec backend go run cmd/forfarm/main.go migrate
|
|
```
|
|
4. **Access Services:**
|
|
- Frontend: `http://localhost:3000`
|
|
- Backend API: `http://localhost:8000`
|
|
- RabbitMQ Management: `http://localhost:15672` (user/password from `.env`)
|
|
- Database: Connect via `localhost:5433` using credentials from `.env`.
|
|
5. **View Logs:** `docker compose logs -f [service_name]` (e.g., `docker compose logs -f backend`)
|
|
6. **Stop:** `docker compose down`
|
|
|
|
## Development Workflow
|
|
|
|
- **Live Reload (Backend):** While `docker compose up -d` keeps the backend running, for active Go development with live reload, stop the backend service (`docker compose stop backend`) and run:
|
|
```bash
|
|
cd backend
|
|
make live
|
|
```
|
|
This uses `air` (configured in `.air.toml`) to automatically rebuild and restart the Go application when code changes.
|
|
- **Live Reload (Frontend):** The `pnpm dev` command used in the frontend Dockerfile typically includes hot module replacement (HMR). Changes made to frontend code should reflect in the browser automatically when running `docker compose up`. If not, check the Next.js configuration.
|
|
|
|
## Deploying to Google Kubernetes Engine (GKE)
|
|
|
|
This requires a configured GKE cluster and `gcloud` CLI authenticated.
|
|
|
|
1. **Prerequisites:**
|
|
|
|
- Create a GKE cluster.
|
|
- Configure `kubectl` to connect to your cluster (`gcloud container clusters get-credentials YOUR_CLUSTER_NAME --zone YOUR_ZONE --project YOUR_PROJECT_ID`).
|
|
- Enable Google Container Registry (GCR) or Artifact Registry API.
|
|
|
|
2. **Configure GCS:**
|
|
|
|
- Create a GCS bucket (`YOUR_GCS_BUCKET_NAME`).
|
|
- **Authentication:**
|
|
- **(Recommended) Workload Identity:** Set up Workload Identity to grant your Kubernetes Service Account permissions to access the GCS bucket without key files. This involves creating a GCP Service Account, granting it `roles/storage.objectAdmin` on the bucket, creating a K8s Service Account (e.g., `backend-sa`), and binding them. Update `backend-deployment.yaml` to use `serviceAccountName: backend-sa`.
|
|
- **(Alternative) Service Account Key:** Create a GCP Service Account, grant it permissions, download its JSON key file.
|
|
|
|
3. **Build and Push Docker Images:**
|
|
|
|
- Authenticate Docker with GCR/Artifact Registry (`gcloud auth configure-docker YOUR_REGION-docker.pkg.dev`).
|
|
- Build the images:
|
|
|
|
```bash
|
|
# Backend
|
|
docker build -t YOUR_REGION-docker.pkg.dev/YOUR_GCR_PROJECT_ID/forfarm/backend:latest -f backend/go.dockerfile ./backend
|
|
|
|
# Frontend
|
|
docker build -t YOUR_REGION-docker.pkg.dev/YOUR_GCR_PROJECT_ID/forfarm/frontend:latest -f frontend/next.dockerfile ./frontend
|
|
```
|
|
|
|
- Push the images:
|
|
```bash
|
|
docker push YOUR_REGION-docker.pkg.dev/YOUR_GCR_PROJECT_ID/forfarm/backend:latest
|
|
docker push YOUR_REGION-docker.pkg.dev/YOUR_GCR_PROJECT_ID/forfarm/frontend:latest
|
|
```
|
|
- **Update `k8s/*.yaml` files:** Replace `YOUR_GCR_PROJECT_ID/forfarm-backend:latest` and `YOUR_GCR_PROJECT_ID/forfarm-frontend:latest` with your actual image paths.
|
|
|
|
4. **Create Kubernetes Secrets:**
|
|
|
|
- **Encode Secrets:** Base64 encode all values needed in `k8s/secrets.yaml`.
|
|
```bash
|
|
echo -n "your_password" | base64
|
|
# For GCS key file (if using):
|
|
cat path/to/your-gcs-key.json | base64 | tr -d '\n' # Ensure no newlines in output
|
|
```
|
|
- **Update `k8s/secrets.yaml`:** Paste the base64 encoded values into the `data` section.
|
|
- **Apply Secrets:**
|
|
```bash
|
|
kubectl apply -f k8s/namespace.yaml
|
|
kubectl apply -f k8s/secrets.yaml -n forfarm
|
|
```
|
|
Alternatively, create secrets imperatively (safer as values aren't stored in YAML):
|
|
```bash
|
|
kubectl create secret generic forfarm-secrets -n forfarm \
|
|
--from-literal=POSTGRES_PASSWORD='your_db_password' \
|
|
--from-literal=RABBITMQ_PASSWORD='your_rabbit_password' \
|
|
# ... add other secrets ...
|
|
# If using key file:
|
|
# --from-file=GCS_SERVICE_ACCOUNT_KEY_JSON=/path/to/your-gcs-key.json
|
|
```
|
|
|
|
5. **Create ConfigMap:**
|
|
|
|
- **Update `k8s/configmap.yaml`:** Replace placeholders like `YOUR_GOOGLE_CLIENT_ID`, `YOUR_GOOGLE_MAPS_API_KEY`, `YOUR_GCS_BUCKET_NAME`. Adjust service URLs if needed.
|
|
- **Apply ConfigMap:**
|
|
```bash
|
|
kubectl apply -f k8s/configmap.yaml -n forfarm
|
|
```
|
|
|
|
6. **Apply Deployments, Services, PVCs:**
|
|
|
|
```bash
|
|
# Apply database and message queue first
|
|
kubectl apply -f k8s/postgres-pvc.yaml -n forfarm # Only if using self-hosted postgres
|
|
kubectl apply -f k8s/postgres-deployment.yaml -n forfarm
|
|
kubectl apply -f k8s/postgres-service.yaml -n forfarm
|
|
kubectl apply -f k8s/rabbitmq-pvc.yaml -n forfarm
|
|
kubectl apply -f k8s/rabbitmq-deployment.yaml -n forfarm
|
|
kubectl apply -f k8s/rabbitmq-service.yaml -n forfarm
|
|
|
|
# Wait for DB and RabbitMQ to be ready (check pods: kubectl get pods -n forfarm -w)
|
|
|
|
# Apply backend and frontend
|
|
kubectl apply -f k8s/backend-deployment.yaml -n forfarm
|
|
kubectl apply -f k8s/backend-service.yaml -n forfarm
|
|
kubectl apply -f k8s/frontend-deployment.yaml -n forfarm
|
|
kubectl apply -f k8s/frontend-service.yaml -n forfarm
|
|
```
|
|
|
|
_Note: The `initContainer` in `backend-deployment.yaml` should handle migrations._
|
|
|
|
7. **Setup Ingress:**
|
|
|
|
- **Update `k8s/ingress.yaml`:** Replace `your-domain.com` with your domain. Configure TLS and managed certificates if needed (requires creating a `ManagedCertificate` resource in GKE).
|
|
- **Apply Ingress:**
|
|
```bash
|
|
kubectl apply -f k8s/ingress.yaml -n forfarm
|
|
```
|
|
- **Get Ingress IP:** Wait a few minutes, then run `kubectl get ingress forfarm-ingress -n forfarm`. Note the `ADDRESS`.
|
|
- **Configure DNS:** Point your domain's A record(s) to the Ingress IP address.
|
|
|
|
8. **Alternative: Cloud SQL:** Instead of running Postgres in K8s, consider using Cloud SQL. Create a Cloud SQL instance, configure its user/database, and update the `DATABASE_URL` in your `k8s/configmap.yaml` to point to the Cloud SQL proxy or private IP. You won't need the `postgres-*.yaml` files.
|
|
|
|
## Troubleshooting
|
|
|
|
- **Docker Compose:** Use `docker compose logs -f <service_name>` to check logs. Use `docker compose exec <service_name> sh` to get a shell inside a container.
|
|
- **Kubernetes:** Use `kubectl get pods -n forfarm`, `kubectl logs <pod_name> -n forfarm [-c <container_name>]`, `kubectl describe pod <pod_name> -n forfarm`.
|
|
- **Migrations:** Check the `goose_db_version` table in your database to see applied migrations.
|