-
Notifications
You must be signed in to change notification settings - Fork 1
Add local development configuration with docker-compose.local.yml #107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a new Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant Dev as Developer
participant Compose as docker compose (-f ...)
participant Redmine as redmine-tunnel
participant Mongo as mongo-tunnel
participant Worker as temporal-worker-main
participant Remote as Remote DBs
Dev->>Compose: docker compose -f docker-compose.yml -f docker-compose.local.yml up
Compose->>Redmine: create/start container (Alpine + ssh)
Compose->>Mongo: create/start container (Alpine + ssh)
Compose->>Worker: create/start temporal worker (env_file + extra_hosts)
Redmine->>Remote: ssh tunnel local:3306 -> remote MySQL
Mongo->>Remote: ssh tunnel local:31000 -> remote Mongo
Worker->>Mongo: connect via forwarded host-gateway ports
Note right of Worker: uses forwarded ports to reach remote services
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Areas to check:
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
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. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Nitpick comments (1)
README.md (1)
195-200: Expand troubleshooting for local development SSH tunnels.The Troubleshooting section (lines 195-200) covers container logs and port availability but misses guidance for SSH tunnel issues specific to local development:
- Connection refused on port 3306/31000
- Host key verification errors
- SSH key permission issues
- Authentication failures
Consider adding:
**SSH Tunnel Issues (local development):** - Verify SSH key permissions: `chmod 600 ~/.ssh/id_rsa` - Test SSH connection manually: `ssh -i ~/.ssh/id_rsa ubuntu@your_host` - Check tunnel logs: `docker logs redmine-tunnel` or `docker logs mongo-tunnel` - Verify port forwarding: `netstat -an | grep 3306` (Linux) or `netstat -an | grep 31000` (macOS)
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
README.md(7 hunks)docker-compose.local.yml(1 hunks)
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-07-28T16:44:50.073Z
Learnt from: CR
PR: speedandfunction/automatization#0
File: .cursor/rules/project-structure.mdc:0-0
Timestamp: 2025-07-28T16:44:50.073Z
Learning: The project architecture must include interconnected services: n8n, Temporal Server, Temporal UI, PostgreSQL, and OpenSearch, each running on their specified ports.
Applied to files:
README.md
📚 Learning: 2025-06-24T12:29:29.869Z
Learnt from: CR
PR: speedandfunction/automatization#0
File: .cursor/rules/service-configuration.mdc:0-0
Timestamp: 2025-06-24T12:29:29.869Z
Learning: Health verification scripts (such as scripts/check_services.sh) should check the accessibility of all critical service endpoints (HTTP, gRPC, database ports) to ensure the stack is running as expected.
Applied to files:
README.md
📚 Learning: 2025-07-28T16:44:24.081Z
Learnt from: CR
PR: speedandfunction/automatization#0
File: .cursor/rules/docker-configuration.mdc:0-0
Timestamp: 2025-07-28T16:44:24.081Z
Learning: Applies to volumes/**/* : All service data must be persisted in Docker volumes mapped to the local volumes/ directory, such as ./volumes/n8n_data, ./volumes/opensearch-data, and ./volumes/postgresql-data
Applied to files:
README.md
📚 Learning: 2025-07-28T16:44:24.081Z
Learnt from: CR
PR: speedandfunction/automatization#0
File: .cursor/rules/docker-configuration.mdc:0-0
Timestamp: 2025-07-28T16:44:24.081Z
Learning: Applies to docker-compose.yml : Services must communicate over an internal Docker network with only the specified ports exposed: n8n (5678), Temporal (7233), Temporal UI (8080), PostgreSQL (5432), and OpenSearch (9200)
Applied to files:
README.md
📚 Learning: 2025-07-28T16:44:24.081Z
Learnt from: CR
PR: speedandfunction/automatization#0
File: .cursor/rules/docker-configuration.mdc:0-0
Timestamp: 2025-07-28T16:44:24.081Z
Learning: Applies to docker-compose.yml : All service configurations, including service dependencies, volume mounts, network configuration, environment variables, and port mappings, must be defined in docker-compose.yml
Applied to files:
README.md
📚 Learning: 2025-06-24T12:29:29.869Z
Learnt from: CR
PR: speedandfunction/automatization#0
File: .cursor/rules/service-configuration.mdc:0-0
Timestamp: 2025-06-24T12:29:29.869Z
Learning: Troubleshooting containerized services should include checking container logs, verifying port availability, ensuring sufficient Docker resources, rerunning setup scripts for volume issues, and checking service health endpoints.
Applied to files:
README.md
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: Docker Security Scanning (n8n, Dockerfile.n8n, n8n-test:latest)
- GitHub Check: Service Availability Check
🔇 Additional comments (3)
docker-compose.local.yml (1)
32-38: Verify temporal-worker-main configuration and .env dependency.The temporal-worker-main service relies on an
.envfile but has minimal inline configuration shown. Ensure:
- The
.envfile exists and contains required environment variables for this service- The
extra_hostsmapping tohost-gatewayis intentional for DNS resolution of MongoDB replicas from within the container- Confirm this service is compatible with the SSH tunnels defined above (port mappings align)
Consider documenting the expected
.envvariables in a.env.local.examplefile.README.md (2)
59-77: Clear local development documentation added.Lines 59-77 properly document the three deployment scenarios (Local Development, Development, Production) with correct docker-compose command syntax. The explicit mention of the
-fflag and the need to specifydocker-compose.local.ymlis helpful.
172-181: Review comment is architecturally inaccurate relative to actual implementation.The review identifies a valid gap—SSH tunnel setup for local development is undocumented in README.md—but proposes environment variables (
REDMINE_SSH_USER,REDMINE_SSH_HOST,REDMINE_DB_HOST,REDMINE_FORWARD_HOST) and.env.localconfiguration that do not exist in the actualdocker-compose.local.yml.The actual
docker-compose.local.ymlcontains hardcoded SSH hosts in command strings:
redmine-tunnel:ssh -i /root/.ssh/id_rsa ubuntu@staging.forecasting-v2.gluzdov.com(hardcoded)mongo-tunnel:ssh -i /root/.ssh/id_rsa ubuntu@forecasting-v2.gluzdov.com(hardcoded)The
SSH_KEYenvironment variable is set but unused dynamically in the current implementation.What actually needs documentation (lines 59-61, "Local Development" section):
- SSH key setup requirement (
~/.ssh/id_rsa)- What tunnel services do (forward remote database ports)
- SSH troubleshooting guidance
The review suggests adding
.env.localparametrization that would require refactoring the docker-compose.local.yml itself—this is beyond documentation and mischaracterizes the current setup.Likely an incorrect or invalid review comment.
| redmine-tunnel: | ||
| container_name: redmine-tunnel | ||
| image: alpine:latest | ||
| command: > | ||
| sh -c "apk add --no-cache openssh && | ||
| ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa ubuntu@staging.forecasting-v2.gluzdov.com -N -L 0.0.0.0:3306:redmine-pr-rds-db-read.c1kaki1qbk4o.us-east-1.rds.amazonaws.com:3306 -L 0.0.0.0:31000:10.4.3.184:31000" | ||
| volumes: | ||
| - ~/.ssh:/root/.ssh:ro | ||
| ports: | ||
| - '3306:3306' | ||
| networks: | ||
| - app-network | ||
| environment: | ||
| - SSH_KEY=/root/.ssh/id_rsa |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Hardcoded infrastructure endpoints and credentials exposed.
Lines 7 and throughout the redmine-tunnel service expose sensitive infrastructure details that must never be committed:
- Hardcoded staging hostname:
ubuntu@staging.forecasting-v2.gluzdov.com - Hardcoded AWS RDS endpoint:
redmine-pr-rds-db-read.c1kaki1qbk4o.us-east-1.rds.amazonaws.com - Hardcoded internal IP:
10.4.3.184:31000
These represent production/staging infrastructure and should be externalized to environment variables or a .env.local file that is excluded from version control.
Refactor to use environment variable substitution:
services:
redmine-tunnel:
container_name: redmine-tunnel
image: alpine:latest
command: >
sh -c "apk add --no-cache openssh &&
- ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa ubuntu@staging.forecasting-v2.gluzdov.com -N -L 0.0.0.0:3306:redmine-pr-rds-db-read.c1kaki1qbk4o.us-east-1.rds.amazonaws.com:3306 -L 0.0.0.0:31000:10.4.3.184:31000"
+ ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa ${REDMINE_SSH_USER}@${REDMINE_SSH_HOST} -N -L 0.0.0.0:3306:${REDMINE_DB_HOST}:3306 -L 0.0.0.0:31000:${REDMINE_FORWARD_HOST}:31000"Ensure .env.local is added to .gitignore and create a .env.local.example template with placeholder values.
🤖 Prompt for AI Agents
In docker-compose.local.yml around lines 2 to 15 the redmine-tunnel service
contains hardcoded sensitive endpoints (staging SSH host, RDS endpoint and
internal IP/port); replace those literal values with environment-variable
placeholders (e.g. ${SSH_REMOTE_USER}@${SSH_REMOTE_HOST}, ${RDS_HOST},
${INTERNAL_IP}:${INTERNAL_PORT}) and reference them via docker-compose variable
substitution, ensure the SSH key path is configurable (e.g. ${SSH_KEY_PATH})
rather than hardcoded, and update the compose file to read from a .env.local
file; add .env.local to .gitignore and create a .env.local.example with
placeholder values for all new variables so no secrets are committed.
| sh -c "apk add --no-cache openssh && | ||
| ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa ubuntu@staging.forecasting-v2.gluzdov.com -N -L 0.0.0.0:3306:redmine-pr-rds-db-read.c1kaki1qbk4o.us-east-1.rds.amazonaws.com:3306 -L 0.0.0.0:31000:10.4.3.184:31000" | ||
| volumes: | ||
| - ~/.ssh:/root/.ssh:ro | ||
| ports: | ||
| - '3306:3306' | ||
| networks: | ||
| - app-network | ||
| environment: | ||
| - SSH_KEY=/root/.ssh/id_rsa |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Major: SSH security misconfigurations and unused environment variable.
Multiple SSH-related issues:
-
Line 6:
StrictHostKeyChecking=nodisables host key verification, bypassing critical SSH security. This should only be used with extreme caution and be justified in comments. -
Line 15:
SSH_KEYenvironment variable is defined but never used in the actual SSH command (line 7). The command hardcodes/root/.ssh/id_rsainstead. This inconsistency suggests incomplete refactoring or dead code. -
Line 7: SSH key path is hardcoded to
/root/.ssh/id_rsa, assuming this specific filename. Consider using theSSH_KEYenv var consistently or making it configurable.
Apply this diff to fix the inconsistency:
redmine-tunnel:
container_name: redmine-tunnel
image: alpine:latest
command: >
sh -c "apk add --no-cache openssh &&
- ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa ubuntu@staging.forecasting-v2.gluzdov.com -N -L 0.0.0.0:3306:redmine-pr-rds-db-read.c1kaki1qbk4o.us-east-1.rds.amazonaws.com:3306 -L 0.0.0.0:31000:10.4.3.184:31000"
+ ssh -o StrictHostKeyChecking=accept-new -i ${SSH_KEY} ${REDMINE_SSH_USER}@${REDMINE_SSH_HOST} -N -L 0.0.0.0:3306:${REDMINE_DB_HOST}:3306 -L 0.0.0.0:31000:${REDMINE_FORWARD_HOST}:31000"
volumes:
- ~/.ssh:/root/.ssh:ro
ports:
- '3306:3306'
networks:
- app-network
environment:
- SSH_KEY=/root/.ssh/id_rsaConsider StrictHostKeyChecking=accept-new as a safer alternative to no, which accepts new keys but still validates known hosts.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In docker-compose.local.yml around lines 6 to 15, the SSH command disables
host-key verification and hardcodes the private key path while the SSH_KEY env
var is unused; replace StrictHostKeyChecking=no with
StrictHostKeyChecking=accept-new (or add a brief comment if no change is
allowed), remove the hardcoded /root/.ssh/id_rsa in the ssh command and
reference the SSH_KEY environment variable instead (or remove SSH_KEY if you
prefer a fixed path), and ensure the mounted volume and permissions match the
chosen key path; keep the SSH_KEY env var consistent with the command or delete
it to avoid dead configuration.
| mongo-tunnel: | ||
| container_name: mongo-tunnel | ||
| image: alpine:latest | ||
| command: > | ||
| sh -c "apk add --no-cache openssh && | ||
| ssh -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa ubuntu@forecasting-v2.gluzdov.com -N -L 0.0.0.0:31000:10.4.3.184:31000" | ||
| volumes: | ||
| - ~/.ssh:/root/.ssh:ro | ||
| ports: | ||
| - '31000:31000' | ||
| networks: | ||
| - app-network | ||
| environment: | ||
| - SSH_KEY=/root/.ssh/id_rsa |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical & Major: Hardcoded infrastructure endpoints and SSH misconfigurations (same as redmine-tunnel).
The mongo-tunnel service contains identical issues:
- Line 22: Hardcoded hostname
ubuntu@forecasting-v2.gluzdov.comand internal IP10.4.3.184 - Line 22:
StrictHostKeyChecking=nodisables host key verification - Line 30:
SSH_KEYenv var defined but unused; command hardcodes/root/.ssh/id_rsa
Apply the same refactoring as redmine-tunnel to externalize sensitive data and fix SSH security configuration.
🤖 Prompt for AI Agents
In docker-compose.local.yml around lines 17 to 30, the mongo-tunnel service
hardcodes the remote user/host and internal IP, disables host key verification,
and declares SSH_KEY env var but never uses it; replace the hardcoded values
with environment variables (e.g. MONGO_SSH_USER, MONGO_SSH_HOST,
MONGO_TARGET_HOST, MONGO_TARGET_PORT) and use the declared SSH_KEY variable as
the identity file path in the ssh command instead of a hardcoded path; remove
StrictHostKeyChecking=no and ensure host verification by either mounting a
known_hosts file or running ssh-keyscan at container startup to populate
/root/.ssh/known_hosts; ensure the private key is mounted read-only from the
host and referenced via the SSH_KEY env var so no secrets are baked into the
image or compose file.
🔍 Vulnerabilities of
|
| digest | sha256:bec1e62deecd352f51c7319cb7773ec3d870fb42eff383635b3b2ecf80221ff2 |
| vulnerabilities | |
| platform | linux/amd64 |
| size | 335 MB |
| packages | 1844 |
📦 Base Image node:22-alpine
Description
Description
Description
Description | ||||||||||||||||||||||||||||||||
Description
Description
| ||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||
Description
| ||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
workers/main/src/index.test.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.test.ts
📄 CodeRabbit inference engine (CLAUDE.md)
Tests are co-located with source files and should be named with the pattern *.test.ts
Files:
workers/main/src/index.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.{ts,tsx}: Follow the function naming pattern: prefix? + action (A) + high context (HC) + low context? (LC), using action verbs such as get, fetch, send, create, validate, handle, calculate, and boolean prefixes is, has, should
Use descriptive, unabbreviated variable names; use singular for single values and plural for collections; ensure variable names are context-specific
Files:
workers/main/src/index.test.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: Docker Security Scanning (temporal, Dockerfile.temporal, temporal-test:latest)
- GitHub Check: Docker Security Scanning (n8n, Dockerfile.n8n, n8n-test:latest)
- GitHub Check: Service Availability Check
- GitHub Check: SonarQube
🔇 Additional comments (1)
workers/main/src/index.test.ts (1)
19-20: LGTM: Proper timer cleanup.The cleanup properly clears pending timers and restores real timers, following best practices for test isolation. This is good test hygiene, though it's only necessary if fake timers are actually being used.
| vi.useFakeTimers(); | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Verify timer usage in handleRunError implementation.
Fake timers are configured but the tests don't explicitly advance or control them. If handleRunError uses timers (e.g., delayed process.exit), the tests should verify that behavior with vi.advanceTimersByTime() or vi.runAllTimers(). If it doesn't use timers, this setup adds unnecessary overhead.
Run the following script to check if handleRunError uses timer functions:
🏁 Script executed:
#!/bin/bash
# Description: Check if handleRunError implementation uses setTimeout, setInterval, or other timer functions
# Search for handleRunError implementation and timer usage
ast-grep --pattern 'function handleRunError($$$) {
$$$
}'
# Also search for timer-related calls in the index.ts file
rg -n 'setTimeout|setInterval|clearTimeout|clearInterval' workers/main/src/index.tsLength of output: 44
I need to check the actual test implementations to see if they're advancing timers or if they're missing this critical step.
🏁 Script executed:
#!/bin/bash
# View the handleRunError implementation and surrounding context
cat workers/main/src/index.ts | head -60 | tail -20
echo "---"
# View the full test file to see if timers are being advanced
cat workers/main/src/index.test.tsLength of output: 1929
Tests must verify the 100ms process.exit behavior when fake timers are enabled.
The test setup enables fake timers and mocks process.exit, but the tests never advance timers to trigger the setTimeout callback. Without calling vi.advanceTimersByTime(100) or vi.runAllTimers(), the process.exit(1) is never invoked and remains untested. Each test should advance timers after calling handleRunError() and verify that process.exit(1) was called.
Example fix:
it('should exit with code 1 after 100ms', () => {
const error = new Error('test error');
const logSpy = vi.spyOn(logger, 'error').mockImplementation(() => {});
handleRunError(error);
expect(logSpy).toHaveBeenCalledWith(
`Error in main worker: ${error.message}`,
);
vi.advanceTimersByTime(100);
expect(processExitSpy).toHaveBeenCalledWith(1);
logSpy.mockRestore();
});🤖 Prompt for AI Agents
In workers/main/src/index.test.ts around lines 9-10, tests enable fake timers
but never advance them so the 100ms setTimeout that calls process.exit(1) is
never executed; update each relevant test to advance timers (e.g.,
vi.advanceTimersByTime(100) or vi.runAllTimers()) after invoking
handleRunError(), then assert that the mocked process.exit was called with 1,
and restore any spies/mocks.
- Introduced a new docker-compose.local.yml file for local development, enabling SSH tunneling for Redmine and MongoDB services. - Updated README.md to include instructions for using the new local development configuration, clarifying the usage of different docker-compose files for various environments. These changes enhance the development workflow by providing a dedicated configuration for local setups.
- Implemented fake timers using vi.useFakeTimers() to control setTimeout behavior during tests. - Restored real timers and cleared pending timers in afterEach to ensure a clean test environment. These changes improve the reliability of tests by preventing unintended delays and ensuring proper timer management.
f629b57 to
8b253f4
Compare
|
1 similar comment
|



These changes enhance the development workflow by providing a dedicated configuration for local setups.
Summary by CodeRabbit
New Features
Documentation
Tests