Some checks failed
CI/CD Pipeline / Test Suite (push) Has been cancelled
CI/CD Pipeline / Security Audit (push) Has been cancelled
CI/CD Pipeline / Build Docker Image (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
CI/CD Pipeline / Performance Benchmarks (push) Has been cancelled
CI/CD Pipeline / Cleanup (push) Has been cancelled
365 lines
8.3 KiB
Markdown
365 lines
8.3 KiB
Markdown
# ROOT_PATH Configuration Guide
|
|
|
|
This document explains how to use the `ROOT_PATH` configuration feature to manage absolute and relative paths in your Rust application.
|
|
|
|
## Overview
|
|
|
|
The `ROOT_PATH` configuration allows you to:
|
|
- Convert all relative paths in configuration files to absolute paths
|
|
- Set a base directory for your application
|
|
- Deploy your application anywhere without hardcoding paths
|
|
- Maintain consistent path resolution across different environments
|
|
|
|
## Configuration
|
|
|
|
### Setting ROOT_PATH
|
|
|
|
There are several ways to set the `ROOT_PATH`:
|
|
|
|
#### 1. Environment Variable (Recommended)
|
|
```bash
|
|
export ROOT_PATH=/path/to/your/application
|
|
```
|
|
|
|
#### 2. Configuration File
|
|
```toml
|
|
# config.toml
|
|
root_path = "/path/to/your/application"
|
|
```
|
|
|
|
#### 3. Default Behavior
|
|
If not set, `ROOT_PATH` defaults to the current working directory.
|
|
|
|
### Environment Variable Priority
|
|
|
|
The `ROOT_PATH` can be overridden using the `ROOT_PATH` environment variable:
|
|
|
|
```bash
|
|
# Override config file setting
|
|
ROOT_PATH=/custom/path ./target/release/server
|
|
```
|
|
|
|
## Path Resolution
|
|
|
|
### How It Works
|
|
|
|
1. **Absolute Paths**: Left unchanged
|
|
- Input: `/absolute/path/to/file`
|
|
- Output: `/absolute/path/to/file`
|
|
|
|
2. **Relative Paths**: Resolved against `ROOT_PATH`
|
|
- ROOT_PATH: `/app`
|
|
- Input: `public/assets`
|
|
- Output: `/app/public/assets`
|
|
|
|
3. **Current Directory References**: Resolved properly
|
|
- ROOT_PATH: `/app`
|
|
- Input: `./config`
|
|
- Output: `/app/config`
|
|
|
|
4. **Parent Directory References**: Resolved properly
|
|
- ROOT_PATH: `/app/server`
|
|
- Input: `../shared`
|
|
- Output: `/app/shared`
|
|
|
|
### Affected Configuration Sections
|
|
|
|
The following configuration sections have their paths resolved:
|
|
|
|
#### Static Files
|
|
```toml
|
|
[static]
|
|
assets_dir = "public" # -> /app/public
|
|
site_root = "target/site" # -> /app/target/site
|
|
site_pkg_dir = "pkg" # -> /app/pkg
|
|
```
|
|
|
|
#### Server Directories
|
|
```toml
|
|
[server_dirs]
|
|
public_dir = "public" # -> /app/public
|
|
uploads_dir = "uploads" # -> /app/uploads
|
|
logs_dir = "logs" # -> /app/logs
|
|
temp_dir = "tmp" # -> /app/tmp
|
|
cache_dir = "cache" # -> /app/cache
|
|
config_dir = "config" # -> /app/config
|
|
data_dir = "data" # -> /app/data
|
|
backup_dir = "backups" # -> /app/backups
|
|
```
|
|
|
|
#### TLS Configuration
|
|
```toml
|
|
[server.tls]
|
|
cert_path = "certs/server.crt" # -> /app/certs/server.crt
|
|
key_path = "certs/server.key" # -> /app/certs/server.key
|
|
```
|
|
|
|
#### Logging
|
|
```toml
|
|
[logging]
|
|
file_path = "logs/app.log" # -> /app/logs/app.log
|
|
```
|
|
|
|
#### Content Directory (if enabled)
|
|
```toml
|
|
[content]
|
|
content_dir = "content" # -> /app/content
|
|
```
|
|
|
|
## Usage Examples
|
|
|
|
### Development Environment
|
|
|
|
```bash
|
|
# Set ROOT_PATH to your project directory
|
|
export ROOT_PATH=/home/user/my-rust-app
|
|
cd /home/user/my-rust-app
|
|
cargo run
|
|
```
|
|
|
|
### Production Deployment
|
|
|
|
```bash
|
|
# Docker example
|
|
FROM rust:latest
|
|
WORKDIR /app
|
|
COPY . .
|
|
ENV ROOT_PATH=/app
|
|
ENV ENVIRONMENT=production
|
|
RUN cargo build --release
|
|
EXPOSE 3030
|
|
CMD ["./target/release/server"]
|
|
```
|
|
|
|
### Systemd Service
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=My Rust Application
|
|
After=network.target
|
|
|
|
[Service]
|
|
Type=simple
|
|
User=myapp
|
|
WorkingDirectory=/opt/myapp
|
|
Environment=ROOT_PATH=/opt/myapp
|
|
Environment=ENVIRONMENT=production
|
|
ExecStart=/opt/myapp/target/release/server
|
|
Restart=always
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
## Directory Structure
|
|
|
|
### Recommended Layout
|
|
|
|
```
|
|
ROOT_PATH/
|
|
├── config.toml
|
|
├── config.dev.toml
|
|
├── config.prod.toml
|
|
├── target/
|
|
│ └── release/
|
|
│ └── server
|
|
├── public/ # Static assets
|
|
├── content/ # Content files
|
|
├── uploads/ # User uploads
|
|
├── logs/ # Application logs
|
|
├── cache/ # Temporary cache
|
|
├── data/ # Application data
|
|
├── backups/ # Backup files
|
|
└── certs/ # TLS certificates
|
|
├── server.crt
|
|
└── server.key
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### Config Methods
|
|
|
|
#### `get_absolute_path(relative_path: &str) -> Result<String, ConfigError>`
|
|
|
|
Converts a relative path to an absolute path using the configured `ROOT_PATH`.
|
|
|
|
```rust
|
|
use server::config::Config;
|
|
|
|
let config = Config::load()?;
|
|
let absolute_path = config.get_absolute_path("uploads/images")?;
|
|
println!("Absolute path: {}", absolute_path);
|
|
// Output: /app/uploads/images
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Description | Default |
|
|
|----------|-------------|---------|
|
|
| `ROOT_PATH` | Base directory for path resolution | Current directory |
|
|
| `CONFIG_FILE` | Explicit path to config file | Auto-discovered |
|
|
| `ENVIRONMENT` | Runtime environment | `development` |
|
|
|
|
## Migration Guide
|
|
|
|
### Converting Hardcoded Paths
|
|
|
|
#### Before (Hardcoded)
|
|
```rust
|
|
// Don't do this
|
|
let config_path = "../../../config.toml";
|
|
let content_path = "../../content/menu.toml";
|
|
```
|
|
|
|
#### After (ROOT_PATH)
|
|
```rust
|
|
// Do this instead
|
|
let config = Config::load()?;
|
|
let uploads_path = config.get_absolute_path("uploads")?;
|
|
let content_path = config.get_absolute_path("content/menu.toml")?;
|
|
```
|
|
|
|
### Content Loading
|
|
|
|
#### Before
|
|
```rust
|
|
// Hardcoded relative path
|
|
let content = include_str!("../../content/menu.toml");
|
|
```
|
|
|
|
#### After
|
|
```rust
|
|
// Dynamic path resolution
|
|
use shared::get_content_path;
|
|
|
|
let menu_path = get_content_path("menu.toml")?;
|
|
let content = std::fs::read_to_string(menu_path)?;
|
|
```
|
|
|
|
## Best Practices
|
|
|
|
### 1. Use Environment Variables in Production
|
|
```bash
|
|
# Production
|
|
export ROOT_PATH=/opt/myapp
|
|
export ENVIRONMENT=production
|
|
export DATABASE_URL=postgresql://...
|
|
```
|
|
|
|
### 2. Keep Config Files Portable
|
|
```toml
|
|
# Use relative paths in config files
|
|
[server_dirs]
|
|
public_dir = "public" # Good
|
|
# public_dir = "/var/www" # Avoid hardcoded absolute paths
|
|
```
|
|
|
|
### 3. Document Your Directory Structure
|
|
```toml
|
|
# config.toml
|
|
# Directory structure:
|
|
# ROOT_PATH/
|
|
# ├── public/ -> static assets
|
|
# ├── uploads/ -> user uploads
|
|
# ├── logs/ -> application logs
|
|
# └── data/ -> application data
|
|
|
|
[server_dirs]
|
|
public_dir = "public"
|
|
uploads_dir = "uploads"
|
|
logs_dir = "logs"
|
|
data_dir = "data"
|
|
```
|
|
|
|
### 4. Use Consistent Naming
|
|
```toml
|
|
# Consistent directory naming
|
|
[server_dirs]
|
|
public_dir = "public" # Not "static" or "assets"
|
|
uploads_dir = "uploads" # Not "files" or "media"
|
|
logs_dir = "logs" # Not "log" or "logging"
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
#### 1. Path Not Found
|
|
```
|
|
Error: Root path '/invalid/path' does not exist
|
|
```
|
|
**Solution**: Ensure the `ROOT_PATH` directory exists and is accessible.
|
|
|
|
#### 2. Permission Denied
|
|
```
|
|
Error: Directory creation error: Permission denied
|
|
```
|
|
**Solution**: Check file permissions and ensure the application has write access.
|
|
|
|
#### 3. Config File Not Found
|
|
```
|
|
Error: Configuration file 'config.toml' not found
|
|
```
|
|
**Solution**: Ensure the config file exists in the `ROOT_PATH` directory.
|
|
|
|
### Debug Commands
|
|
|
|
```bash
|
|
# Check current configuration
|
|
cargo run --bin config_tool -- show
|
|
|
|
# Validate configuration
|
|
cargo run --bin config_tool -- validate
|
|
|
|
# Generate new config
|
|
cargo run --bin config_tool -- generate dev
|
|
```
|
|
|
|
## Testing
|
|
|
|
### Unit Tests
|
|
|
|
```rust
|
|
#[test]
|
|
fn test_path_resolution() {
|
|
use std::env;
|
|
|
|
// Set test ROOT_PATH
|
|
env::set_var("ROOT_PATH", "/tmp/test");
|
|
|
|
let config = Config::load().unwrap();
|
|
let absolute_path = config.get_absolute_path("uploads").unwrap();
|
|
|
|
assert!(absolute_path.starts_with("/tmp/test"));
|
|
assert!(absolute_path.ends_with("uploads"));
|
|
}
|
|
```
|
|
|
|
### Integration Tests
|
|
|
|
```bash
|
|
# Test with different ROOT_PATH values
|
|
ROOT_PATH=/tmp/test1 cargo test
|
|
ROOT_PATH=/var/tmp/test2 cargo test
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
1. **Path Traversal**: The system prevents `../` attacks by resolving paths properly
|
|
2. **Permissions**: Ensure the `ROOT_PATH` directory has appropriate permissions
|
|
3. **Validation**: All paths are validated before use
|
|
4. **Sandboxing**: Consider using chroot or containers for additional security
|
|
|
|
## Performance
|
|
|
|
- Path resolution is performed once at startup
|
|
- Resolved paths are cached in the configuration
|
|
- No runtime overhead for path lookups
|
|
- Canonical path resolution may involve filesystem access
|
|
|
|
## Related Documentation
|
|
|
|
- [Configuration Guide](./CONFIGURATION.md)
|
|
- [Deployment Guide](./DEPLOYMENT.md)
|
|
- [Environment Variables](./ENVIRONMENT.md)
|
|
- [Directory Structure](./DIRECTORY_STRUCTURE.md) |