Skip to content

Conversation

zhravan
Copy link
Collaborator

@zhravan zhravan commented Sep 30, 2025

Description:

This PR introduces a comprehensive dockerized development environment with live reloading capabilities for the Nixopus project. The changes separate development and production deployment modes, enabling developers to run the entire stack locally with hot-reload functionality.

Summary by CodeRabbit

  • New Features

    • Added development install mode in the CLI with options for path, repo, branch, and dry-run.
    • Introduced a development Dockerfile and docker-compose setup for API, DB, Redis, Supertokens, and Caddy with health checks.
    • Development workflow includes live-reload, frontend dev server start, and service readiness checks.
  • Chores

    • Updated API version release timestamp to UTC.
    • Adjusted dev configuration: ports (3000), SSH host/key defaults, compose file path, and yarn requirement.
    • Removed nextjs-cors dependency from the frontend.

Copy link
Contributor

coderabbitai bot commented Sep 30, 2025

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Introduces a development workflow: adds an API dev Dockerfile and a dev docker-compose stack, extends the CLI installer with a development subcommand and control-flow paths, updates dev configuration defaults, removes a view dependency, and refreshes the API version timestamp.

Changes

Cohort / File(s) Summary
CLI install: development mode
cli/app/commands/install/command.py, cli/app/commands/install/run.py
Adds an install development subcommand and development flags/paths in Install. Adjusts run flow for dev: dependency checks, skips proxy, starts frontend, validates services, updates env vars, and alters success messaging. Inserts cleanup timing when --force.
Dev Docker and Compose
api/Dockerfile.dev, docker-compose-dev.yml
Adds a Go Alpine-based API dev Dockerfile with air, module caching, and live reload. Introduces a dev docker-compose with API, Redis, Postgres, Supertokens, Caddy, healthchecks, shared network, volumes, and dev-friendly env/ports.
Dev config defaults
helpers/config.dev.yaml
Switches compose file to docker-compose-dev.yml, updates ports (3000), SSH host/key defaults, adds yarn constraint, removes certain deps, and aligns values for dev.
API metadata
api/api/versions.json
Updates v1 release_date to a new UTC timestamp; structure unchanged.
View dependency cleanup
view/package.json
Removes dependency on nextjs-cors.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant CLI as nixopus CLI
  participant I as Install (development=True)
  participant DC as docker-compose (dev)
  participant API as API Service
  participant V as Frontend Dev Server
  participant DB as Postgres
  participant R as Redis
  participant ST as Supertokens
  participant C as Caddy

  U->>CLI: nixopus install development [options]
  CLI->>I: Construct Install(development=True, dev_install_path)
  I->>I: _get_config(dev) and log setup
  I->>I: _check_and_install_dependencies_dev()
  alt --force
    I->>I: _cleanup_docker()
  end
  I->>DC: up -d (api, db, redis, supertokens, caddy)
  DC-->>DB: start + healthcheck
  DC-->>R: start + healthcheck
  DC-->>ST: start + healthcheck
  DC-->>API: build from Dockerfile.dev + healthcheck
  DC-->>C: start + healthcheck
  I->>I: _start_frontend() (yarn install && dev)
  I->>I: _validate_services() (HTTP readiness)
  I-->>CLI: success details (ports, logs, commands)
  CLI-->>U: Output summary
  note over I,DC: Proxy setup skipped in dev
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

nixopus-api, cli, nixopus-config, nixopus-view

Suggested reviewers

  • raghavyuva

Poem

A rabbit taps keys by the moon’s cool glow,
Spins up dev stacks where fresh ports flow.
Caddy hums, Redis chirps, DB says hi,
The frontend twirls while hot-reloads fly.
With whiskered pride and dockered delight,
I hop through healthchecks—green lights tonight! 🐇✨

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

… feat/dev-setup-stokns # Please enter a commit message

to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines
starting with '#' will be ignored, and an empty message aborts # the commit.
@zhravan
Copy link
Collaborator Author

zhravan commented Oct 7, 2025

@coderabbitai: Add detailed summary and detailed review

Copy link
Contributor

coderabbitai bot commented Oct 7, 2025

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# Get PR details
echo "=== PR Details ==="
gh pr view 441 --json title,body,files,additions,deletions,changedFiles,commits

echo -e "\n=== PR Diff ==="
gh pr diff 441

echo -e "\n=== List of changed files ==="
gh pr view 441 --json files --jq '.files[].path'

Length of output: 90435


@zhravan: I'll provide a detailed summary and review of this PR.

Detailed Summary

This PR introduces a comprehensive dockerized development environment with live reloading capabilities for the Nixopus project. The changes separate development and production deployment modes, enabling developers to run the entire stack locally with hot-reload functionality.

Key Changes:

1. New Development Dockerfile (api/Dockerfile.dev)

  • Uses golang:alpine as base image
  • Installs Air for Go live reloading
  • Mounts source code as volumes for hot-reload
  • Configures development-specific environment

2. Development Docker Compose (docker-compose-dev.yml)

  • Services configured: API (with Air), PostgreSQL, Redis, SuperTokens, Caddy
  • Live reloading enabled for backend via Air
  • Volume mounts for source code, SSH keys, Docker socket
  • Service dependencies and health checks properly configured
  • Container networking with host.docker.internal for SSH access

3. CLI Enhancement (cli/app/commands/install/command.py & run.py)

  • New command: install development for local dev setup
  • Intelligent dependency management: Only installs missing dependencies in dev mode
  • Frontend startup: Automatically installs and starts Next.js dev server
  • Service validation: Health checks for backend and frontend
  • Environment isolation: Separate env variable handling for dev vs production
  • Enhanced messaging: Detailed success messages with service URLs, logs, and commands

4. Configuration Updates (helpers/config.dev.yaml)

  • Removed containerized dependencies (Redis, PostgreSQL, Go, Air) from host requirements
  • Updated SSH configuration for container-to-host access (host.docker.internal)
  • Changed default ports (API: 8080, Frontend: 3000)
  • Updated compose file reference to docker-compose-dev.yml

5. Dependency Cleanup

  • Removed nextjs-cors package (no longer needed)
  • Updated various yarn dependencies in lock file

Architecture Improvements:

  1. Separation of Concerns: Clear distinction between production and development modes
  2. Developer Experience: One command to set up entire local environment
  3. Live Reloading: Instant feedback for code changes (backend via Air, frontend via Next.js)
  4. Service Orchestration: Proper startup order, health checks, and dependency management
  5. Localhost Access: Backend can SSH to host machine for development/testing

Workflow:

# Install development environment
nixopus install development --path /path/to/dev

# Services start automatically:
# - Backend: http://localhost:8080 (with live reload)
# - Frontend: http://localhost:3000 (with Next.js dev server)
# - Database, Redis, SuperTokens, Caddy (all containerized)

# View logs, make changes, and see live updates

Detailed Review

🎯 Strengths

  1. Comprehensive Solution: The PR covers all aspects of a development environment - containers, CLI, configuration, and documentation through success messages

  2. Smart Dependency Handling: The _check_and_install_dependencies_dev() method only installs missing dependencies, improving installation speed on subsequent runs

  3. Proper Service Orchestration: Health checks and dependency management ensure services start in the correct order

  4. Excellent Developer Feedback: Success messages provide all necessary information (URLs, log commands, restart commands)

  5. Environment Variable Isolation: Clear separation between dev and prod environment configurations

⚠️ Areas for Improvement

1. Error Handling and Cleanup (Lines 443-500 in run.py)

The frontend startup process creates background processes and log files but lacks proper cleanup on failure:

def _start_frontend(self):
    # ... 
    try:
        log_file = open(log_file_path, "w")
        process = subprocess.Popen(...)
        
        # If process fails, log_file remains open
        if process.poll() is not None:
            raise Exception("Frontend server failed to start. Check logs/frontend.log")

Suggestion: Add proper resource cleanup:

def _start_frontend(self):
    log_file = None
    try:
        log_file = open(log_file_path, "w")
        process = subprocess.Popen(...)
        
        time.sleep(5)
        
        if process.poll() is not None:
            raise Exception("Frontend server failed to start. Check logs/frontend.log")
            
    except Exception as e:
        if log_file:
            log_file.close()
        raise Exception(f"Failed to start frontend: {str(e)}")

2. Service Validation Reliability (Lines 502-625 in run.py)

The validation uses hardcoded retry counts and sleep intervals:

for i in range(5):  # Hardcoded retries
    try:
        response = urllib.request.urlopen(backend_url, timeout=5)
        ...
    except Exception:
        if i < 4:
            time.sleep(2)  # Hardcoded sleep

Suggestion: Make these configurable and use exponential backoff:

def _validate_service(self, url, service_name, max_retries=5, initial_delay=1):
    for attempt in range(max_retries):
        try:
            response = urllib.request.urlopen(url, timeout=5)
            return True
        except Exception:
            if attempt < max_retries - 1:
                delay = initial_delay * (2 ** attempt)  # Exponential backoff
                time.sleep(min(delay, 10))  # Cap at 10 seconds
    return False

3. Docker Compose Resource Management

The docker-compose-dev.yml doesn't specify resource limits:

api:
  build:
    context: ./api
    dockerfile: Dockerfile.dev
  # No resource limits specified

Suggestion: Add resource constraints to prevent resource exhaustion:

api:
  build:
    context: ./api
    dockerfile: Dockerfile.dev
  deploy:
    resources:
      limits:
        cpus: '2'
        memory: 2G
      reservations:
        cpus: '1'
        memory: 512M

4. SSH Key Configuration (Line 449 in run.py)

The SSH key path is hardcoded:

if key == "ssh_key_path":
    return os.path.expanduser("~/.ssh/id_rsa_nixopus")

Suggestion: Make it configurable through config or allow override via environment variable.

5. Missing Frontend Stop Command

The success message shows how to stop the frontend but doesn't provide a helper command:

self.logger.info(f"  • Frontend:  kill $(cat {os.path.join(install_dir, 'logs', 'frontend.pid')})")

Suggestion: Add a CLI command to stop/restart services:

nixopus dev stop
nixopus dev restart
nixopus dev logs [service]

6. Dockerfile Security

The api/Dockerfile.dev runs as root:

WORKDIR /app
# No USER directive
CMD ["air"]

Suggestion: Add non-root user for better security:

FROM golang:alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# ... rest of setup
USER appuser
CMD ["air"]

📝 Minor Issues

  1. Line 3 in api/Dockerfile.dev: Comment says "Install air for live reload" but should mention bash, git, curl, make are also installed

  2. Line 106 in docker-compose-dev.yml: Comment says "Basic health check" but it only checks if Caddy binary is available, not if it's serving correctly

  3. Line 621 in run.py: Duplicate code between verbose and non-verbose success messages - consider refactoring

Testing Recommendations

  1. Test installation on clean machines (no existing dependencies)
  2. Test with missing yarn/node (should fail gracefully)
  3. Test frontend/backend restart scenarios
  4. Test with non-standard ports (port conflicts)
  5. Verify SSH access from container to host
  6. Test cleanup when installation fails mid-way

Conclusion

This is an excellent PR that significantly improves the developer experience. The implementation is comprehensive and well-thought-out. The suggested improvements mainly focus on robustness, error handling, and security hardening.

Recommendation: Approve with minor improvements for error handling and resource management.

✅ Actions performed

Summary regeneration triggered.

@zhravan zhravan added good first issue Good for newcomers nixopus-view nixopus-api setup any issues related to dev/selfhosting setup hacktoberfest Issues relevant to the Hacktoberfest event hacktoberfest-accepted PRs accepted under Hacktober Fest event hacktoberfest2025 Issues for Hacktoberfest event - 2025 backend api labels Oct 8, 2025
@zhravan zhravan requested a review from raghavyuva October 10, 2025 06:31
Copy link
Owner

@raghavyuva raghavyuva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @zhravan here are some details to take care, rest LGTM!

view_domain=view_domain,
repo=repo,
branch=branch,
development=False,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if Install and DevelopmentInstall are two seperate methods then why are we passing development=False here?

self._cache = {}

# Determine config file based on environment
config_file = "config.dev.yaml" if default_env.upper() == "DEVELOPMENT" else "config.prod.yaml"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we also have a over ride yaml right here? like if we set a CUSTOM_YAML='/some/path' then it should override these behaviours by default.

not related to this PR, but good to go as you are aware of the flow here,

SSH_PORT: ${SSH_PORT:-22}
SSH_USER: ${SSH_USER:-$USER}
SSH_PRIVATE_KEY: ${SSH_PRIVATE_KEY:-~/.ssh/id_rsa_nixopus}
SSH_PRIVATE_KEY: ${SSH_PRIVATE_KEY:-/root/.ssh/id_rsa_nixopus}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why root instead of HOME directory?

"lucide-react": "^0.479.0",
"next": "15.2.3",
"next-themes": "^0.4.4",
"nextjs-cors": "^2.2.0",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we revert this change? and keep it in a seperate pr?

supertokens:

nixopus-supertokens:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's avoid this change for now, and see if this is affecting in production,

have you tested this change?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if some containers are running and some fails out? are we handling proper cleanup ensure so that user does not have to come in a state where he does not what happened, and not sure how to resolve in a half broken state?

@zhravan zhravan deleted the branch raghavyuva:feat/supertokens October 11, 2025 07:42
@zhravan zhravan closed this Oct 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api backend good first issue Good for newcomers hacktoberfest Issues relevant to the Hacktoberfest event hacktoberfest2025 Issues for Hacktoberfest event - 2025 hacktoberfest-accepted PRs accepted under Hacktober Fest event nixopus-api nixopus-view setup any issues related to dev/selfhosting setup

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants