JournivJourniv
Installation

Manual Installation

Manual installation guide for advanced users who want to run Journiv without Docker.

Manual installation is recommended for development, custom configurations, or when you need more control over the environment. This guide covers installing Journiv directly with Python.

Prerequisites

  • Python 3.9 or higher
  • PostgreSQL 12+ (optional, SQLite is default)
  • pip (Python package manager)
  • Node.js 24 and npm (to build the web frontend, required since beta.25)
  • Git (to clone the repository)
  • Redis or Valkey and a Celery worker for media uploads and import/export

Installation Steps

1. Clone the Repository

git clone https://github.com/journiv/journiv-app.git
cd journiv-app

2. Create Virtual Environment

# Create virtual environment
python -m venv venv

# Activate virtual environment
# On Linux/macOS:
source venv/bin/activate

# On Windows:
venv\Scripts\activate

3. Install Dependencies

# Install production dependencies
pip install -r requirements/prod.txt

# Or install development dependencies (includes dev tools)
pip install -r requirements/dev.txt

4. Configure Environment

Create a .env file in the journiv-app directory:

# Required
SECRET_KEY=your-secret-key-here
DOMAIN_NAME=localhost

# Database (optional - defaults to SQLite)
DATABASE_URL=sqlite:///./journiv.db
# Or for PostgreSQL:
# DATABASE_URL=postgresql://user:password@localhost:5432/journiv

# Application settings
LOG_LEVEL=INFO
ENVIRONMENT=development
DEBUG=true

# Storage
MEDIA_ROOT=./data/media
LOG_DIR=./data/logs
MAX_FILE_SIZE_MB=50

# Media processing and import/export
REDIS_URL=redis://localhost:6379/0
CELERY_BROKER_URL=redis://localhost:6379/0
CELERY_RESULT_BACKEND=redis://localhost:6379/0

Generate a secure SECRET_KEY:

python -c "import secrets; print(secrets.token_urlsafe(32))"

5. Build the Web Frontend

Since beta.25, Journiv ships a new React frontend that is not included in the repository as a prebuilt bundle. Docker images build it automatically; for manual installs you must build it once, and again after each upgrade:

cd journiv-app/frontend
npm ci
npm run build

The build output is written to journiv-app/frontend/dist, which is where Journiv looks by default. To serve it from another location, set REACT_WEB_BUILD_PATH to a directory containing index.html.

6. Initialize Database

# Run database migrations
alembic upgrade head

This creates the database schema and initializes all tables.

7. Run the Application

Development mode (with hot reload):

uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

Production mode:

uvicorn app.main:app --host 0.0.0.0 --port 8000

Access Journiv at http://localhost:8000.

Start the background worker

Start Redis/Valkey, then run a Celery worker in a separate process from the same checkout and virtual environment:

celery -A app.core.celery_app worker --loglevel=info

The API and worker need the same .env, database, and media directory. If the worker is not running, uploaded files can be saved to disk while their status stays pending; they will not appear in entries. Keep the worker running alongside the API in production.

Production Deployment

For production, use Gunicorn with Uvicorn workers:

# Install Gunicorn
pip install gunicorn

# Run with Gunicorn
gunicorn app.main:app \
  -w 4 \
  -k uvicorn.workers.UvicornWorker \
  --bind 0.0.0.0:8000 \
  --access-logfile - \
  --error-logfile -

Gunicorn Options:

  • -w 4: Number of worker processes (adjust based on CPU cores)
  • -k uvicorn.workers.UvicornWorker: Use Uvicorn workers for async support
  • --bind 0.0.0.0:8000: Bind to all interfaces on port 8000
  • --access-logfile -: Log access to stdout
  • --error-logfile -: Log errors to stdout

Systemd Service (Linux)

Create a systemd service file for automatic startup:

# /etc/systemd/system/journiv.service
[Unit]
Description=Journiv Journaling Application
After=network.target postgresql.service

[Service]
Type=notify
User=journiv
Group=journiv
WorkingDirectory=/opt/journiv/journv-app
Environment="PATH=/opt/journiv/venv/bin"
ExecStart=/opt/journiv/venv/bin/gunicorn app.main:app \
  -w 4 \
  -k uvicorn.workers.UvicornWorker \
  --bind 127.0.0.1:8000 \
  --access-logfile - \
  --error-logfile -
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl enable journiv
sudo systemctl start journiv
sudo systemctl status journiv

Reverse Proxy Setup

Use nginx or another reverse proxy for HTTPS:

nginx configuration:

server {
    listen 80;
    server_name journiv.example.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Development Setup

For development with hot reload and debugging:

# Install development dependencies
pip install -r requirements/dev.txt

# Run with auto-reload
uvicorn app.main:app --reload --host 0.0.0.0 --port 8000

# Run tests
pytest

# Run tests with coverage
pytest --cov=app --cov-report=html

Database Migrations

Create a new migration:

alembic revision --autogenerate -m "description of changes"

Apply migrations:

alembic upgrade head

Rollback migration:

alembic downgrade -1

Troubleshooting

{"error":"not_found","message":"Frontend not found"}

The React frontend has not been built (or REACT_WEB_BUILD_PATH points to a directory without index.html). This is common after upgrading a manual install from a version before beta.25. The legacy app at /legacy keeps working because it is still bundled. Journiv also logs a warning at startup naming the missing path.

Build the frontend (see step 5) and restart Journiv:

cd journiv-app/frontend && npm ci && npm run build

Database Migration Issues

If migrations fail:

# Check current migration status
alembic current

# Rollback one migration
alembic downgrade -1

# Apply migrations again
alembic upgrade head

Port Already in Use

Change the port:

uvicorn app.main:app --host 0.0.0.0 --port 8080

Permission Errors

Ensure directories are writable:

chmod -R 755 ./data

Import Errors

Ensure all dependencies are installed:

pip install -r requirements/prod.txt

PostgreSQL Connection Issues

Verify:

  • PostgreSQL is running: sudo systemctl status postgresql
  • DATABASE_URL is correct
  • Database and user exist
  • Firewall allows connections

Advantages of Manual Installation

  • Full Control: Complete control over Python version and dependencies
  • Development: Easier debugging and development workflow
  • Customization: Easy to modify code and configuration
  • Integration: Better integration with existing Python environments

Disadvantages

  • Complexity: More setup steps than Docker
  • Maintenance: Need to manage Python dependencies and updates manually
  • Platform Differences: May behave differently across platforms

For most users, Docker installation is recommended. Use manual installation only if you need the additional control or are developing Journiv itself.