Refactor nginx setup to use host-level configuration
- Remove main nginx ingress container from docker-compose - Add minimal api-nginx container for FastCGI to HTTP conversion - Expose services directly on ports 7654 (API) and 7655 (UI) - Add comprehensive NGINX_SETUP.md documentation - Include example host nginx configuration - Update docker setup script for new architecture This change allows OpnForm to integrate better with existing host nginx setups by removing the containerized ingress and exposing services directly to the host for reverse proxy configuration.
This commit is contained in:
parent
a11fb01bef
commit
3a8e601a37
|
|
@ -0,0 +1,131 @@
|
|||
# OpnForm Nginx Setup Guide
|
||||
|
||||
This guide explains how to set up OpnForm with a host-level nginx configuration.
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
The modified setup removes the main nginx ingress container and exposes services directly:
|
||||
|
||||
- **UI Service**: Exposed on port 7655 (HTTP)
|
||||
- **API Service**: Exposed on port 7654 (HTTP via minimal nginx container)
|
||||
- **Database**: PostgreSQL (internal only)
|
||||
- **Redis**: Cache service (internal only)
|
||||
|
||||
## Key Changes from Default Setup
|
||||
|
||||
1. **Removed YAML anchors** - Each container now has its own explicit configuration to avoid conflicts
|
||||
2. **Removed main ingress container** - Your host nginx handles all routing
|
||||
3. **Added minimal api-nginx** - Small nginx container just to convert FastCGI to HTTP for the API
|
||||
4. **Custom ports** - Using 7654-7655 range to avoid conflicts
|
||||
|
||||
## Setup Steps
|
||||
|
||||
### 1. Stop any existing containers
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
docker compose -f docker-compose.dev.yml down
|
||||
```
|
||||
|
||||
### 2. Run the setup script
|
||||
|
||||
```bash
|
||||
./scripts/docker-setup.sh
|
||||
```
|
||||
|
||||
### 3. Verify services are running
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
```
|
||||
|
||||
You should see:
|
||||
- opnform-api (healthy)
|
||||
- opnform-api-nginx (healthy)
|
||||
- opnform-api-worker (running)
|
||||
- opnform-api-scheduler (running)
|
||||
- opnform-client (healthy)
|
||||
- opnform-redis (healthy)
|
||||
- opnform-db (healthy)
|
||||
|
||||
### 4. Configure your host nginx
|
||||
|
||||
Copy the example configuration:
|
||||
|
||||
```bash
|
||||
sudo cp nginx-host-example.conf /etc/nginx/sites-available/forms.portnimara.dev
|
||||
sudo ln -s /etc/nginx/sites-available/forms.portnimara.dev /etc/nginx/sites-enabled/
|
||||
```
|
||||
|
||||
Edit the file to adjust:
|
||||
- SSL certificate paths
|
||||
- Server name if different
|
||||
- Any other site-specific settings
|
||||
|
||||
### 5. Test nginx configuration
|
||||
|
||||
```bash
|
||||
sudo nginx -t
|
||||
```
|
||||
|
||||
### 6. Reload nginx
|
||||
|
||||
```bash
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Port already in use
|
||||
|
||||
If you get "port already allocated" errors:
|
||||
|
||||
1. Check what's using the ports:
|
||||
```bash
|
||||
sudo lsof -i :7654
|
||||
sudo lsof -i :7655
|
||||
```
|
||||
|
||||
2. Stop conflicting services or change the ports in docker-compose.yml
|
||||
|
||||
### API not responding
|
||||
|
||||
1. Check the api-nginx logs:
|
||||
```bash
|
||||
docker logs opnform-api-nginx
|
||||
```
|
||||
|
||||
2. Verify the API container is running:
|
||||
```bash
|
||||
docker logs opnform-api
|
||||
```
|
||||
|
||||
### UI not loading
|
||||
|
||||
1. Check the client logs:
|
||||
```bash
|
||||
docker logs opnform-client
|
||||
```
|
||||
|
||||
2. Ensure the client/.env file has correct API URL settings
|
||||
|
||||
## Port Reference
|
||||
|
||||
- **7654**: API (HTTP) - proxied through api-nginx to PHP-FPM
|
||||
- **7655**: UI (HTTP) - Nuxt.js frontend
|
||||
- **9000**: PHP-FPM (internal only, FastCGI protocol)
|
||||
- **5432**: PostgreSQL (internal only)
|
||||
- **6379**: Redis (internal only)
|
||||
|
||||
## Security Notes
|
||||
|
||||
1. Ports are bound to 127.0.0.1 only, not exposed to external network
|
||||
2. All traffic should go through your host nginx with SSL
|
||||
3. The minimal api-nginx container only handles FastCGI conversion, no SSL termination
|
||||
|
||||
## Default Credentials
|
||||
|
||||
- Email: admin@opnform.com
|
||||
- Password: password
|
||||
|
||||
**Important**: Change these immediately after first login!
|
||||
|
|
@ -1,11 +1,10 @@
|
|||
---
|
||||
services:
|
||||
api: &api-environment
|
||||
api:
|
||||
image: jhumanj/opnform-api:latest
|
||||
container_name: opnform-api
|
||||
volumes: &api-environment-volumes
|
||||
volumes:
|
||||
- opnform_storage:/usr/share/nginx/html/storage:rw
|
||||
environment: &api-env
|
||||
environment:
|
||||
APP_ENV: production
|
||||
# Database settings
|
||||
DB_HOST: db
|
||||
|
|
@ -25,7 +24,7 @@ services:
|
|||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy # Depend on redis being healthy too
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "php /usr/share/nginx/html/artisan about || exit 1"]
|
||||
interval: 30s
|
||||
|
|
@ -33,13 +32,49 @@ services:
|
|||
retries: 3
|
||||
start_period: 60s
|
||||
|
||||
api-nginx:
|
||||
image: nginx:alpine
|
||||
container_name: opnform-api-nginx
|
||||
volumes:
|
||||
- ./docker/api-nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
- opnform_storage:/usr/share/nginx/html/storage:ro
|
||||
ports:
|
||||
- "127.0.0.1:7654:80" # API on port 7654
|
||||
depends_on:
|
||||
- api
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "wget --spider -q http://localhost/ || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
api-worker:
|
||||
<<: *api-environment
|
||||
image: jhumanj/opnform-api:latest
|
||||
container_name: opnform-api-worker
|
||||
command: ["php", "artisan", "queue:work"]
|
||||
volumes:
|
||||
- opnform_storage:/usr/share/nginx/html/storage:rw
|
||||
environment:
|
||||
<<: *api-env
|
||||
APP_ENV: production
|
||||
# Database settings
|
||||
DB_HOST: db
|
||||
REDIS_HOST: redis
|
||||
DB_DATABASE: ${DB_DATABASE:-forge}
|
||||
DB_USERNAME: ${DB_USERNAME:-forge}
|
||||
DB_PASSWORD: ${DB_PASSWORD:-forge}
|
||||
DB_CONNECTION: ${DB_CONNECTION:-pgsql}
|
||||
# PHP Configuration
|
||||
PHP_MEMORY_LIMIT: "1G"
|
||||
PHP_MAX_EXECUTION_TIME: "600"
|
||||
PHP_UPLOAD_MAX_FILESIZE: "64M"
|
||||
PHP_POST_MAX_SIZE: "64M"
|
||||
env_file:
|
||||
- ./api/.env
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "pgrep -f 'php artisan queue:work' > /dev/null || exit 1"]
|
||||
interval: 60s
|
||||
|
|
@ -48,22 +83,44 @@ services:
|
|||
start_period: 30s
|
||||
|
||||
api-scheduler:
|
||||
<<: *api-environment
|
||||
image: jhumanj/opnform-api:latest
|
||||
container_name: opnform-api-scheduler
|
||||
command: ["php", "artisan", "schedule:work"]
|
||||
volumes:
|
||||
- opnform_storage:/usr/share/nginx/html/storage:rw
|
||||
environment:
|
||||
<<: *api-env
|
||||
APP_ENV: production
|
||||
# Database settings
|
||||
DB_HOST: db
|
||||
REDIS_HOST: redis
|
||||
DB_DATABASE: ${DB_DATABASE:-forge}
|
||||
DB_USERNAME: ${DB_USERNAME:-forge}
|
||||
DB_PASSWORD: ${DB_PASSWORD:-forge}
|
||||
DB_CONNECTION: ${DB_CONNECTION:-pgsql}
|
||||
# PHP Configuration
|
||||
PHP_MEMORY_LIMIT: "1G"
|
||||
PHP_MAX_EXECUTION_TIME: "600"
|
||||
PHP_UPLOAD_MAX_FILESIZE: "64M"
|
||||
PHP_POST_MAX_SIZE: "64M"
|
||||
env_file:
|
||||
- ./api/.env
|
||||
depends_on:
|
||||
db:
|
||||
condition: service_healthy
|
||||
redis:
|
||||
condition: service_healthy
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "php /usr/share/nginx/html/artisan app:scheduler-status --mode=check --max-minutes=3 || exit 1"]
|
||||
interval: 60s
|
||||
timeout: 30s
|
||||
retries: 3
|
||||
start_period: 70s # Allow time for first scheduled run and cache write
|
||||
start_period: 70s
|
||||
|
||||
ui:
|
||||
image: jhumanj/opnform-client:latest
|
||||
container_name: opnform-client
|
||||
ports:
|
||||
- "127.0.0.1:7655:3000" # UI on port 7655
|
||||
env_file:
|
||||
- ./client/.env
|
||||
healthcheck:
|
||||
|
|
@ -95,27 +152,6 @@ services:
|
|||
volumes:
|
||||
- postgres-data:/var/lib/postgresql/data
|
||||
|
||||
ingress:
|
||||
image: nginx:1
|
||||
container_name: opnform-ingress
|
||||
volumes:
|
||||
- ./docker/nginx.conf:/etc/nginx/templates/default.conf.template
|
||||
ports:
|
||||
- 80:80
|
||||
environment:
|
||||
- NGINX_MAX_BODY_SIZE=64m
|
||||
depends_on:
|
||||
api:
|
||||
condition: service_started
|
||||
ui:
|
||||
condition: service_started
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "nginx -t && curl -f http://localhost/ || exit 1"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
|
||||
volumes:
|
||||
postgres-data:
|
||||
opnform_storage:
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
default_type application/octet-stream;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name _;
|
||||
root /usr/share/nginx/html/public;
|
||||
index index.php;
|
||||
|
||||
client_max_body_size 64M;
|
||||
|
||||
# Logging
|
||||
access_log /dev/stdout;
|
||||
error_log /dev/stderr;
|
||||
|
||||
# Handle all requests through PHP
|
||||
location / {
|
||||
try_files $uri $uri/ /index.php$is_args$args;
|
||||
}
|
||||
|
||||
# PHP-FPM configuration
|
||||
location ~ \.php$ {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
fastcgi_pass opnform-api:9000;
|
||||
fastcgi_index index.php;
|
||||
include fastcgi_params;
|
||||
fastcgi_param SCRIPT_FILENAME /usr/share/nginx/html/public/index.php;
|
||||
fastcgi_param DOCUMENT_ROOT /usr/share/nginx/html/public;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
fastcgi_read_timeout 300;
|
||||
}
|
||||
|
||||
# Deny access to . files
|
||||
location ~ /\. {
|
||||
deny all;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
# Example nginx configuration for forms.portnimara.dev
|
||||
# Place this in /etc/nginx/sites-available/forms.portnimara.dev
|
||||
# Then create a symlink: ln -s /etc/nginx/sites-available/forms.portnimara.dev /etc/nginx/sites-enabled/
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name forms.portnimara.dev;
|
||||
|
||||
# Redirect HTTP to HTTPS
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name forms.portnimara.dev;
|
||||
|
||||
# SSL certificates - adjust paths as needed
|
||||
ssl_certificate /etc/letsencrypt/live/forms.portnimara.dev/fullchain.pem;
|
||||
ssl_certificate_key /etc/letsencrypt/live/forms.portnimara.dev/privkey.pem;
|
||||
|
||||
# SSL configuration
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
# Client upload size
|
||||
client_max_body_size 64M;
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/forms.portnimara.dev.access.log;
|
||||
error_log /var/log/nginx/forms.portnimara.dev.error.log;
|
||||
|
||||
# API routes - proxy to the api-nginx container
|
||||
location ~ ^/(api|open|local/temp|forms/assets)/ {
|
||||
proxy_pass http://127.0.0.1:7654;
|
||||
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;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_connect_timeout 75s;
|
||||
}
|
||||
|
||||
# Everything else goes to the UI container
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:7655;
|
||||
proxy_http_version 1.1;
|
||||
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;
|
||||
proxy_set_header X-Forwarded-Host $host;
|
||||
proxy_set_header X-Forwarded-Port $server_port;
|
||||
|
||||
# WebSocket support for hot reload and real-time features
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_cache_bypass $http_upgrade;
|
||||
}
|
||||
|
||||
# Security headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
}
|
||||
|
|
@ -63,7 +63,10 @@ if [ "$DEV_MODE" = true ]; then
|
|||
else
|
||||
echo -e "${BLUE}Production environment setup complete!${NC}"
|
||||
echo -e "${YELLOW}Please wait a moment for all services to start${NC}"
|
||||
echo -e "${GREEN}Then visit: http://localhost${NC}"
|
||||
echo -e "${GREEN}Services are available on:${NC}"
|
||||
echo -e "${GREEN}- UI: http://localhost:7655${NC}"
|
||||
echo -e "${GREEN}- API: http://localhost:7654${NC}"
|
||||
echo -e "${YELLOW}Note: Configure your host nginx to proxy to these ports${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${BLUE}Default admin credentials:${NC}"
|
||||
|
|
|
|||
Loading…
Reference in New Issue