From fff4675aa319b701089b3f5bb01772c995ad171c Mon Sep 17 00:00:00 2001 From: Daniel Luiz Alves Date: Wed, 28 May 2025 18:07:16 -0300 Subject: [PATCH] feat: add docker-compose files for S3 and local filesystem storage options Introduce three new docker-compose files: docker-compose-file-system.yaml for local filesystem storage, docker-compose-s3-minio.yaml for MinIO S3-compatible storage, and docker-compose-s3.yaml for direct S3 storage. Each configuration includes environment variables for service setup, health checks, and persistent volume management. This enhances deployment flexibility for the Palmr application. --- Dockerfile | 5 +- ONLY_DOCKER.md | 192 ++++++++++++++++++ apps/server/.dockerignore | 9 - apps/server/.env.example | 21 +- apps/server/.gitignore | 1 + apps/server/Dockerfile | 26 --- apps/server/docker-compose-postgres.yaml | 22 ++ apps/server/docker-compose.yaml | 42 ---- apps/server/src/env.ts | 2 - apps/server/src/server.ts | 6 +- apps/web/Dockerfile | 46 ----- apps/web/docker-compose.yml | 17 -- .../components/modals/upload-file-modal.tsx | 17 +- docker-compose-file-system.yaml | 66 ++++++ docker-compose-s3-minio.yaml | 68 +++++++ docker-compose-s3.yaml | 67 ++++++ docker-compose.yaml | 82 -------- infra/server-start.sh | 8 +- 18 files changed, 453 insertions(+), 244 deletions(-) create mode 100644 ONLY_DOCKER.md delete mode 100644 apps/server/.dockerignore delete mode 100644 apps/server/Dockerfile create mode 100644 apps/server/docker-compose-postgres.yaml delete mode 100644 apps/server/docker-compose.yaml delete mode 100644 apps/web/Dockerfile delete mode 100644 apps/web/docker-compose.yml create mode 100644 docker-compose-file-system.yaml create mode 100644 docker-compose-s3-minio.yaml create mode 100644 docker-compose-s3.yaml delete mode 100644 docker-compose.yaml diff --git a/Dockerfile b/Dockerfile index fe3eabf..7a004a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -130,9 +130,10 @@ autorestart=true stderr_logfile=/var/log/supervisor/server.err.log stdout_logfile=/var/log/supervisor/server.out.log environment=PORT=3333,HOME="/home/palmr",ENABLE_S3="false",ENCRYPTION_KEY="default-key-change-in-production" +priority=100 [program:web] -command=node server.js +command=/bin/sh -c 'echo "Waiting for API to be ready..."; while ! netstat -tln | grep ":3333 "; do echo "API not ready, waiting..."; sleep 2; done; echo "API is ready! Starting frontend..."; exec node server.js' directory=/app/web user=palmr autostart=true @@ -140,6 +141,8 @@ autorestart=true stderr_logfile=/var/log/supervisor/web.err.log stdout_logfile=/var/log/supervisor/web.out.log environment=PORT=5487,HOSTNAME="0.0.0.0",HOME="/home/palmr" +priority=200 +startsecs=10 EOF # Create main startup script diff --git a/ONLY_DOCKER.md b/ONLY_DOCKER.md new file mode 100644 index 0000000..425d7dc --- /dev/null +++ b/ONLY_DOCKER.md @@ -0,0 +1,192 @@ +# Running Palmr with Docker (without docker-compose) + +This document explains how to run Palmr and PostgreSQL using separate Docker commands, without the need for docker-compose. + +## Prerequisites + +- Docker installed +- Docker network created for container communication + +## 1. Create Docker Network + +First, create a custom network to allow communication between containers: + +```bash +docker network create palmr-network +``` + +## 2. Create Volumes + +Create the necessary volumes for data persistence: + +```bash +# Volume for PostgreSQL data +docker volume create postgres_data + +# Volume for Palmr uploads +docker volume create palmr_uploads + +# Volume for temporary chunks +docker volume create palmr_temp_chunks +``` + +## 3. Run PostgreSQL Container + +Run the PostgreSQL container first: + +```bash +docker run -d \ + --name palmr-database \ + --network palmr-network \ + -e POSTGRES_USER=postgres \ + -e POSTGRES_PASSWORD=postgresRootPassword \ + -e POSTGRES_DB=palmr_db \ + -v postgres_data:/var/lib/postgresql/data \ + -p 5432:5432 \ + --restart unless-stopped \ + --health-cmd="pg_isready -U postgres -d palmr_db" \ + --health-interval=5s \ + --health-timeout=3s \ + --health-retries=6 \ + --health-start-period=30s \ + postgres:16-alpine +``` + +## 4. Wait for PostgreSQL to be Healthy + +Wait for PostgreSQL to become healthy before starting Palmr: + +```bash +# Check container status +docker ps + +# Check logs if necessary +docker logs palmr-database + +# Wait until health status is "healthy" +docker inspect palmr-database --format='{{.State.Health.Status}}' +``` + +## 5. Run Palmr Container + +After PostgreSQL is running, execute the Palmr container: + +```bash +docker run -d \ + --name palmr-application \ + --network palmr-network \ + -e ENABLE_S3=false \ + -e ENCRYPTION_KEY=change-this-key-in-production-min-32-chars \ + -e DATABASE_URL="postgresql://postgres:postgresRootPassword@palmr-database:5432/palmr_db?schema=public" \ + -e FRONTEND_URL="http://palmr-application:5487" \ + -e MAX_FILESIZE=1073741824 \ + -e NODE_ENV=production \ + -e NEXT_TELEMETRY_DISABLED=1 \ + -e API_BASE_URL="http://palmr-application:3333" \ + -v palmr_uploads:/app/server/uploads \ + -v palmr_temp_chunks:/app/server/temp-chunks \ + -p 3333:3333 \ + -p 5487:5487 \ + --restart unless-stopped \ + --health-cmd='sh -c "wget --no-verbose --tries=1 --spider http://palmr-application:3333/health && wget --no-verbose --tries=1 --spider http://palmr-application:5487"' \ + --health-interval=30s \ + --health-timeout=10s \ + --health-retries=5 \ + --health-start-period=120s \ + kyantech/palmr:latest +``` + +## 6. Verify Execution + +Check if both containers are running correctly: + +```bash +# Check running containers +docker ps + +# Check PostgreSQL logs +docker logs palmr-database + +# Check Palmr logs +docker logs palmr-application + +# Check container health +docker inspect palmr-database --format='{{.State.Health.Status}}' +docker inspect palmr-application --format='{{.State.Health.Status}}' +``` + +## 7. Application Access + +After both containers are healthy: + +- **API**: http://localhost:3333 +- **Frontend**: http://localhost:5487 +- **PostgreSQL**: localhost:5432 + +## 8. Management Commands + +### Stop containers: +```bash +docker stop palmr-application palmr-database +``` + +### Remove containers: +```bash +docker rm palmr-application palmr-database +``` + +### Remove network: +```bash +docker network rm palmr-network +``` + +### Remove volumes (WARNING - this will delete all data): +```bash +docker volume rm postgres_data palmr_uploads palmr_temp_chunks +``` + +## 9. Customization with Environment Variables + +You can customize configurations by changing the environment variables in the commands above: + +- `POSTGRES_USER`: PostgreSQL username +- `POSTGRES_PASSWORD`: PostgreSQL password +- `POSTGRES_DB`: PostgreSQL database name +- `ENCRYPTION_KEY`: encryption key (minimum 32 characters) +- `MAX_FILESIZE`: maximum file size in bytes +- Ports can be changed using `-p HOST_PORT:CONTAINER_PORT` + +## 10. Example with Custom Variables + +```bash +# PostgreSQL with custom configurations +docker run -d \ + --name palmr-database \ + --network palmr-network \ + -e POSTGRES_USER=myuser \ + -e POSTGRES_PASSWORD=mypassword123 \ + -e POSTGRES_DB=my_palmr_db \ + -v postgres_data:/var/lib/postgresql/data \ + -p 15432:5432 \ + --restart unless-stopped \ + postgres:16-alpine + +# Palmr with corresponding configurations +docker run -d \ + --name palmr-application \ + --network palmr-network \ + -e ENABLE_S3=false \ + -e ENCRYPTION_KEY=my-super-secret-key-32-chars-minimum \ + -e DATABASE_URL="postgresql://myuser:mypassword123@palmr-database:5432/my_palmr_db?schema=public" \ + -e FRONTEND_URL="http://palmr-application:8080" \ + -e MAX_FILESIZE=2147483648 \ + -e NODE_ENV=production \ + -e NEXT_TELEMETRY_DISABLED=1 \ + -e API_BASE_URL="http://palmr-application:8081" \ + -v palmr_uploads:/app/server/uploads \ + -v palmr_temp_chunks:/app/server/temp-chunks \ + -p 8081:3333 \ + -p 8080:5487 \ + --restart unless-stopped \ + kyantech/palmr:latest +``` \ No newline at end of file diff --git a/apps/server/.dockerignore b/apps/server/.dockerignore deleted file mode 100644 index e4925b1..0000000 --- a/apps/server/.dockerignore +++ /dev/null @@ -1,9 +0,0 @@ -node_modules -dist -.env -.env.* -*.log -.git -.gitignore -.next -.cache \ No newline at end of file diff --git a/apps/server/.env.example b/apps/server/.env.example index 2d17411..5022606 100644 --- a/apps/server/.env.example +++ b/apps/server/.env.example @@ -1,15 +1,16 @@ DATABASE_URL="postgresql://palmr:palmr123@localhost:5432/palmr?schema=public" FRONTEND_URL="http://localhost:3000" -PORT=3333 -SERVER_IP="localhost" MAX_FILESIZE="1073741824" +ENABLE_S3=false +ENCRYPTION_KEY=change-this-key-in-production-min-32-chars -S3_ENDPOINT=localhost -S3_PORT=9000 -S3_USE_SSL=false -S3_ACCESS_KEY=minioadmin -S3_SECRET_KEY=minioadmin -S3_REGION=us-east-1 -S3_BUCKET_NAME=palmr-files -S3_FORCE_PATH_STYLE=true +# For use with S3 compatible +# S3_ENDPOINT=localhost +# S3_PORT=9000 +# S3_USE_SSL=false +# S3_ACCESS_KEY=minioadmin +# S3_SECRET_KEY=minioadmin +# S3_REGION=us-east-1 +# S3_BUCKET_NAME=palmr-files +# S3_FORCE_PATH_STYLE=true diff --git a/apps/server/.gitignore b/apps/server/.gitignore index 4cd7f41..9eb8e53 100644 --- a/apps/server/.gitignore +++ b/apps/server/.gitignore @@ -2,3 +2,4 @@ node_modules .env dist/* uploads/* +temp-chunks/* diff --git a/apps/server/Dockerfile b/apps/server/Dockerfile deleted file mode 100644 index 1995c85..0000000 --- a/apps/server/Dockerfile +++ /dev/null @@ -1,26 +0,0 @@ -FROM node:22-alpine - -WORKDIR /app/server - -RUN apk add --no-cache netcat-openbsd -RUN npm install -g pnpm - -COPY package*.json ./ -COPY pnpm-lock.yaml ./ -COPY prisma ./prisma/ -COPY scripts ./scripts/ - -RUN rm -rf node_modules/.prisma - -RUN pnpm install --frozen-lockfile - -RUN npx prisma generate - -COPY . . - -RUN pnpm build -RUN chmod +x ./scripts/start.sh - -EXPOSE 3333 - -CMD ["./scripts/start.sh"] diff --git a/apps/server/docker-compose-postgres.yaml b/apps/server/docker-compose-postgres.yaml new file mode 100644 index 0000000..03ea0fe --- /dev/null +++ b/apps/server/docker-compose-postgres.yaml @@ -0,0 +1,22 @@ +services: + postgres: + image: bitnami/postgresql:17.2.0 + container_name: palmr-postgres + ports: + - "5432:5432" + environment: + - POSTGRESQL_USERNAME=palmr + - POSTGRESQL_PASSWORD=palmr123 + - POSTGRESQL_DATABASE=palmr + volumes: + - postgres_data:/bitnami/postgresql + restart: "unless-stopped" + healthcheck: + test: ["CMD", "pg_isready", "-U", "palmr"] + interval: 10s + timeout: 5s + retries: 5 + +volumes: + postgres_data: + minio_data: diff --git a/apps/server/docker-compose.yaml b/apps/server/docker-compose.yaml deleted file mode 100644 index f13c33a..0000000 --- a/apps/server/docker-compose.yaml +++ /dev/null @@ -1,42 +0,0 @@ -services: - - minio: - image: minio/minio:RELEASE.2025-03-12T18-04-18Z - container_name: minio - ports: - - "9000:9000" - - "9001:9001" - environment: - - MINIO_ROOT_USER=palmr - - MINIO_ROOT_PASSWORD=palmr123 - volumes: - - minio_data:/data - command: server /data --console-address ":9001" - restart: "unless-stopped" - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/ready"] - interval: 10s - timeout: 5s - retries: 5 - - postgres: - image: bitnami/postgresql:17.2.0 - container_name: palmr-postgres - ports: - - "5432:5432" - environment: - - POSTGRESQL_USERNAME=palmr - - POSTGRESQL_PASSWORD=palmr123 - - POSTGRESQL_DATABASE=palmr - volumes: - - postgres_data:/bitnami/postgresql - restart: "unless-stopped" - healthcheck: - test: ["CMD", "pg_isready", "-U", "palmr"] - interval: 10s - timeout: 5s - retries: 5 - -volumes: - postgres_data: - minio_data: diff --git a/apps/server/src/env.ts b/apps/server/src/env.ts index b7ad522..2b1adbe 100644 --- a/apps/server/src/env.ts +++ b/apps/server/src/env.ts @@ -12,9 +12,7 @@ const envSchema = z.object({ S3_REGION: z.string().optional(), S3_BUCKET_NAME: z.string().optional(), S3_FORCE_PATH_STYLE: z.union([z.literal("true"), z.literal("false")]).default("false"), - PORT: z.string().min(1), DATABASE_URL: z.string().min(1), - SERVER_IP: z.string().min(1), MAX_FILESIZE: z.string().min(1), }); diff --git a/apps/server/src/server.ts b/apps/server/src/server.ts index 136b107..2483321 100644 --- a/apps/server/src/server.ts +++ b/apps/server/src/server.ts @@ -70,15 +70,15 @@ async function startServer() { app.register(healthRoutes); await app.listen({ - port: Number(env.PORT), + port: 3333, host: "0.0.0.0", }); - console.log(`🌓 Palmr server running on port ${env.PORT} 🌓`); + console.log(`🌓 Palmr server running on port 3333 🌓`); console.log(`šŸ“¦ Storage mode: ${env.ENABLE_S3 === "true" ? "S3" : "Local Filesystem (Encrypted)"}`); console.log("\nšŸ“š API Documentation:"); - console.log(` - API Reference: http://localhost:${env.PORT}/docs\n`); + console.log(` - API Reference: http://localhost:3333/docs\n`); } startServer().catch((err) => { diff --git a/apps/web/Dockerfile b/apps/web/Dockerfile deleted file mode 100644 index 8bb581f..0000000 --- a/apps/web/Dockerfile +++ /dev/null @@ -1,46 +0,0 @@ -# Use the official Node.js image as the base image - -FROM node:22-alpine AS base - -# Install dependencies only when needed -FROM base AS deps -RUN apk add --no-cache libc6-compat -WORKDIR /app - -# Install dependencies based on the preferred package manager -COPY package.json pnpm-lock.yaml ./ -RUN corepack enable pnpm && pnpm install --frozen-lockfile - -# Rebuild the source code only when needed -FROM base AS builder -WORKDIR /app -COPY --from=deps /app/node_modules ./node_modules -COPY . . - -ENV NEXT_TELEMETRY_DISABLED=1 -ENV NODE_ENV=production - -RUN corepack enable pnpm && pnpm run build - -# Production image, copy all the files and run next -FROM base AS runner -WORKDIR /app - -ENV NODE_ENV=production -ENV NEXT_TELEMETRY_DISABLED=1 - -RUN addgroup --system --gid 1001 nodejs -RUN adduser --system --uid 1001 nextjs - -COPY --from=builder /app/public ./public -COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ -COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static - -USER nextjs - -EXPOSE 5487 - -ENV PORT=5487 -ENV HOSTNAME="0.0.0.0" - -CMD ["node", "server.js"] \ No newline at end of file diff --git a/apps/web/docker-compose.yml b/apps/web/docker-compose.yml deleted file mode 100644 index ccaaa0d..0000000 --- a/apps/web/docker-compose.yml +++ /dev/null @@ -1,17 +0,0 @@ -services: - web: - build: - context: . - dockerfile: Dockerfile - ports: - - "6644:3000" - environment: - - NODE_ENV=production - - NEXT_TELEMETRY_DISABLED=1 - - API_BASE_URL=http://host.docker.internal:3333 - restart: unless-stopped - healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:3000"] - interval: 30s - timeout: 10s - retries: 3 diff --git a/apps/web/src/components/modals/upload-file-modal.tsx b/apps/web/src/components/modals/upload-file-modal.tsx index 81b28a0..a93c9ea 100644 --- a/apps/web/src/components/modals/upload-file-modal.tsx +++ b/apps/web/src/components/modals/upload-file-modal.tsx @@ -1,7 +1,14 @@ "use client"; import { useEffect, useRef, useState } from "react"; -import { IconCloudUpload, IconFileText, IconFileTypePdf, IconFileTypography, IconPhoto } from "@tabler/icons-react"; +import { + IconCloudUpload, + IconFileText, + IconFileTypePdf, + IconFileTypography, + IconLoader, + IconPhoto, +} from "@tabler/icons-react"; import axios from "axios"; import { useTranslations } from "next-intl"; import { toast } from "sonner"; @@ -181,7 +188,7 @@ export function UploadFileModal({ isOpen, onClose, onSuccess }: UploadFileModalP

- {t("uploadFile.uploading")} {uploadProgress}% //!TODO Add translations + {t("uploadFile.uploadProgress")}: {uploadProgress}%

)} @@ -193,7 +200,11 @@ export function UploadFileModal({ isOpen, onClose, onSuccess }: UploadFileModalP {t("common.cancel")} diff --git a/docker-compose-file-system.yaml b/docker-compose-file-system.yaml new file mode 100644 index 0000000..3d3a718 --- /dev/null +++ b/docker-compose-file-system.yaml @@ -0,0 +1,66 @@ +services: + palmr: + image: kyantech/palmr:latest # Make sure to use the correct version (latest) of the image + container_name: palmr-application + depends_on: + postgres: + condition: "service_healthy" + environment: + # Storage Configuration + - ENABLE_S3=false # Set to 'false' to use local filesystem storage instead of S3/MinIO or true to use S3/MinIO in this case we are using filesystem storage + - ENCRYPTION_KEY=${ENCRYPTION_KEY:-change-this-key-in-production-min-32-chars} # Required for filesystem encryption (min 32 chars) + + # Server environment variables + - DATABASE_URL=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgresRootPassword}@postgres:${DB_EXTERNAL_PORT:-5432}/${POSTGRES_DB:-palmr_db}?schema=public # Database URL with configurable credentials through env vars + - FRONTEND_URL=http://palmr:${APP_EXTERNAL_PORT:-5487} # Frontend URL - Make sure to use the correct frontend URL, depends on where the frontend is running, its prepared for localhost, but you can change it to your frontend URL if needed + - MAX_FILESIZE=${MAX_FILESIZE:-1073741824} # Max Filesize for upload - Declared in Bytes. Default is 1GiB. can be changed by admin in the frontend. + + # Web environment variables + - NODE_ENV=production # Always set to production for better performance + - NEXT_TELEMETRY_DISABLED=1 # Disable telemetry for better performance + - API_BASE_URL=http://palmr:3333 # Using Docker service name for internal communication + ports: + - "${API_EXTERNAL_PORT:-3333}:3333" # Server port (default: 3333) can be overridden by env var + - "${APP_EXTERNAL_PORT:-5487}:5487" # Web port (default: 5487) can be overridden by env var + volumes: + - palmr_uploads:/app/server/uploads # Uploads folder for the application + - palmr_temp_chunks:/app/server/temp-chunks # Temp chunks folder for the application + networks: + - palmr-network # Network for the application to communicate with the database + restart: unless-stopped + healthcheck: + test: ["CMD", "sh", "-c", "wget --no-verbose --tries=1 --spider http://palmr:3333/health && wget --no-verbose --tries=1 --spider http://palmr:5487"] # Healthcheck for the application + interval: 30s + timeout: 10s + retries: 5 + start_period: 120s + + postgres: + image: postgres:16-alpine # You can use any postgres version you prefer, but remember that some versions might not be compatible + container_name: palmr-database + environment: + - POSTGRES_USER=${POSTGRES_USER:-postgres} # PostgreSQL username (default: postgres) can be overridden by env var + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgresRootPassword} # PostgreSQL password (default: postgresRootPassword) can be overridden by env var + - POSTGRES_DB=${POSTGRES_DB:-palmr_db} # PostgreSQL database name (default: palmr_db) can be overridden by env var + volumes: + - postgres_data:/var/lib/postgresql/data # PostgreSQL data volume for the application + ports: + - "${DB_EXTERNAL_PORT:-5432}:5432" # PostgreSQL port (default: 5432) can be overridden by env var + networks: + - palmr-network # Network for the application to communicate with the database + restart: unless-stopped + healthcheck: + test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER:-postgres}", "-d", "${POSTGRES_DB:-palmr_db}"] # Healthcheck for the database + interval: 5s + timeout: 3s + retries: 6 + start_period: 30s + +volumes: + postgres_data: + palmr_uploads: + palmr_temp_chunks: + +networks: + palmr-network: + driver: bridge \ No newline at end of file diff --git a/docker-compose-s3-minio.yaml b/docker-compose-s3-minio.yaml new file mode 100644 index 0000000..a52ddb7 --- /dev/null +++ b/docker-compose-s3-minio.yaml @@ -0,0 +1,68 @@ +services: + palmr: + image: kyantech/palmr:latest # Make sure to use the correct version (latest) of the image + container_name: palmr-application + depends_on: + postgres: + condition: "service_healthy" + environment: + # S3/MinIO Configuration (only used when ENABLE_S3=true) + - ENABLE_S3=true # Set to 'false' to use local filesystem storage instead of S3/MinIO or true to use S3/MinIO in this case we are using filesystem storage + - S3_ENDPOINT=${S3_ENDPOINT:-localhost} # S3/MinIO minio server ip or 'localhost' if you are running minio in local machine (don't use the dns name of the minio server use the ip address) + - S3_PORT=${S3_PORT:-9000} # S3/MinIO minio server port + - S3_USE_SSL=${S3_USE_SSL:-false} # S3/MinIO minio server use ssl false if you are running minio in local machine + - S3_ACCESS_KEY=${S3_ACCESS_KEY} # S3/MinIO minio server access key (you have to generate this key in minio server) + - S3_SECRET_KEY=${S3_SECRET_KEY} # S3/MinIO minio server secret key (you have to generate this key in minio server) + - S3_REGION=${S3_REGION:-us-east-1} # S3/MinIO minio server region (us-east-1 is the default region) but it depends on your minio server region + - S3_BUCKET_NAME=${S3_BUCKET_NAME:-palmr-files} # Bucket name for the S3/MinIO storage (here we are using palmr-files as the bucket name to understand that this is the bucket for palmr) + - S3_FORCE_PATH_STYLE=${S3_FORCE_PATH_STYLE:-true} # For minio compatibility we have to set this to true + + # Server environment variables + - DATABASE_URL=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgresRootPassword}@postgres:${DB_EXTERNAL_PORT:-5432}/${POSTGRES_DB:-palmr_db}?schema=public # Database URL with configurable credentials through env vars + - FRONTEND_URL=http://palmr:${APP_EXTERNAL_PORT:-5487} # Frontend URL - Make sure to use the correct frontend URL, depends on where the frontend is running, its prepared for localhost, but you can change it to your frontend URL if needed + - MAX_FILESIZE=${MAX_FILESIZE:-1073741824} # Max Filesize for upload - Declared in Bytes. Default is 1GiB. can be changed by admin in the frontend. + + # Web environment variables + - NODE_ENV=production # Always set to production for better performance + - NEXT_TELEMETRY_DISABLED=1 # Disable telemetry for better performance + - API_BASE_URL=http://palmr:3333 # Using Docker service name for internal communication + ports: + - "${API_EXTERNAL_PORT:-3333}:3333" # Server port (default: 3333) can be overridden by env var + - "${APP_EXTERNAL_PORT:-5487}:5487" # Web port (default: 5487) can be overridden by env var + networks: + - palmr-network # Network for the application to communicate with the database + restart: unless-stopped + healthcheck: + test: ["CMD", "sh", "-c", "wget --no-verbose --tries=1 --spider http://palmr:3333/health && wget --no-verbose --tries=1 --spider http://palmr:5487"] # Healthcheck for the application + interval: 30s + timeout: 10s + retries: 5 + start_period: 120s + + postgres: + image: postgres:16-alpine # You can use any postgres version you prefer, but remember that some versions might not be compatible + container_name: palmr-database + environment: + - POSTGRES_USER=${POSTGRES_USER:-postgres} # PostgreSQL username (default: postgres) can be overridden by env var + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgresRootPassword} # PostgreSQL password (default: postgresRootPassword) can be overridden by env var + - POSTGRES_DB=${POSTGRES_DB:-palmr_db} # PostgreSQL database name (default: palmr_db) can be overridden by env var + volumes: + - postgres_data:/var/lib/postgresql/data # PostgreSQL data volume for the application + ports: + - "${DB_EXTERNAL_PORT:-5432}:5432" # PostgreSQL port (default: 5432) can be overridden by env var + networks: + - palmr-network # Network for the application to communicate with the database + restart: unless-stopped + healthcheck: + test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER:-postgres}", "-d", "${POSTGRES_DB:-palmr_db}"] # Healthcheck for the database + interval: 5s + timeout: 3s + retries: 6 + start_period: 30s + +volumes: + postgres_data: + +networks: + palmr-network: + driver: bridge \ No newline at end of file diff --git a/docker-compose-s3.yaml b/docker-compose-s3.yaml new file mode 100644 index 0000000..37a68f2 --- /dev/null +++ b/docker-compose-s3.yaml @@ -0,0 +1,67 @@ +services: + palmr: + image: kyantech/palmr:latest # Make sure to use the correct version (latest) of the image + container_name: palmr-application + depends_on: + postgres: + condition: "service_healthy" + environment: + # S3 Configuration (only used when ENABLE_S3=true) + - ENABLE_S3=true # Set to true to use S3 storage + - S3_ENDPOINT=${S3_ENDPOINT} # S3 endpoint (you have to set this to the s3 endpoint of the s3 server) CHANGE THIS TO YOUR S3 ENDPOINT + - S3_USE_SSL=${S3_USE_SSL:-true} # Use ssl for the s3 server always true for s3 + - S3_ACCESS_KEY=${S3_ACCESS_KEY} # S3 access key (you have to generate this key in s3 server) + - S3_SECRET_KEY=${S3_SECRET_KEY} # S3 secret key (you have to generate this key in s3 server) + - S3_REGION=${S3_REGION:-us-east-1} # S3 region (us-east-1 is the default region) but it depends on your s3 server region + - S3_BUCKET_NAME=${S3_BUCKET_NAME:-palmr-files} # Bucket name for the S3 storage (here we are using palmr-files as the bucket name to understand that this is the bucket for palmr) + - S3_FORCE_PATH_STYLE=${S3_FORCE_PATH_STYLE:-false} # For S3 compatibility we have to set this to false + + # Server environment variables + - DATABASE_URL=postgresql://${POSTGRES_USER:-postgres}:${POSTGRES_PASSWORD:-postgresRootPassword}@postgres:${DB_EXTERNAL_PORT:-5432}/${POSTGRES_DB:-palmr_db}?schema=public # Database URL with configurable credentials through env vars + - FRONTEND_URL=http://palmr:${APP_EXTERNAL_PORT:-5487} # Frontend URL - Make sure to use the correct frontend URL, depends on where the frontend is running, its prepared for localhost, but you can change it to your frontend URL if needed + - MAX_FILESIZE=${MAX_FILESIZE:-1073741824} # Max Filesize for upload - Declared in Bytes. Default is 1GiB. can be changed by admin in the frontend. + + # Web environment variables + - NODE_ENV=production # Always set to production for better performance + - NEXT_TELEMETRY_DISABLED=1 # Disable telemetry for better performance + - API_BASE_URL=http://palmr:3333 # Using Docker service name for internal communication + ports: + - "${API_EXTERNAL_PORT:-3333}:3333" # Server port (default: 3333) can be overridden by env var + - "${APP_EXTERNAL_PORT:-5487}:5487" # Web port (default: 5487) can be overridden by env var + networks: + - palmr-network # Network for the application to communicate with the database + restart: unless-stopped + healthcheck: + test: ["CMD", "sh", "-c", "wget --no-verbose --tries=1 --spider http://palmr:3333/health && wget --no-verbose --tries=1 --spider http://palmr:5487"] # Healthcheck for the application + interval: 30s + timeout: 10s + retries: 5 + start_period: 120s + + postgres: + image: postgres:16-alpine # You can use any postgres version you prefer, but remember that some versions might not be compatible + container_name: palmr-database + environment: + - POSTGRES_USER=${POSTGRES_USER:-postgres} # PostgreSQL username (default: postgres) can be overridden by env var + - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-postgresRootPassword} # PostgreSQL password (default: postgresRootPassword) can be overridden by env var + - POSTGRES_DB=${POSTGRES_DB:-palmr_db} # PostgreSQL database name (default: palmr_db) can be overridden by env var + volumes: + - postgres_data:/var/lib/postgresql/data # PostgreSQL data volume for the application + ports: + - "${DB_EXTERNAL_PORT:-5432}:5432" # PostgreSQL port (default: 5432) can be overridden by env var + networks: + - palmr-network # Network for the application to communicate with the database + restart: unless-stopped + healthcheck: + test: ["CMD", "pg_isready", "-U", "${POSTGRES_USER:-postgres}", "-d", "${POSTGRES_DB:-palmr_db}"] # Healthcheck for the database + interval: 5s + timeout: 3s + retries: 6 + start_period: 30s + +volumes: + postgres_data: + +networks: + palmr-network: + driver: bridge \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml deleted file mode 100644 index 676d28b..0000000 --- a/docker-compose.yaml +++ /dev/null @@ -1,82 +0,0 @@ -services: - palmr: - image: kyantech/palmr:latest # Make sure to use the correct version (latest) of the image - container_name: palmr - depends_on: - postgres: - condition: "service_healthy" - environment: - # Storage Configuration - - ENABLE_S3=${ENABLE_S3:-false} # Set to 'false' to use local filesystem storage instead of S3/MinIO or true to use S3/MinIO - - ENCRYPTION_KEY=${ENCRYPTION_KEY:-change-this-key-in-production-min-32-chars} # Required for filesystem encryption (min 32 chars) - - # Server environment variables - - PORT=${API_INTERNAL_PORT:-3333} # Port for the backend service - - DATABASE_URL=postgresql://postgres:${POSTGRESQL_PASSWORD:-postgresRootPassword}@postgres:5432/palmr_db?schema=public # Database URL with configurable password through POSTGRESQL_PASSWORD env var - - # S3/MinIO Configuration (only used when ENABLE_S3=true) - # - S3_ENDPOINT=localhost - # - S3_PORT=9000 - # - S3_USE_SSL=false - # - S3_ACCESS_KEY=K0l63C4OVEMwhmudABZF - # - S3_SECRET_KEY=9xMHpE9QgAye17abq7Lf6qzkCtDMEZeIjMNXt1x7 - # - S3_REGION=us-east-1 - # - S3_BUCKET_NAME=palmr-files - # - S3_FORCE_PATH_STYLE=true - - # Timeout Configuration - # - KEEP_ALIVE_TIMEOUT=72000000 # 20 hours in milliseconds - # - REQUEST_TIMEOUT=0 # Disabled (0) - # - TOKEN_EXPIRATION=3600000 # 1 hour in milliseconds - - # Application Configuration - - FRONTEND_URL=${APP_URL:-http://${SERVER_IP:-localhost}:${APP_EXTERNAL_PORT:-5487}} # Frontend URL - Make sure to use the correct frontend URL, depends on where the frontend is running, its prepared for localhost, but you can change it to your frontend URL if needed - - SERVER_IP=${SERVER_IP:-localhost} # Server IP - Make sure to use the correct server IP if you running on a cloud provider or a virtual machine. This prepared for localhost, but you can change it to your server IP if needed - - MAX_FILESIZE=${MAX_FILESIZE:-1073741824} # Max Filesize for upload - Declared in Bytes. Default is 1GiB - - # Web environment variables - - NODE_ENV=production - - NEXT_TELEMETRY_DISABLED=1 - - API_BASE_URL=http://palmr:${API_INTERNAL_PORT:-3333} # Using Docker service name for internal communication - ports: - - "${API_EXTERNAL_PORT:-3333}:3333" # Server port - - "${APP_EXTERNAL_PORT:-5487}:5487" # Web port - volumes: - # Persistent storage for filesystem mode (only used when ENABLE_S3=false) - - palmr_uploads:/app/server/uploads - - palmr_temp_chunks:/app/server/temp-chunks - restart: unless-stopped - healthcheck: - test: ["CMD", "wget", "--no-verbose", "http://palmr:${API_INTERNAL_PORT:-3333}/health", "&&", "wget", "--no-verbose", "http://palmr:${APP_INTERNAL_PORT:-5487}"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 60s - - - - postgres: - image: bitnami/postgresql:17.2.0 # You can use any postgres version you prefer, but remember that some versions might not be compatible - container_name: palmr-postgres - environment: - # PostgreSQL credentials configurable through environment variables - # POSTGRESQL_USERNAME, POSTGRESQL_PASSWORD, and POSTGRES_DB can be set to override defaults - - POSTGRESQL_USERNAME=${POSTGRESQL_USERNAME:-postgres} - - POSTGRESQL_PASSWORD=${POSTGRESQL_PASSWORD:-postgresRootPassword} - - POSTGRESQL_DATABASE=${POSTGRES_DATABASE:-palmr_db} - volumes: - - postgres_data:/bitnami/postgresql - ports: - - "5432:5432" - restart: unless-stopped - healthcheck: - test: ["CMD", "pg_isready", "-U", "palmr"] - interval: 10s - timeout: 5s - retries: 5 - -volumes: - postgres_data: - # Volumes for filesystem storage mode - palmr_uploads: - palmr_temp_chunks: \ No newline at end of file diff --git a/infra/server-start.sh b/infra/server-start.sh index 9e72016..c14435f 100644 --- a/infra/server-start.sh +++ b/infra/server-start.sh @@ -7,9 +7,11 @@ export HOME=/home/palmr export NPM_CONFIG_CACHE=/home/palmr/.npm export PNPM_HOME=/home/palmr/.pnpm -# Wait for PostgreSQL -echo "Waiting for PostgreSQL..." -while ! nc -z postgres 5432; do +# Wait for PostgreSQL - use environment variable or default to postgres +DB_HOST=${DB_HOST:-postgres} +DB_PORT=${DB_PORT:-5432} +echo "Waiting for PostgreSQL at $DB_HOST:$DB_PORT..." +while ! nc -z $DB_HOST $DB_PORT; do sleep 1 done echo "PostgreSQL is up!"