The error occurs because the map
directive in Nginx has specific placement requirements. Unlike regular directives that can appear in various contexts, map
can only be placed within the http
context in your main configuration file.
# Correct placement example:
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
# Other http context configurations
}
In your current setup, you've placed the map
block directly in your site configuration file (/etc/nginx/sites-enabled/app
), outside of any context. Nginx's parser rejects this because:
- The
map
directive is context-sensitive - It must be declared before any server blocks that reference its variables
- It cannot be nested inside other blocks except
http
For the cleanest implementation, move the map
block to either:
# Option 1: Main nginx.conf (recommended)
http {
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
include /etc/nginx/sites-enabled/*;
}
Or alternatively create a separate config file in /etc/nginx/conf.d/
:
# Option 2: Separate include file (/etc/nginx/conf.d/websocket.conf)
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
Here's how your final configuration should look for a Meteor deployment:
# In /etc/nginx/nginx.conf
http {
# WebSocket mapping
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
include /etc/nginx/sites-enabled/*;
}
# In /etc/nginx/sites-enabled/app
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
location = /favicon.ico {
root /home/USERNAME/portal/programs/web.browser/app;
access_log off;
}
location ~* "^/[a-z0-9]{40}\.(css|js)$" {
gzip_static on;
root /home/USERNAME/portal/programs/web.browser;
access_log off;
}
location ~ "^/packages" {
root /home/USERNAME/portal/programs/web.browser;
access_log off;
}
location / {
proxy_pass http://127.0.0.1:8080;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
}
}
After making these changes, always verify your configuration:
sudo nginx -t
sudo systemctl reload nginx
Test WebSocket functionality by checking the Connection
and Upgrade
headers in your browser's developer tools.
For production environments, consider these enhancements:
- Add SSL/TLS configuration
- Implement proper caching headers
- Set up load balancing if scaling horizontally
- Configure proper timeouts for WebSocket connections
When deploying Meteor applications with Nginx, developers often need to configure WebSocket support through a map
directive. The error occurs because the map
block is incorrectly placed in the server configuration file rather than the HTTP context.
The map
directive must be placed in the http
context of your Nginx configuration. Here's the proper structure:
http {
# WebSocket mapping goes here at http level
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
include /etc/nginx/sites-enabled/*;
}
For your specific case, you should modify the files as follows:
In /etc/nginx/nginx.conf
:
http {
# ... existing http configuration ...
# Add map directive here
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
include /etc/nginx/sites-enabled/*;
}
And in your site configuration (/etc/nginx/sites-enabled/app
):
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
location = /favicon.ico {
root /home/USERNAME/portal/programs/web.browser/app;
access_log off;
}
# ... other location blocks ...
}
After making these changes:
sudo nginx -t
sudo systemctl reload nginx
1. Double-check for duplicate include
statements in your nginx.conf
2. Ensure no conflicting map
directives exist in other included files
3. Watch for syntax errors in the modified files
For production environments, consider adding these optimizations:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream meteor_server {
server 127.0.0.1:8080;
keepalive 64;
}
server {
# ... existing server config ...
location / {
proxy_pass http://meteor_server;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}