Skip to content

Conversation

umidjon-2231
Copy link

@umidjon-2231 umidjon-2231 commented Jul 24, 2025

Description

This PR introduces a complete Docker-based deployment solution for Resume-Matcher, providing containerized environments for both development and production. The configuration eliminates the need for complex local environment setup by containerizing all services including the FastAPI backend, Next.js frontend, and Ollama AI service.

Relevant issue

#415

Type

  • Bug Fix
  • Feature Enhancement
  • Documentation Update
  • Code Refactoring
  • Other (please specify):

Proposed Changes

  • Added Dockerfile.backend for FastAPI application with uv package manager
  • Added Dockerfile.frontend for Next.js application with standalone output
  • Created docker-compose.yml for production environment setup
  • Created docker-compose.dev.yml for development environment with hot-reload
  • Introduced .dockerignore file to optimize Docker build context
  • Added comprehensive DOCKER.md documentation
  • Updated next.config.ts to support standalone builds and dynamic API URLs
  • Added health checks for all services in docker-compose configurations
  • Configured automated Ollama setup with gemma3:4b model initialization
  • Implemented proper service dependencies and startup orchestration
  • Added Docker volume persistence for data and AI models

Screenshots / Code Snippets (if applicable)

# docker-compose.yml - Simple production setup
services:
  ollama:
    image: ollama/ollama:latest
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
  
  backend:
    build:
      context: .
      dockerfile: Dockerfile.backend
    ports:
      - "8000:8000"
    depends_on:
      ollama:
        condition: service_healthy
  
  frontend:
    build:
      context: .
      dockerfile: Dockerfile.frontend
    ports:
      - "3000:3000"
    depends_on:
      backend:
        condition: service_healthy
# Simple Docker commands - no scripts needed
docker-compose build                              # Build images
docker-compose up -d                              # Start production
docker-compose -f docker-compose.dev.yml up -d   # Start development
docker-compose down                               # Stop services

How to Test

  1. Prerequisites: Install Docker and Docker Compose
  2. Clone repository: git clone <repo> && cd Resume-Matcher
  3. Build images: docker-compose build
  4. Start production: docker-compose up -d
  5. Wait for initialization: Allow 5-10 minutes for AI model download on first run
  6. Verify services:
  7. Test development mode:
    docker-compose down
    docker-compose -f docker-compose.dev.yml up -d
  8. Verify hot-reload: Edit frontend/backend code and confirm changes reflect automatically
  9. Clean up: docker-compose down -v to remove containers and volumes

Checklist

  • The code compiles successfully without any errors or warnings
  • The changes have been tested and verified
  • The documentation has been updated (if applicable)
  • The changes follow the project's coding guidelines and best practices
  • The commit messages are descriptive and follow the project's guidelines
  • All tests (if applicable) pass successfully
  • This pull request has been linked to the related issue (if applicable)

Additional Information

Key Benefits:

  • 🐳 Zero local dependencies: No need to install Python, Node.js, Ollama, or uv locally
  • 🚀 Simple deployment: Standard docker-compose up -d command
  • 🔄 Development-friendly: Hot-reload support in development mode
  • 🤖 AI-ready: Automated Ollama setup with gemma3:4b model
  • 🌐 Cross-platform: Works identically on Windows, macOS, and Linux
  • 📦 Optimized: Multi-stage Dockerfiles with minimal production images
  • 🔒 Production-ready: Health checks, proper user permissions, and service dependencies

Technical Implementation:

  • Backend: Python 3.12 + FastAPI + uv package manager
  • Frontend: Node.js 18 + Next.js with standalone output
  • AI: Ollama with automated gemma3:4b model download
  • Database: SQLite with Docker volume persistence
  • Architecture: Multi-service with proper dependency management

File Structure:

├── Dockerfile.backend          # FastAPI container (Python + uv)
├── Dockerfile.frontend         # Next.js container (standalone build)
├── docker-compose.yml          # Production environment
├── docker-compose.dev.yml      # Development environment
├── .dockerignore              # Build context optimization
└── DOCKER.md                  # Setup and usage documentation

Breaking Changes:

  • None - this is purely additive functionality
  • Existing local development workflow remains unchanged

Resource Requirements:

  • Minimum: 8GB RAM, 10GB disk space
  • Recommended: 16GB RAM, 20GB disk space
  • First run: Additional time for AI model download (~4GB)

Summary by CodeRabbit

  • New Features

    • Added comprehensive Docker support for both production and development, including Dockerfiles, Compose files, and a .dockerignore for optimized builds.
    • Introduced health checks and persistent storage for backend, frontend, and AI services.
    • Enhanced environment configuration and service orchestration for reliable startup and scaling.
    • Provided new npm scripts for streamlined Docker management.
  • Documentation

    • Added a detailed Docker setup and troubleshooting guide.
    • Updated the README with Docker installation instructions and references to further documentation.
  • Configuration

    • Improved frontend configuration for dynamic API URL handling and standalone output.

- Added Docker setup instructions to README.md and DOCKER.md.
- Updated Dockerfiles for backend and frontend services.
- Improved docker-compose configurations for development and production environments.
- Introduced .dockerignore file to optimize Docker builds.
- Added health checks for backend and frontend services in docker-compose files.
Copy link
Contributor

coderabbitai bot commented Jul 24, 2025

Walkthrough

A comprehensive Docker setup was introduced for the Resume Matcher project. This includes new Dockerfiles for backend and frontend, production and development Docker Compose files, a detailed Docker setup guide, and an extensive .dockerignore. The frontend Next.js configuration and project scripts were updated to support Dockerized workflows, with new documentation in the README.

Changes

File(s) Change Summary
.dockerignore Added file listing patterns to exclude unnecessary files from Docker build context.
DOCKER.md New documentation detailing Docker setup, configuration, troubleshooting, performance, security, and scaling.
Dockerfile.backend, Dockerfile.frontend Added Dockerfiles for backend (Python) and frontend (Node.js/Next.js) with multi-stage builds and health checks.
docker-compose.yml, docker-compose.dev.yml Added Compose files defining services, dependencies, volumes, health checks for production and development.
README.md Enhanced with Docker installation instructions, quick start, and references to new Docker documentation.
apps/frontend/next.config.ts Updated Next.js config: added output: 'standalone' and dynamic API URL rewrites for Docker compatibility.
package.json Added npm scripts for Docker build, up, down, dev, logs, and clean commands.

Sequence Diagram(s)

sequenceDiagram
    participant Dev as Developer
    participant Docker as Docker Engine
    participant Compose as Docker Compose
    participant Ollama as Ollama AI Service
    participant Backend as Backend Service
    participant Frontend as Frontend Service

    Dev->>Docker: Build images (backend, frontend)
    Dev->>Compose: Start services (docker-compose up)
    Compose->>Ollama: Start Ollama container
    Compose->>Ollama: Health check /api/tags
    Compose->>Ollama-init: Wait for Ollama healthy, pull model
    Compose->>Backend: Start after Ollama & Ollama-init ready
    Compose->>Backend: Health check /health
    Compose->>Frontend: Start after Backend healthy
    Compose->>Frontend: Health check /
    Dev->>Frontend: Access web app (port 3000)
    Frontend->>Backend: API requests (rewritten via API_URL)
    Backend->>Ollama: AI model requests
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

Docker ships upon the sea,
Compose and files in harmony.
Backend, frontend, Ollama too,
All set sail with something new!
Scripts and docs now lead the way—
Rabbit’s paws are here to say:
"Hop aboard, deploy today!" 🐇🚢

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
🧪 Generate unit tests
  • 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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🔭 Outside diff range comments (1)
Dockerfile.backend (1)

2-39: Add non-root user for better security.

The container runs as root, which poses security risks. Consider adding a non-root user.

 FROM python:3.12-slim
 
 # Set environment variables
 ENV PYTHONDONTWRITEBYTECODE=1
 ENV PYTHONUNBUFFERED=1
 ENV UV_CACHE_DIR=/tmp/uv-cache
 
+# Create non-root user
+RUN groupadd -r appuser && useradd -r -g appuser appuser
+
 # Install system dependencies
 RUN apt-get update && apt-get install -y \
     curl \
     build-essential \
     && rm -rf /var/lib/apt/lists/*
 
 # Install uv
 RUN pip install uv
 
 # Set working directory
 WORKDIR /app
 
+# Change ownership to appuser
+RUN chown -R appuser:appuser /app
+
+# Switch to non-root user
+USER appuser
+
 # Copy backend files
 COPY apps/backend/ .
♻️ Duplicate comments (1)
docker-compose.yml (1)

80-92: NEXT_PUBLIC_API_URL build arg is passed, but Dockerfile doesn’t consume it

Without an ARG in Dockerfile.frontend, this value is lost (see Dockerfile comment). After fixing the Dockerfile, leave this block as-is.

🧹 Nitpick comments (6)
.dockerignore (1)

96-99: Consider being more selective with documentation exclusions.

Excluding all .md files might be too broad as some documentation might be needed at runtime (e.g., embedded help text, API documentation). Consider being more specific about which documentation files to exclude.

# Documentation
-README.md
-*.md
-docs/
+README.md
+DOCKER.md
+SETUP.md
+docs/
Dockerfile.backend (1)

16-16: Consider installing uv using the official installer.

Installing uv via pip might not provide the latest version. Consider using the official installer for better performance and latest features.

-# Install uv
-RUN pip install uv
+# Install uv using official installer
+RUN curl -LsSf https://astral.sh/uv/install.sh | sh
+ENV PATH="/root/.local/bin:$PATH"
package.json (1)

26-26: Consider less aggressive Docker cleanup.

The docker system prune -f command removes all unused Docker resources system-wide, which might affect other projects. Consider a more targeted cleanup.

-"docker:clean": "docker compose down -v --remove-orphans && docker system prune -f"
+"docker:clean": "docker compose down -v --remove-orphans && docker image prune -f --filter label=project=resume-matcher"

Or provide separate commands:

-"docker:clean": "docker compose down -v --remove-orphans && docker system prune -f"
+"docker:clean": "docker compose down -v --remove-orphans",
+"docker:clean:system": "docker system prune -f"
DOCKER.md (3)

16-20: Typo: docker-compo se.yml

Extra spaces split the filename, which will confuse copy-pasting.

-`docker-compo  se.yml`
+`docker-compose.yml`

40-45: Command sample contains docdocker – looks like a paste artefact

-docdocker compose ps
+docker compose ps

227-235: Reset section commands are mangled

Two typos will make the destructive commands fail:

-docdocker compose n -v --remove-orphans
+# Stop & remove everything
+docker compose down -v --remove-orphans

-docdocker compose down --rmi all
+docker compose down --rmi all
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 294d52a and e2863ab.

📒 Files selected for processing (9)
  • .dockerignore (1 hunks)
  • DOCKER.md (1 hunks)
  • Dockerfile.backend (1 hunks)
  • Dockerfile.frontend (1 hunks)
  • README.md (2 hunks)
  • apps/frontend/next.config.ts (1 hunks)
  • docker-compose.dev.yml (1 hunks)
  • docker-compose.yml (1 hunks)
  • package.json (1 hunks)
🔇 Additional comments (9)
.dockerignore (2)

92-94: Good practice: Selective lock file handling.

Correctly keeping package-lock.json while excluding other lock files ensures npm dependencies are properly locked for consistent builds across environments.


69-71: .dockerignore exclusions safe for multi-stage builds

  • Grep search found no COPY/ADD instructions pulling in other Dockerfiles or docker-compose*.yml.
  • Remember that .dockerignore only filters the build context sent by docker build—it does not prevent docker-compose from reading its YAML files.
  • The Dockerfile itself is always loaded by the Docker CLI, so multi-stage builds remain unaffected.

No further changes required.

apps/frontend/next.config.ts (2)

5-5: Excellent: Enabling standalone output for Docker.

The standalone output mode is perfect for Docker containerization as it creates a self-contained application with all dependencies bundled, reducing image size and improving startup performance.


10-10: Good practice: Dynamic API URL configuration.

Using NEXT_PUBLIC_API_URL environment variable with a localhost fallback provides flexibility for different deployment environments while maintaining backward compatibility for local development.

README.md (1)

74-95: Excellent Docker documentation structure.

The Docker installation section is well-organized with clear commands, environment options, and helpful quick reference commands. Good practice to make Docker the recommended approach while preserving local setup options.

Dockerfile.backend (1)

34-35: Good practice: Health check implementation.

The health check configuration is well-implemented with appropriate intervals and timeout values, enabling proper container orchestration and monitoring.

package.json (1)

21-25: Excellent Docker script coverage.

The Docker scripts provide comprehensive container lifecycle management with appropriate flags and configurations. Good separation of production and development environments.

Dockerfile.frontend (1)

56-58: Health-check uses wget; ensure it exists

node:18-alpine includes BusyBox’s minimal wget, but if the base image changes this will break silently. Consider switching to curl (already installed in most images) or explicitly apk add --no-cache wget during the deps stage.

docker-compose.dev.yml (1)

50-54: target: base assumes a stage that may not exist

Ensure Dockerfile.backend defines a FROM … AS base stage. If not, the build will fail in dev mode.

umidjon-2231 and others added 5 commits July 24, 2025 15:04
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
@vaddisrinivas
Copy link

Adding a relevant issue here

@umidjon-2231
Copy link
Author

Adding a relevant issue here

Thanks

@arsaboo
Copy link

arsaboo commented Jul 25, 2025

Users may use their existing Ollama instance. It may be better to just add a env variable specifying the ollama endpoint.

@vaddisrinivas
Copy link

Users may use their existing Ollama instance. It may be better to just add a env variable specifying the ollama endpoint.

➕1 on this

@umidjon-2231
Copy link
Author

umidjon-2231 commented Jul 25, 2025 via email

Copy link

@amarrerod amarrerod left a comment

Choose a reason for hiding this comment

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

I suggest to update the ollama and backend containers to include curl

Comment on lines +72 to +77
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 5
start_period: 30s

Choose a reason for hiding this comment

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

Had a similar problem here with curl. Here's the docker inspect output:

"Health": {
               "Status": "unhealthy",
               "FailingStreak": 0,
               "Log": [
                   {
                       "Start": "2025-07-25T13:33:35.929450468Z",
                       "End": "2025-07-25T13:33:36.011462273Z",
                       "ExitCode": -1,
                       "Output": "OCI runtime exec failed: exec failed: unable to start container process: exec: \"curl\": executable file not found in $PATH: unknown"
                   }
               ]
           }
       },

But now, it is impossible to manually install curl since the container is continuously restarting.

Copy link
Author

Choose a reason for hiding this comment

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

Okay let me check

@smit-io
Copy link

smit-io commented Jul 25, 2025

Having to provide your own ollama instance rather than having to spin up another ollama container would be nice.

@umidjon-2231
Copy link
Author

Having to provide your own ollama instance rather than having to spin up another ollama container would be nice.

Sure i am working on that

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
DOCKER.md (1)

57-60: Wrap bare URLs to satisfy markdownlint MD034

Lines 57-59 trigger MD034 (bare URLs).
Wrapping them keeps the doc linter quiet and renders consistently across markdown viewers.

- - Frontend: http://localhost:3000
- - Backend API: http://localhost:8000
- - Ollama API: http://localhost:11434 (if using containerized Ollama)
+ - Frontend: <http://localhost:3000>
+ - Backend API: <http://localhost:8000>
+ - Ollama API: <http://localhost:11434> (if using containerized Ollama)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e2863ab and 26f4f23.

📒 Files selected for processing (6)
  • DOCKER.md (1 hunks)
  • Dockerfile.backend (1 hunks)
  • Dockerfile.frontend (1 hunks)
  • README.md (2 hunks)
  • docker-compose.dev.yml (1 hunks)
  • docker-compose.yml (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • Dockerfile.frontend
🚧 Files skipped from review as they are similar to previous changes (4)
  • README.md
  • Dockerfile.backend
  • docker-compose.yml
  • docker-compose.dev.yml
🧰 Additional context used
🪛 markdownlint-cli2 (0.17.2)
DOCKER.md

57-57: Bare URL used

(MD034, no-bare-urls)


58-58: Bare URL used

(MD034, no-bare-urls)


59-59: Bare URL used

(MD034, no-bare-urls)


- `Dockerfile.backend` - Backend FastAPI application container
- `Dockerfile.frontend` - Frontend Next.js application container
- `docker-compo se.yml` - Production deployment configuration
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix misspelled compose filename

The list of Docker-related files shows "docker-compo se.yml", which contains an internal space and drops the “s”.
Anyone copy-pasting will end up with a non-existent file name.

Proposed fix:

- - `docker-compo  se.yml` - Production deployment configuration
+ - `docker-compose.yml` - Production deployment configuration
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- `docker-compo se.yml` - Production deployment configuration
- `docker-compose.yml` - Production deployment configuration
🤖 Prompt for AI Agents
In DOCKER.md at line 18, fix the misspelled Docker compose filename by removing
the internal space and adding the missing "s" so it reads "docker-compose.yml"
instead of "docker-compo  se.yml". This correction ensures the filename is
accurate and can be used correctly when copy-pasting.

Comment on lines +275 to +283
### Reset Everything

```bash
# Stop and remove all containers, networks, and volumes
docdocker compose n -v --remove-orphans

# Remove all images
docdocker compose down --rmi all

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct the “Reset Everything” cleanup commands

The header has extra spaces and the commands contain the typo docdocker, plus a malformed n option. These will fail when executed.

-### Reset    Everything
+### Reset Everything
@@
-docdocker compose n -v --remove-orphans
+docker compose down -v --remove-orphans
@@
-docdocker compose down --rmi all
+docker compose down --rmi all
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Reset Everything
```bash
# Stop and remove all containers, networks, and volumes
docdocker compose n -v --remove-orphans
# Remove all images
docdocker compose down --rmi all
### Reset Everything
🤖 Prompt for AI Agents
In DOCKER.md around lines 275 to 283, the "Reset Everything" section has extra
spaces in the header and incorrect commands with the typo "docdocker" and a
malformed "n" option. Remove the extra spaces in the header to make it "###
Reset Everything" and fix the commands by replacing "docdocker" with "docker"
and correcting the options to valid docker compose commands for stopping and
removing containers, networks, volumes, and images.

@mahimairaja
Copy link

LGTM

@Noobzik
Copy link

Noobzik commented Jul 31, 2025

Followed blindly your instruction, I have an error with the backend not connecting to database. Here the logs
pastebin.com/raw/BuE83b0X

@umidjon-2231

@umidjon-2231
Copy link
Author

Followed blindly your instruction, I have an error with the backend not connecting to database. Here the logs
pastebin.com/raw/BuE83b0X

@umidjon-2231

Thanks for the report. I will fix it soon. I guess the problem is SQLite file is not created.

@mahimairaja
Copy link

@umidjon-2231 are you still working on the issue? can I give my hands

@umidjon-2231
Copy link
Author

@umidjon-2231 are you still working on the issue? can I give my hands

Hi @mahimairaja ,
Yes, I’m still working on it, but help is welcome. Let me know what part you’d like to take on so we can coordinate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Backlog
Development

Successfully merging this pull request may close these issues.

7 participants