mirror of
https://github.com/kyantech/Palmr.git
synced 2025-10-23 06:11:58 +00:00
feat: Enhance Docker setup and documentation for Palmr.
- Added a new `docker-compose-bind-mount-example.yaml` for easier bind mount configuration. - Updated `.gitignore` to include the `data/` directory for persistent storage. - Modified `docker-compose.yaml` to clarify volume paths and improve comments. - Enhanced `Dockerfile` to support flexible UID/GID configuration and ensure proper directory permissions. - Updated environment variable handling in `server-start.sh` and Prisma configuration for better database management. - Revised documentation in `quick-start.mdx` and `uid-gid-configuration.mdx` to reflect new features and best practices for deployment.
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -29,4 +29,5 @@ apps/server/.env
|
|||||||
apps/server/dist/*
|
apps/server/dist/*
|
||||||
|
|
||||||
#DEFAULT
|
#DEFAULT
|
||||||
.env
|
.env
|
||||||
|
data/
|
92
Dockerfile
92
Dockerfile
@@ -1,10 +1,11 @@
|
|||||||
FROM node:20-alpine AS base
|
FROM node:20-alpine AS base
|
||||||
|
|
||||||
# Install system dependencies (removed netcat-openbsd since we no longer need to wait for PostgreSQL)
|
# Install system dependencies
|
||||||
RUN apk add --no-cache \
|
RUN apk add --no-cache \
|
||||||
gcompat \
|
gcompat \
|
||||||
supervisor \
|
supervisor \
|
||||||
curl
|
curl \
|
||||||
|
su-exec
|
||||||
|
|
||||||
# Enable pnpm
|
# Enable pnpm
|
||||||
RUN corepack enable pnpm
|
RUN corepack enable pnpm
|
||||||
@@ -80,15 +81,12 @@ ARG PALMR_GID=1001
|
|||||||
RUN addgroup --system --gid ${PALMR_GID} nodejs
|
RUN addgroup --system --gid ${PALMR_GID} nodejs
|
||||||
RUN adduser --system --uid ${PALMR_UID} --ingroup nodejs palmr
|
RUN adduser --system --uid ${PALMR_UID} --ingroup nodejs palmr
|
||||||
|
|
||||||
# Create application directories and set permissions
|
# Create application directories
|
||||||
# Include storage directories for filesystem mode and SQLite database directory
|
RUN mkdir -p /app/palmr-app /app/web /home/palmr/.npm /home/palmr/.cache
|
||||||
RUN mkdir -p /app/server /app/web /home/palmr/.npm /home/palmr/.cache \
|
|
||||||
/app/server/uploads /app/server/temp-chunks /app/server/uploads/logo \
|
|
||||||
/app/server/prisma
|
|
||||||
RUN chown -R palmr:nodejs /app /home/palmr
|
RUN chown -R palmr:nodejs /app /home/palmr
|
||||||
|
|
||||||
# === Copy Server Files ===
|
# === Copy Server Files to /app/palmr-app (separate from /app/server for bind mounts) ===
|
||||||
WORKDIR /app/server
|
WORKDIR /app/palmr-app
|
||||||
|
|
||||||
# Copy server production files
|
# Copy server production files
|
||||||
COPY --from=server-builder --chown=palmr:nodejs /app/server/dist ./dist
|
COPY --from=server-builder --chown=palmr:nodejs /app/server/dist ./dist
|
||||||
@@ -101,8 +99,9 @@ COPY --from=server-builder --chown=palmr:nodejs /app/server/reset-password.sh ./
|
|||||||
COPY --from=server-builder --chown=palmr:nodejs /app/server/src/scripts/ ./src/scripts/
|
COPY --from=server-builder --chown=palmr:nodejs /app/server/src/scripts/ ./src/scripts/
|
||||||
RUN chmod +x ./reset-password.sh
|
RUN chmod +x ./reset-password.sh
|
||||||
|
|
||||||
# Ensure storage directories have correct permissions
|
# Copy seed file to the shared location for bind mounts
|
||||||
RUN chown -R palmr:nodejs /app/server/uploads /app/server/temp-chunks /app/server/prisma
|
RUN mkdir -p /app/server/prisma
|
||||||
|
COPY --from=server-builder --chown=palmr:nodejs /app/server/prisma/seed.js /app/server/prisma/seed.js
|
||||||
|
|
||||||
# === Copy Web Files ===
|
# === Copy Web Files ===
|
||||||
WORKDIR /app/web
|
WORKDIR /app/web
|
||||||
@@ -123,7 +122,7 @@ COPY infra/server-start.sh /app/server-start.sh
|
|||||||
RUN chmod +x /app/server-start.sh
|
RUN chmod +x /app/server-start.sh
|
||||||
RUN chown palmr:nodejs /app/server-start.sh
|
RUN chown palmr:nodejs /app/server-start.sh
|
||||||
|
|
||||||
# Copy supervisor configuration (simplified without PostgreSQL dependency)
|
# Copy supervisor configuration (updated paths)
|
||||||
COPY <<EOF /etc/supervisor/conf.d/supervisord.conf
|
COPY <<EOF /etc/supervisor/conf.d/supervisord.conf
|
||||||
[supervisord]
|
[supervisord]
|
||||||
nodaemon=true
|
nodaemon=true
|
||||||
@@ -132,9 +131,9 @@ logfile=/var/log/supervisor/supervisord.log
|
|||||||
pidfile=/var/run/supervisord.pid
|
pidfile=/var/run/supervisord.pid
|
||||||
|
|
||||||
[program:server]
|
[program:server]
|
||||||
command=/app/server-start.sh
|
command=/bin/sh -c "export DATABASE_URL='file:/app/server/prisma/palmr.db' && export UPLOAD_PATH='/app/server/uploads' && export TEMP_CHUNKS_PATH='/app/server/temp-chunks' && /app/server-start.sh"
|
||||||
directory=/app/server
|
directory=/app/palmr-app
|
||||||
user=palmr
|
user=root
|
||||||
autostart=true
|
autostart=true
|
||||||
autorestart=true
|
autorestart=true
|
||||||
stderr_logfile=/var/log/supervisor/server.err.log
|
stderr_logfile=/var/log/supervisor/server.err.log
|
||||||
@@ -155,7 +154,7 @@ priority=200
|
|||||||
startsecs=10
|
startsecs=10
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
# Create main startup script with UID/GID runtime support
|
# Create main startup script
|
||||||
COPY <<EOF /app/start.sh
|
COPY <<EOF /app/start.sh
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
@@ -164,56 +163,15 @@ echo "Starting Palmr Application..."
|
|||||||
echo "Storage Mode: \${ENABLE_S3:-false}"
|
echo "Storage Mode: \${ENABLE_S3:-false}"
|
||||||
echo "Database: SQLite"
|
echo "Database: SQLite"
|
||||||
|
|
||||||
# Runtime UID/GID configuration - only apply if environment variables are set
|
# Set global environment variables
|
||||||
if [ -n "\${PALMR_UID}" ] || [ -n "\${PALMR_GID}" ]; then
|
export DATABASE_URL="file:/app/server/prisma/palmr.db"
|
||||||
RUNTIME_UID=\${PALMR_UID:-${PALMR_UID}}
|
export UPLOAD_PATH="/app/server/uploads"
|
||||||
RUNTIME_GID=\${PALMR_GID:-${PALMR_GID}}
|
export TEMP_CHUNKS_PATH="/app/server/temp-chunks"
|
||||||
|
|
||||||
echo "Runtime UID/GID configuration detected: UID=\$RUNTIME_UID, GID=\$RUNTIME_GID"
|
|
||||||
|
|
||||||
# Get current user/group IDs
|
|
||||||
CURRENT_UID=\$(id -u palmr 2>/dev/null || echo "${PALMR_UID}")
|
|
||||||
CURRENT_GID=\$(id -g palmr 2>/dev/null || echo "${PALMR_GID}")
|
|
||||||
|
|
||||||
# Only modify if different from current
|
|
||||||
if [ "\$CURRENT_UID" != "\$RUNTIME_UID" ] || [ "\$CURRENT_GID" != "\$RUNTIME_GID" ]; then
|
|
||||||
echo "Adjusting user/group IDs from \$CURRENT_UID:\$CURRENT_GID to \$RUNTIME_UID:\$RUNTIME_GID"
|
|
||||||
|
|
||||||
# Modify group if needed
|
|
||||||
if [ "\$CURRENT_GID" != "\$RUNTIME_GID" ]; then
|
|
||||||
if getent group \$RUNTIME_GID >/dev/null 2>&1; then
|
|
||||||
EXISTING_GROUP=\$(getent group \$RUNTIME_GID | cut -d: -f1)
|
|
||||||
echo "Using existing group with GID \$RUNTIME_GID: \$EXISTING_GROUP"
|
|
||||||
usermod -g \$EXISTING_GROUP palmr 2>/dev/null || echo "Warning: Could not change user group"
|
|
||||||
else
|
|
||||||
groupmod -g \$RUNTIME_GID nodejs 2>/dev/null || echo "Warning: Could not modify group GID"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Modify user if needed
|
|
||||||
if [ "\$CURRENT_UID" != "\$RUNTIME_UID" ]; then
|
|
||||||
if getent passwd \$RUNTIME_UID >/dev/null 2>&1; then
|
|
||||||
EXISTING_USER=\$(getent passwd \$RUNTIME_UID | cut -d: -f1)
|
|
||||||
echo "Warning: UID \$RUNTIME_UID already exists as user '\$EXISTING_USER'"
|
|
||||||
echo "Container will continue but may have permission issues"
|
|
||||||
else
|
|
||||||
usermod -u \$RUNTIME_UID palmr 2>/dev/null || echo "Warning: Could not modify user UID"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Update file ownership for application directories
|
|
||||||
echo "Updating file ownership for application directories..."
|
|
||||||
chown -R palmr:nodejs /app /home/palmr 2>/dev/null || echo "Warning: Could not update all file ownership"
|
|
||||||
else
|
|
||||||
echo "Runtime UID/GID matches current values, no changes needed"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "No runtime UID/GID configuration provided, using defaults"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Ensure storage directories exist with correct permissions
|
# Ensure /app/server directory exists for bind mounts
|
||||||
mkdir -p /app/server/uploads /app/server/temp-chunks /app/server/uploads/logo /app/server/prisma
|
mkdir -p /app/server/uploads /app/server/temp-chunks /app/server/uploads/logo /app/server/prisma
|
||||||
chown -R palmr:nodejs /app/server/uploads /app/server/temp-chunks /app/server/prisma 2>/dev/null || echo "Warning: Could not set permissions on storage directories"
|
|
||||||
|
echo "Data directories ready for first run..."
|
||||||
|
|
||||||
# Start supervisor
|
# Start supervisor
|
||||||
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
exec /usr/bin/supervisord -c /etc/supervisor/conf.d/supervisord.conf
|
||||||
@@ -221,8 +179,8 @@ EOF
|
|||||||
|
|
||||||
RUN chmod +x /app/start.sh
|
RUN chmod +x /app/start.sh
|
||||||
|
|
||||||
# Create volume mount points for persistent storage (filesystem mode and SQLite database)
|
# Create volume mount points for bind mounts
|
||||||
VOLUME ["/app/server/uploads", "/app/server/temp-chunks", "/app/server/prisma"]
|
VOLUME ["/app/server"]
|
||||||
|
|
||||||
# Expose ports
|
# Expose ports
|
||||||
EXPOSE 3333 5487
|
EXPOSE 3333 5487
|
||||||
@@ -232,4 +190,4 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
|||||||
CMD curl -f http://localhost:5487 || exit 1
|
CMD curl -f http://localhost:5487 || exit 1
|
||||||
|
|
||||||
# Start application
|
# Start application
|
||||||
CMD ["/app/start.sh"]
|
CMD ["/app/start.sh"]
|
@@ -3,32 +3,50 @@ title: Quick Start (Docker)
|
|||||||
icon: "Rocket"
|
icon: "Rocket"
|
||||||
---
|
---
|
||||||
|
|
||||||
Hey there! Welcome to the fastest way to launch <span className="font-bold">Palmr.</span>, your very own secure <span className="font-bold italic">file sharing solution</span>. Whether you're a first-timer to <span className="font-bold italic">self-hosting</span> or a tech wizard, we've made this process incredibly straightforward. In just a few minutes, you'll have a sleek, user-friendly <span className="font-bold italic">file sharing platform</span> running on your <span className="font-bold italic">server</span> or <span className="font-bold italic">VPS</span>.
|
Welcome to the fastest way to deploy <span className="font-bold">Palmr.</span> - your secure, self-hosted file sharing solution. This guide will have you up and running in minutes, whether you're new to self-hosting or an experienced developer.
|
||||||
|
|
||||||
This guide is all about speed and simplicity, using our built-in <span className="font-bold italic">file storage system</span> ideal for most users. While Palmr. supports advanced setups like <span className="font-bold italic">manual installation</span> or <span className="font-bold italic">Amazon S3-compatible external storage</span>, we're focusing on the easiest path with <span className="font-bold italic">Docker Compose</span>. Curious about other options? Check out the dedicated sections in our docs for those advanced configurations.
|
Palmr. offers flexible deployment options to match your infrastructure needs. This guide focuses on Docker deployment with our recommended filesystem storage, perfect for most use cases.
|
||||||
|
|
||||||
Let's dive in and get Palmr. up and running!
|
## Prerequisites
|
||||||
|
|
||||||
## What you'll need
|
Ensure you have the following installed on your system:
|
||||||
|
|
||||||
To get started, you only need two tools installed on your system. Don't worry, they're easy to set up:
|
- **Docker** - Container runtime ([installation guide](https://docs.docker.com/get-docker/))
|
||||||
|
- **Docker Compose** - Multi-container orchestration ([installation guide](https://docs.docker.com/compose/install/))
|
||||||
|
|
||||||
- **Docker** ([https://docs.docker.com](https://docs.docker.com/)) - This will run Palmr. in a container.
|
> **Platform Support**: Palmr. is developed on macOS and extensively tested on Linux servers. While we haven't formally tested other platforms, Docker's cross-platform nature should ensure compatibility. Report any issues on our [GitHub repository](https://github.com/kyantech/Palmr/issues).
|
||||||
- **Docker Compose** ([https://docs.docker.com/compose](https://docs.docker.com/compose/)) - This helps manage the setup with a simple configuration file.
|
|
||||||
|
|
||||||
> **Note**: Palmr. was developed on **MacOS** and thoroughly tested on **Linux servers**, ensuring top-notch performance on these platforms. We haven't tested on **Windows** or other environments yet, so there might be some hiccups. Since we're still in **beta**, bugs can pop up anywhere. If you spot an issue, we'd love your help please report it on our GitHub [issues page](https://github.com/kyantech/Palmr/issues).
|
## Storage Options
|
||||||
|
|
||||||
## Setting up with Docker Compose
|
Palmr. supports two storage approaches for persistent data:
|
||||||
|
|
||||||
Docker Compose is the simplest way to deploy Palmr. across different environments. Once you've got Docker and Docker Compose installed, you're ready to roll with our streamlined setup.
|
### Named Volumes (Recommended)
|
||||||
|
|
||||||
In the root folder of the Palmr. project, you'll find a few compose files. For this guide, we're using `docker-compose.yaml` the only file you need to run Palmr. with file system storage. No need to build anything yourself; our pre-built images are hosted on [DockerHub](https://hub.docker.com/repositories/kyantech) and referenced in this file.
|
**Best for**: Production environments, automated deployments
|
||||||
|
|
||||||
You can tweak settings directly in `docker-compose.yaml` or use environment variables (more on that later). Let's take a closer look at what's inside this file.
|
- ✅ **Managed by Docker**: No permission issues or manual path management
|
||||||
|
- ✅ **Optimized Performance**: Docker-native storage optimization
|
||||||
|
- ✅ **Cross-platform**: Consistent behavior across operating systems
|
||||||
|
- ✅ **Simplified Backups**: Docker volume commands for backup/restore
|
||||||
|
|
||||||
## Exploring the docker-compose.yaml file
|
### Bind Mounts
|
||||||
|
|
||||||
Here's the full content of our `docker-compose.yaml`. Feel free to copy it from here or grab it from our official repository ([Docker Compose](https://github.com/kyantech/Palmr/blob/main/docker-compose.yaml)).
|
**Best for**: Development, direct file access requirements
|
||||||
|
|
||||||
|
- ✅ **Direct Access**: Files stored in local directory you specify
|
||||||
|
- ✅ **Transparent Storage**: Direct filesystem access from host
|
||||||
|
- ✅ **Custom Backup**: Use existing file system backup solutions
|
||||||
|
- ⚠️ **Permission Considerations**: May require user/group configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Option 1: Named Volumes (Recommended)
|
||||||
|
|
||||||
|
Named volumes provide the best performance and are managed entirely by Docker.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
Use the provided `docker-compose.yaml` for named volumes:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
@@ -39,103 +57,112 @@ services:
|
|||||||
- ENABLE_S3=false
|
- ENABLE_S3=false
|
||||||
- ENCRYPTION_KEY=change-this-key-in-production-min-32-chars # CHANGE THIS KEY FOR SECURITY
|
- ENCRYPTION_KEY=change-this-key-in-production-min-32-chars # CHANGE THIS KEY FOR SECURITY
|
||||||
ports:
|
ports:
|
||||||
- "5487:5487" # Web port
|
- "5487:5487" # Web interface
|
||||||
- "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY, IF YOU DONT WANT TO EXPOSE THE API, JUST REMOVE THIS LINE )
|
- "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY)
|
||||||
volumes:
|
volumes:
|
||||||
- palmr_data:/app/server # Volume for the application data
|
- palmr_data:/app/server # Named volume for the application data
|
||||||
restart: unless-stopped # Restart the container unless it is stopped
|
restart: unless-stopped # Restart the container unless it is stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
palmr_data:
|
palmr_data:
|
||||||
```
|
```
|
||||||
|
|
||||||
We've added helpful comments in the file to guide you through customization. Let's break down what you can adjust to fit your setup.
|
### Deployment
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Understanding the services
|
|
||||||
|
|
||||||
Palmr. runs as a single service in this filesystem storage setup. Here's a quick overview:
|
|
||||||
|
|
||||||
| **Service** | **Image** | **Exposed Ports** | **Main Features** |
|
|
||||||
| ----------- | ---------------------------------------------------------------------------------------- | --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
|
||||||
| palmr | [kyantech/palmr:latest](https://hub.docker.com/repository/docker/kyantech/palmr/general) | **3333** (API)<br/>**5487** (Web) | • Combined backend API and frontend service<br/>• Uses local filesystem storage<br/>• Has healthcheck to ensure availability |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Customizing with environment variables
|
|
||||||
|
|
||||||
You can fine-tune Palmr. using environment variables. Here's what's available for the filesystem storage setup:
|
|
||||||
|
|
||||||
| **Variable** | **Default Value** | **Description** |
|
|
||||||
| ---------------- | ------------------------------------------ | ------------------------------------------------------------ |
|
|
||||||
| `ENABLE_S3` | false | Set to 'false' for filesystem storage or 'true' for S3/MinIO |
|
|
||||||
| `ENCRYPTION_KEY` | change-this-key-in-production-min-32-chars | Required for filesystem encryption (minimum 32 characters) |
|
|
||||||
|
|
||||||
> **Important**: These variables can be set in a `.env` file at the project root or directly in your environment when running Docker Compose. The `ENCRYPTION_KEY` is crucial for securing your filesystem storage **always change it** to a unique, secure value in production. you can generate a secure key using the [KeyGenerator](/docs/3.0-beta/quick-start#generating-a-secure-encryption-key) tool.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### Managing persistent data
|
|
||||||
|
|
||||||
To ensure your data sticks around even if the container restarts, we use a persistent volume:
|
|
||||||
|
|
||||||
| **Volume** | **Description** |
|
|
||||||
| ------------ | ------------------------------------- |
|
|
||||||
| `palmr_data` | Stores all the data of Palmr. service |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Launching Palmr.
|
|
||||||
|
|
||||||
With your `docker-compose.yaml` ready, it's time to start Palmr.! Run this command to launch everything in the background:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
This runs Palmr. in **detached mode**, meaning it operates silently in the background without flooding your terminal with logs.
|
|
||||||
|
|
||||||
Now, open your browser and visit:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
http://localhost:5487
|
|
||||||
```
|
|
||||||
|
|
||||||
If you're on a server, replace `localhost` with your server's IP:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
http://[YOUR_SERVER_IP]:5487
|
|
||||||
```
|
|
||||||
|
|
||||||
For example, if your server IP is `192.168.1.10`, the URL would be `http://192.168.1.10:5487`. Remember, this is just an example use your actual server IP.
|
|
||||||
|
|
||||||
> **Pro Tip**: For full functionality and security, configure your server with **HTTPS** by setting up a valid SSL certificate.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Keeping Palmr. up to date
|
## Option 2: Bind Mounts
|
||||||
|
|
||||||
Want the latest features and fixes? Updating Palmr. is a breeze. Run these commands to pull the newest version from DockerHub and restart the service:
|
Bind mounts store data in a local directory, providing direct file system access.
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
|
||||||
|
To use bind mounts, **replace the content** of your `docker-compose.yaml` with the following configuration (you can also reference `docker-compose-bind-mount-example.yaml` as a template):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
palmr:
|
||||||
|
image: kyantech/palmr:latest
|
||||||
|
container_name: palmr
|
||||||
|
environment:
|
||||||
|
- ENABLE_S3=false
|
||||||
|
- ENCRYPTION_KEY=change-this-key-in-production-min-32-chars # CHANGE THIS KEY FOR SECURITY
|
||||||
|
# Optional: Set custom UID/GID for file permissions
|
||||||
|
# - PALMR_UID=1000
|
||||||
|
# - PALMR_GID=1000
|
||||||
|
ports:
|
||||||
|
- "5487:5487" # Web port
|
||||||
|
- "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY)
|
||||||
|
volumes:
|
||||||
|
# Bind mount for persistent data (uploads, database, temp files)
|
||||||
|
- ./data:/app/server # Local directory for the application data
|
||||||
|
restart: unless-stopped # Restart the container unless it is stopped
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose pull
|
|
||||||
docker-compose up -d
|
docker-compose up -d
|
||||||
```
|
```
|
||||||
|
|
||||||
That's it! You're now running the latest version of Palmr.
|
> **Permission Configuration**: If you encounter permission issues with bind mounts (common on NAS systems), see our [UID/GID Configuration](/docs/3.0-beta/uid-gid-configuration) guide for automatic permission handling.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Running with Docker (without Compose)
|
## Environment Variables
|
||||||
|
|
||||||
Prefer to skip Docker Compose and use plain Docker? No problem! Use this command to start Palmr. directly:
|
Configure Palmr. behavior through environment variables:
|
||||||
|
|
||||||
|
| Variable | Default | Description |
|
||||||
|
| ---------------- | ------- | ------------------------------------------------------- |
|
||||||
|
| `ENABLE_S3` | `false` | Enable S3-compatible storage |
|
||||||
|
| `ENCRYPTION_KEY` | - | **Required**: Minimum 32 characters for file encryption |
|
||||||
|
|
||||||
|
> **⚠️ Security Warning**: Always change the `ENCRYPTION_KEY` in production. This key encrypts your files - losing it makes files permanently inaccessible.
|
||||||
|
|
||||||
|
### Generate Secure Encryption Keys
|
||||||
|
|
||||||
|
Need a strong key for `ENCRYPTION_KEY`? Use our built-in generator to create cryptographically secure keys:
|
||||||
|
|
||||||
|
<KeyGenerator />
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Accessing Palmr.
|
||||||
|
|
||||||
|
Once deployed, access Palmr. through your web browser:
|
||||||
|
|
||||||
|
- **Local**: `http://localhost:5487`
|
||||||
|
- **Server**: `http://YOUR_SERVER_IP:5487`
|
||||||
|
|
||||||
|
### API Access (Optional)
|
||||||
|
|
||||||
|
If you exposed port 3333 in your configuration, you can also access:
|
||||||
|
|
||||||
|
- **API Documentation**: `http://localhost:3333/docs` (local) or `http://YOUR_SERVER_IP:3333/docs` (server)
|
||||||
|
- **API Endpoints**: Available at `http://localhost:3333` (local) or `http://YOUR_SERVER_IP:3333` (server)
|
||||||
|
|
||||||
|
> **📚 Learn More**: For complete API documentation, authentication, and integration examples, see our [API Reference](/docs/3.0-beta/api) guide.
|
||||||
|
|
||||||
|
> **💡 Production Tip**: For production deployments, configure HTTPS with a valid SSL certificate for enhanced security.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Docker CLI Alternative
|
||||||
|
|
||||||
|
Prefer using Docker directly? Both storage options are supported:
|
||||||
|
|
||||||
|
**Named Volume:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--name palmr \
|
--name palmr \
|
||||||
-e ENABLE_S3=false \
|
-e ENABLE_S3=false \
|
||||||
-e ENCRYPTION_KEY=change-this-key-in-production-min-32-chars \
|
-e ENCRYPTION_KEY=your-secure-key-min-32-chars \
|
||||||
-p 5487:5487 \
|
-p 5487:5487 \
|
||||||
-p 3333:3333 \
|
-p 3333:3333 \
|
||||||
-v palmr_data:/app/server \
|
-v palmr_data:/app/server \
|
||||||
@@ -143,22 +170,84 @@ docker run -d \
|
|||||||
kyantech/palmr:latest
|
kyantech/palmr:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
This also runs in detached mode, so it's hands-off. Access Palmr. at the same URLs mentioned earlier.
|
**Bind Mount:**
|
||||||
|
|
||||||
> **Critical Reminder**: Whichever method you choose, **change the `ENCRYPTION_KEY`** to a secure, unique value. This key encrypts your files on the filesystem if you lose it, your files become inaccessible.
|
```bash
|
||||||
|
docker run -d \
|
||||||
|
--name palmr \
|
||||||
|
-e ENABLE_S3=false \
|
||||||
|
-e ENCRYPTION_KEY=your-secure-key-min-32-chars \
|
||||||
|
-p 5487:5487 \
|
||||||
|
-p 3333:3333 \
|
||||||
|
-v $(pwd)/data:/app/server \
|
||||||
|
--restart unless-stopped \
|
||||||
|
kyantech/palmr:latest
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Generating a Secure Encryption Key
|
## Maintenance
|
||||||
|
|
||||||
Need a strong key for `ENCRYPTION_KEY`? Use our handy Password Generator Tool below to create one:
|
### Updates
|
||||||
|
|
||||||
<KeyGenerator />
|
Keep Palmr. current with the latest features and security fixes:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker-compose pull
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
### Backup & Restore
|
||||||
|
|
||||||
|
The backup method depends on which storage option you're using:
|
||||||
|
|
||||||
|
**Named Volume Backup:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm \
|
||||||
|
-v palmr_data:/data \
|
||||||
|
-v $(pwd):/backup \
|
||||||
|
alpine tar czf /backup/palmr-backup.tar.gz -C /data .
|
||||||
|
```
|
||||||
|
|
||||||
|
**Named Volume Restore:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker run --rm \
|
||||||
|
-v palmr_data:/data \
|
||||||
|
-v $(pwd):/backup \
|
||||||
|
alpine tar xzf /backup/palmr-backup.tar.gz -C /data
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bind Mount Backup:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tar czf palmr-backup.tar.gz ./data
|
||||||
|
```
|
||||||
|
|
||||||
|
**Bind Mount Restore:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
tar xzf palmr-backup.tar.gz
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## You're all set!
|
## Next Steps
|
||||||
|
|
||||||
Congratulations! You've just deployed your own secure file sharing solution with Palmr. in record time. We're thrilled to have you on board and hope you love using this powerful tool as much as we loved building it.
|
Your Palmr. instance is now ready! Explore additional configuration options:
|
||||||
|
|
||||||
Got questions or ideas? Dive into the rest of our documentation or reach out via our GitHub [issues page](https://github.com/kyantech/Palmr/issues). Happy sharing!
|
### Advanced Configuration
|
||||||
|
|
||||||
|
- **[UID/GID Configuration](/docs/3.0-beta/uid-gid-configuration)** - Configure user permissions for NAS systems and custom environments
|
||||||
|
- **[S3 Storage](/docs/3.0-beta/s3-configuration)** - Scale with Amazon S3 or compatible storage providers
|
||||||
|
- **[Manual Installation](/docs/3.0-beta/manual-installation)** - Manual installation and custom configurations
|
||||||
|
|
||||||
|
### Integration & Development
|
||||||
|
|
||||||
|
- **[API Reference](/docs/3.0-beta/api)** - Integrate Palmr. with your applications
|
||||||
|
- **[Architecture Guide](/docs/3.0-beta/architecture)** - Understanding Palmr. components and design
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Need help? Visit our [GitHub Issues](https://github.com/kyantech/Palmr/issues) or community discussions.
|
||||||
|
@@ -3,78 +3,62 @@ title: UID/GID Configuration
|
|||||||
icon: "Users"
|
icon: "Users"
|
||||||
---
|
---
|
||||||
|
|
||||||
Having trouble with **permission denied** errors when using bind-mounted directories? This guide will help you configure <span className="font-bold">Palmr.</span> to work seamlessly with your host system's <span className="font-bold italic">user and group permissions</span>.
|
Configure user and group permissions for seamless bind mount compatibility across different host systems, particularly NAS environments.
|
||||||
|
|
||||||
This is particularly common on **NAS systems** like Synology or QNAP, where the container's default UID/GID doesn't match your host system. Instead of manually changing directory ownership on your host, Palmr. now supports <span className="font-bold italic">flexible UID/GID configuration</span> to automatically handle these permission conflicts.
|
## Overview
|
||||||
|
|
||||||
## The Problem
|
Palmr. supports runtime UID/GID configuration to resolve permission conflicts when using bind mounts. This eliminates the need for manual permission management on your host system.
|
||||||
|
|
||||||
By default, Palmr. runs with UID 1001 and GID 1001 inside the container. When you bind-mount a directory from your host system (like `./data:/app/server`), permission conflicts can occur if:
|
**Default Configuration**: UID 1001, GID 1001
|
||||||
|
|
||||||
- Your host user has a different UID/GID
|
## When to Configure
|
||||||
- You're running on a NAS system with specific user configurations
|
|
||||||
- The mounted directory ownership doesn't match the container user
|
|
||||||
|
|
||||||
This results in errors like:
|
UID/GID configuration is recommended when:
|
||||||
|
|
||||||
- **Access denied** even with 777 permissions
|
- Using bind mounts with different host user permissions
|
||||||
- **Database connection failures** (SQLite can't create/access files)
|
- Deploying on NAS systems (Synology, QNAP, etc.)
|
||||||
- **File upload failures** in the application
|
- Encountering "permission denied" errors
|
||||||
|
- Host system uses different default UID/GID values
|
||||||
## The Solution
|
|
||||||
|
|
||||||
Palmr. now supports **runtime UID/GID configuration** through environment variables. The container will automatically adjust its internal user permissions to match your host system, eliminating the need to manually change directory ownership.
|
|
||||||
|
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
|
|
||||||
Configure these **optional** environment variables in your `docker-compose.yml`:
|
Configure permissions using these optional environment variables:
|
||||||
|
|
||||||
| Variable | Description | Default | When to Use |
|
| Variable | Description | Default | Example |
|
||||||
| ----------- | ---------------------------------- | ------- | ------------------------------------------- |
|
| ----------- | -------------------------------- | ------- | ------- |
|
||||||
| `PALMR_UID` | User ID for the container process | 1001 | When host directory owner has different UID |
|
| `PALMR_UID` | User ID for container processes | `1001` | `1000` |
|
||||||
| `PALMR_GID` | Group ID for the container process | 1001 | When host directory group has different GID |
|
| `PALMR_GID` | Group ID for container processes | `1001` | `1000` |
|
||||||
|
|
||||||
> **Important**: These variables are **completely optional**. If you don't set them, Palmr. works exactly as before with UID/GID 1001.
|
---
|
||||||
|
|
||||||
## Finding Your Host UID/GID
|
## Finding Host UID/GID
|
||||||
|
|
||||||
Before configuring, you need to find your host system's user and group IDs:
|
Determine your host system's user and group IDs:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Find your user ID
|
# Check current user
|
||||||
id -u
|
|
||||||
|
|
||||||
# Find your group ID
|
|
||||||
id -g
|
|
||||||
|
|
||||||
# See both together
|
|
||||||
id
|
id
|
||||||
|
|
||||||
|
# Output example
|
||||||
|
uid=1000(user) gid=1000(group) groups=1000(group),27(sudo)
|
||||||
```
|
```
|
||||||
|
|
||||||
Example output:
|
Use the `uid` and `gid` values for your configuration.
|
||||||
|
|
||||||
```bash
|
---
|
||||||
$ id
|
|
||||||
uid=1000(myuser) gid=1000(mygroup) groups=1000(mygroup),27(sudo)
|
|
||||||
```
|
|
||||||
|
|
||||||
In this example, you would use `PALMR_UID=1000` and `PALMR_GID=1000`.
|
|
||||||
|
|
||||||
## Configuration Examples
|
## Configuration Examples
|
||||||
|
|
||||||
### Basic Linux System
|
### Standard Linux System
|
||||||
|
|
||||||
Most Linux desktop systems use UID/GID 1000 for the first user:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
palmr:
|
palmr:
|
||||||
image: docker.io/kyantech/palmr:latest
|
image: kyantech/palmr:latest
|
||||||
container_name: palmr
|
container_name: palmr
|
||||||
environment:
|
environment:
|
||||||
- ENABLE_S3=false
|
- ENABLE_S3=false
|
||||||
- ENCRYPTION_KEY=change-this-key-in-production-min-32-chars
|
- ENCRYPTION_KEY=your-secure-key-min-32-chars
|
||||||
# Add these lines to match your host user
|
|
||||||
- PALMR_UID=1000
|
- PALMR_UID=1000
|
||||||
- PALMR_GID=1000
|
- PALMR_GID=1000
|
||||||
ports:
|
ports:
|
||||||
@@ -86,158 +70,135 @@ services:
|
|||||||
|
|
||||||
### Synology NAS
|
### Synology NAS
|
||||||
|
|
||||||
Synology systems commonly use these UID/GID combinations:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
palmr:
|
palmr:
|
||||||
image: docker.io/kyantech/palmr:latest
|
image: kyantech/palmr:latest
|
||||||
container_name: palmr
|
container_name: palmr
|
||||||
environment:
|
environment:
|
||||||
- ENABLE_S3=false
|
- ENABLE_S3=false
|
||||||
- ENCRYPTION_KEY=change-this-key-in-production-min-32-chars
|
- ENCRYPTION_KEY=your-secure-key-min-32-chars
|
||||||
# Common Synology configuration
|
|
||||||
- PALMR_UID=1026
|
- PALMR_UID=1026
|
||||||
- PALMR_GID=100
|
- PALMR_GID=100
|
||||||
ports:
|
ports:
|
||||||
- "5487:5487"
|
- "5487:5487"
|
||||||
volumes:
|
volumes:
|
||||||
- /volume1/docker/palmr/data:/app/server
|
- /volume1/docker/palmr:/app/server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
```
|
```
|
||||||
|
|
||||||
### QNAP NAS
|
### QNAP NAS
|
||||||
|
|
||||||
QNAP systems typically use:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
services:
|
services:
|
||||||
palmr:
|
palmr:
|
||||||
image: docker.io/kyantech/palmr:latest
|
image: kyantech/palmr:latest
|
||||||
container_name: palmr
|
container_name: palmr
|
||||||
environment:
|
environment:
|
||||||
- ENABLE_S3=false
|
- ENABLE_S3=false
|
||||||
- ENCRYPTION_KEY=change-this-key-in-production-min-32-chars
|
- ENCRYPTION_KEY=your-secure-key-min-32-chars
|
||||||
# Common QNAP configuration
|
|
||||||
- PALMR_UID=1000
|
- PALMR_UID=1000
|
||||||
- PALMR_GID=100
|
- PALMR_GID=100
|
||||||
ports:
|
ports:
|
||||||
- "5487:5487"
|
- "5487:5487"
|
||||||
volumes:
|
volumes:
|
||||||
- /share/Container/palmr/data:/app/server
|
- /share/Container/palmr:/app/server
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
```
|
```
|
||||||
|
|
||||||
### No Configuration Needed
|
---
|
||||||
|
|
||||||
If you're not experiencing permission issues, you don't need to set these variables:
|
## Migration Guide
|
||||||
|
|
||||||
```yaml
|
### Existing Installations
|
||||||
services:
|
|
||||||
palmr:
|
|
||||||
image: docker.io/kyantech/palmr:latest
|
|
||||||
container_name: palmr
|
|
||||||
environment:
|
|
||||||
- ENABLE_S3=false
|
|
||||||
- ENCRYPTION_KEY=change-this-key-in-production-min-32-chars
|
|
||||||
# No PALMR_UID/PALMR_GID needed - uses defaults
|
|
||||||
ports:
|
|
||||||
- "5487:5487"
|
|
||||||
volumes:
|
|
||||||
- ./data:/app/server
|
|
||||||
restart: unless-stopped
|
|
||||||
```
|
|
||||||
|
|
||||||
## Migration for Existing Installations
|
To add UID/GID configuration to running installations:
|
||||||
|
|
||||||
If you already have Palmr. running and want to add UID/GID configuration:
|
1. **Stop the container**
|
||||||
|
|
||||||
### Step 1: Backup Your Data
|
```bash
|
||||||
|
docker-compose down
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Backup your data**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cp -r ./data ./data-backup
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Update configuration**
|
||||||
|
Add UID/GID variables to your `docker-compose.yaml`
|
||||||
|
|
||||||
|
4. **Restart with new configuration**
|
||||||
|
```bash
|
||||||
|
docker-compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
### Check Configuration
|
||||||
|
|
||||||
|
Verify UID/GID settings are applied correctly:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker-compose down
|
# View startup logs
|
||||||
cp -r ./data ./data-backup
|
docker-compose logs palmr | head -20
|
||||||
```
|
|
||||||
|
|
||||||
### Step 2: Update docker-compose.yml
|
# Check file ownership
|
||||||
|
|
||||||
Add the UID/GID environment variables to your existing configuration:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
services:
|
|
||||||
palmr:
|
|
||||||
image: docker.io/kyantech/palmr:latest
|
|
||||||
container_name: palmr
|
|
||||||
environment:
|
|
||||||
- ENABLE_S3=false
|
|
||||||
- ENCRYPTION_KEY=your-existing-key
|
|
||||||
# Add these new lines
|
|
||||||
- PALMR_UID=1000 # Your host user UID
|
|
||||||
- PALMR_GID=1000 # Your host group GID
|
|
||||||
# ... rest of your configuration
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 3: Restart Palmr.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker-compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
The container will automatically detect the new UID/GID configuration and adjust permissions accordingly.
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### Checking Current Configuration
|
|
||||||
|
|
||||||
To verify your container is running with the correct UID/GID:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Check the user ID inside the container
|
|
||||||
docker exec palmr id
|
|
||||||
|
|
||||||
# Check file ownership in the mounted volume
|
|
||||||
docker exec palmr ls -la /app/server/
|
docker exec palmr ls -la /app/server/
|
||||||
|
|
||||||
|
# Verify process UID/GID
|
||||||
|
docker exec palmr ps aux | grep node
|
||||||
```
|
```
|
||||||
|
|
||||||
### Permission Issues Persist
|
### Troubleshooting
|
||||||
|
|
||||||
If you're still having permission issues after configuration:
|
**Permission issues persist:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check container logs for UID/GID adjustment messages
|
# Check environment variables
|
||||||
docker-compose logs palmr | grep -i "uid\|gid"
|
docker exec palmr env | grep PALMR
|
||||||
|
|
||||||
# Manually fix permissions if needed
|
# Verify file ownership
|
||||||
docker exec -u root palmr chown -R palmr:nodejs /app/server
|
docker exec palmr stat /app/server/prisma/palmr.db
|
||||||
|
|
||||||
|
# Review configuration logs
|
||||||
|
docker-compose logs palmr | grep -E "🔧|🔐|🔽"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Finding NAS-Specific UID/GID
|
**NAS-specific debugging:**
|
||||||
|
|
||||||
For NAS systems, check your system's user management interface or use SSH:
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# On your NAS, check existing users
|
# Synology - Check mount point ownership
|
||||||
|
ls -la /volume1/docker/palmr/
|
||||||
|
|
||||||
|
# QNAP - Check mount point ownership
|
||||||
|
ls -la /share/Container/palmr/
|
||||||
|
|
||||||
|
# Check NAS user configuration
|
||||||
cat /etc/passwd | grep -v nobody
|
cat /etc/passwd | grep -v nobody
|
||||||
|
|
||||||
# Check groups
|
|
||||||
cat /etc/group
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## How It Works
|
---
|
||||||
|
|
||||||
When you set `PALMR_UID` and/or `PALMR_GID` environment variables:
|
## Implementation Details
|
||||||
|
|
||||||
1. **Container startup**: The container detects the environment variables
|
The UID/GID configuration process:
|
||||||
2. **User adjustment**: Automatically modifies the internal `palmr` user to use your specified UID/GID
|
|
||||||
3. **Ownership update**: Updates file ownership of application directories
|
|
||||||
4. **Conflict handling**: Gracefully handles cases where the UID/GID already exists
|
|
||||||
5. **Logging**: Provides clear feedback about what changes were made
|
|
||||||
|
|
||||||
The process is completely automatic and requires no manual intervention.
|
1. **Detection** - Environment variables are read during container startup
|
||||||
|
2. **Ownership Update** - File permissions are adjusted to match target UID/GID
|
||||||
|
3. **Privilege Drop** - Application runs with specified user permissions via `su-exec`
|
||||||
|
4. **Logging** - Configuration changes are logged for verification
|
||||||
|
|
||||||
## Build-Time Customization
|
This approach provides automatic permission management without user creation or system modification.
|
||||||
|
|
||||||
For advanced users who want to build custom images with different default UID/GID:
|
---
|
||||||
|
|
||||||
|
## Build-Time Configuration
|
||||||
|
|
||||||
|
For custom base images with different default values:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker build \
|
docker build \
|
||||||
@@ -246,18 +207,16 @@ docker build \
|
|||||||
-t palmr:custom .
|
-t palmr:custom .
|
||||||
```
|
```
|
||||||
|
|
||||||
This sets new defaults at build time, which can still be overridden with environment variables at runtime.
|
Runtime environment variables override build-time defaults.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Summary
|
## Benefits
|
||||||
|
|
||||||
The UID/GID configuration feature makes Palmr. **universally compatible** with different host systems without requiring manual permission changes. Key benefits:
|
- **Zero Configuration** - Works automatically when environment variables are set
|
||||||
|
- **Universal Compatibility** - Supports any valid UID/GID combination
|
||||||
|
- **NAS Optimized** - Tested with major NAS platforms
|
||||||
|
- **Backward Compatible** - Existing deployments continue without modification
|
||||||
|
- **Performance Optimized** - Lightweight implementation using `su-exec`
|
||||||
|
|
||||||
- ✅ **Automatic permission handling** - No manual `chown` commands needed
|
For permission issues with bind mounts, add the appropriate `PALMR_UID` and `PALMR_GID` environment variables to resolve conflicts automatically.
|
||||||
- ✅ **NAS system compatibility** - Tested with Synology and QNAP
|
|
||||||
- ✅ **Backward compatible** - Existing installations continue to work unchanged
|
|
||||||
- ✅ **Optional configuration** - Only use when needed
|
|
||||||
- ✅ **Runtime flexibility** - Change UID/GID without rebuilding images
|
|
||||||
|
|
||||||
If you're experiencing permission issues with bind-mounted directories, try adding the appropriate `PALMR_UID` and `PALMR_GID` environment variables to your configuration. The container will handle the rest automatically!
|
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
# FOR FILESYSTEM STORAGE ENV VARS
|
# FOR FILESYSTEM STORAGE ENV VARS
|
||||||
ENABLE_S3=false
|
ENABLE_S3=false
|
||||||
ENCRYPTION_KEY=change-this-key-in-production-min-32-chars
|
ENCRYPTION_KEY=change-this-key-in-production-min-32-chars
|
||||||
|
DATABASE_URL="file:./palmr.db"
|
||||||
|
|
||||||
# FOR USE WITH S3 COMPATIBLE STORAGE
|
# FOR USE WITH S3 COMPATIBLE STORAGE
|
||||||
# ENABLE_S3=true
|
# ENABLE_S3=true
|
||||||
|
@@ -4,7 +4,7 @@ generator client {
|
|||||||
|
|
||||||
datasource db {
|
datasource db {
|
||||||
provider = "sqlite"
|
provider = "sqlite"
|
||||||
url = "file:./palmr.db"
|
url = env("DATABASE_URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
model User {
|
model User {
|
||||||
|
@@ -11,6 +11,7 @@ const envSchema = z.object({
|
|||||||
S3_REGION: z.string().optional(),
|
S3_REGION: z.string().optional(),
|
||||||
S3_BUCKET_NAME: z.string().optional(),
|
S3_BUCKET_NAME: z.string().optional(),
|
||||||
S3_FORCE_PATH_STYLE: z.union([z.literal("true"), z.literal("false")]).default("false"),
|
S3_FORCE_PATH_STYLE: z.union([z.literal("true"), z.literal("false")]).default("false"),
|
||||||
|
DATABASE_URL: z.string().optional().default("file:/app/server/prisma/palmr.db"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const env = envSchema.parse(process.env);
|
export const env = envSchema.parse(process.env);
|
||||||
|
17
docker-compose-bind-mount-example.yaml
Normal file
17
docker-compose-bind-mount-example.yaml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
services:
|
||||||
|
palmr:
|
||||||
|
image: kyantech/palmr:latest
|
||||||
|
container_name: palmr
|
||||||
|
environment:
|
||||||
|
- ENABLE_S3=false
|
||||||
|
- ENCRYPTION_KEY=change-this-key-in-production-min-32-chars # CHANGE THIS KEY FOR SECURITY
|
||||||
|
# Optional: Set custom UID/GID for file permissions
|
||||||
|
# - PALMR_UID=1000
|
||||||
|
# - PALMR_GID=1000
|
||||||
|
ports:
|
||||||
|
- "5487:5487" # Web port
|
||||||
|
- "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY)
|
||||||
|
volumes:
|
||||||
|
# Bind mount for persistent data (uploads, database, temp files)
|
||||||
|
- ./data:/app/server # Volume for the application data
|
||||||
|
restart: unless-stopped # Restart the container unless it is stopped
|
@@ -9,7 +9,7 @@ services:
|
|||||||
- "5487:5487" # Web port
|
- "5487:5487" # Web port
|
||||||
- "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY)
|
- "3333:3333" # API port (OPTIONAL EXPOSED - ONLY IF YOU WANT TO ACCESS THE API DIRECTLY)
|
||||||
volumes:
|
volumes:
|
||||||
- palmr_data:/app/server # Volume for the application data
|
- palmr_data:/app/server # Volume for the application data (changed from /data to /app/server)
|
||||||
restart: unless-stopped # Restart the container unless it is stopped
|
restart: unless-stopped # Restart the container unless it is stopped
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
|
@@ -1,22 +1,93 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
echo "Starting Palmr Server with SQLite..."
|
echo "🌴 Starting Palmr Server..."
|
||||||
|
|
||||||
# Set proper environment
|
# === UID/GID Runtime Configuration ===
|
||||||
export HOME=/home/palmr
|
TARGET_UID=${PALMR_UID:-1001}
|
||||||
export NPM_CONFIG_CACHE=/home/palmr/.npm
|
TARGET_GID=${PALMR_GID:-1001}
|
||||||
export PNPM_HOME=/home/palmr/.pnpm
|
|
||||||
|
|
||||||
cd /app/server
|
if [ -n "$PALMR_UID" ] || [ -n "$PALMR_GID" ]; then
|
||||||
|
echo "🔧 Runtime UID/GID: $TARGET_UID:$TARGET_GID"
|
||||||
|
|
||||||
|
# Update ownership of critical directories to match target UID/GID
|
||||||
|
echo "🔐 Updating file ownership..."
|
||||||
|
chown -R $TARGET_UID:$TARGET_GID /app/palmr-app 2>/dev/null || echo "⚠️ Some ownership changes may have failed"
|
||||||
|
chown -R $TARGET_UID:$TARGET_GID /home/palmr 2>/dev/null || echo "⚠️ Some home directory ownership changes may have failed"
|
||||||
|
|
||||||
|
# Update ownership of data directory if it exists
|
||||||
|
if [ -d "/app/server" ]; then
|
||||||
|
chown -R $TARGET_UID:$TARGET_GID /app/server 2>/dev/null || echo "⚠️ Some data directory ownership changes may have failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ UID/GID configuration completed"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Generating Prisma client..."
|
# Ensure we're in the correct directory
|
||||||
npx prisma generate --schema=./prisma/schema.prisma
|
cd /app/palmr-app
|
||||||
|
|
||||||
echo "Pushing database schema..."
|
# Set the database URL
|
||||||
npx prisma db push --accept-data-loss
|
export DATABASE_URL="file:/app/server/prisma/palmr.db"
|
||||||
|
|
||||||
echo "Running database seeds..."
|
echo "📂 Data directory: /app/server"
|
||||||
node prisma/seed.js || echo "Seeds failed or already exist, continuing..."
|
echo "💾 Database: $DATABASE_URL"
|
||||||
|
|
||||||
echo "Starting server application..."
|
# Create all necessary directories
|
||||||
exec node dist/server.js
|
echo "📁 Creating data directories..."
|
||||||
|
mkdir -p /app/server/prisma /app/server/uploads /app/server/temp-chunks /app/server/uploads/logo
|
||||||
|
|
||||||
|
# Check if it's a first run (no database file exists)
|
||||||
|
if [ ! -f "/app/server/prisma/palmr.db" ]; then
|
||||||
|
echo "🚀 First run detected - setting up database..."
|
||||||
|
|
||||||
|
# Create database with proper schema path
|
||||||
|
echo "🗄️ Creating database schema..."
|
||||||
|
npx prisma db push --schema=./prisma/schema.prisma --skip-generate
|
||||||
|
|
||||||
|
# Run seed script from application directory (where node_modules is)
|
||||||
|
echo "🌱 Seeding database..."
|
||||||
|
node ./prisma/seed.js
|
||||||
|
|
||||||
|
echo "✅ Database setup completed!"
|
||||||
|
else
|
||||||
|
echo "♻️ Existing database found"
|
||||||
|
|
||||||
|
# Always run migrations to ensure schema is up to date
|
||||||
|
echo "🔧 Checking for schema updates..."
|
||||||
|
npx prisma db push --schema=./prisma/schema.prisma --skip-generate
|
||||||
|
|
||||||
|
# Check if configurations exist
|
||||||
|
echo "🔍 Verifying database configurations..."
|
||||||
|
CONFIG_COUNT=$(node -e "
|
||||||
|
const { PrismaClient } = require('@prisma/client');
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
prisma.appConfig.count()
|
||||||
|
.then(count => {
|
||||||
|
console.log(count);
|
||||||
|
process.exit(0);
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
console.log(0);
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
" 2>/dev/null || echo "0")
|
||||||
|
|
||||||
|
if [ "$CONFIG_COUNT" -eq "0" ]; then
|
||||||
|
echo "🌱 No configurations found, running seed..."
|
||||||
|
# Always run seed from application directory where node_modules is available
|
||||||
|
node ./prisma/seed.js
|
||||||
|
else
|
||||||
|
echo "✅ Found $CONFIG_COUNT configurations"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🚀 Starting Palmr server..."
|
||||||
|
|
||||||
|
# Drop privileges using su-exec with specific UID/GID
|
||||||
|
if [ "$(id -u)" = "0" ]; then
|
||||||
|
echo "🔽 Dropping privileges to UID:GID $TARGET_UID:$TARGET_GID"
|
||||||
|
exec su-exec $TARGET_UID:$TARGET_GID node dist/server.js
|
||||||
|
else
|
||||||
|
# We're already running as non-root
|
||||||
|
exec node dist/server.js
|
||||||
|
fi
|
Reference in New Issue
Block a user