You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Docker Compose的Lizmap服务器配置优化及防火墙问题咨询

问题

我从Git仓库拿到测试环境用的yaml配置,想部署生产环境的Lizmap。我调整了端口配置:把原配置的127.0.0.1:8090:8080改成8090:80,PostGIS容器端口改成5432:5432,现在外部能正常访问,但不确定配置是否足够适配生产环境,想知道优化方向。另外遇到防火墙问题:不管有没有添加5432和8090的规则,这些端口始终处于开放状态,求解答。

当前使用的docker-compose.yml配置如下:

version: '3.9'
services:
  lizmap:
    image: 3liz/lizmap-web-client:${LIZMAP_VERSION_TAG}
    environment:
      LIZMAP_CACHEREDISDB: '1'
      LIZMAP_CACHEREDISHOST: redis
      LIZMAP_CACHESTORAGETYPE: redis
      LIZMAP_HOME: /srv/lizmap
      LIZMAP_USER: ${LIZMAP_UID}
      LIZMAP_WMSSERVERURL: http://map:8080/ows/
      LIZMAP_CONFIG_INCLUDE: /srv/etc
      PGSERVICEFILE: /srv/etc/pg_service.conf
      PGPASSFILE: /srv/etc/pgpass.conf
    volumes:
      - { type: bind, source: "${LIZMAP_PROJECTS}", target: /srv/projects }
      - { type: bind, source: "${LIZMAP_DIR}/var/lizmap-theme-config", target: /www/lizmap/var/lizmap-theme-config }
      - { type: bind, source: "${LIZMAP_DIR}/var/lizmap-config", target: /www/lizmap/var/config }
      - { type: bind, source: "${LIZMAP_DIR}/var/lizmap-db",     target: /www/lizmap/var/db }
      - { type: bind, source: "${LIZMAP_DIR}/www", target: /www/lizmap/www }
      - { type: bind, source: "${LIZMAP_DIR}/www/var/log", target: /www/lizmap/var/log }
      - { type: bind, source: "${LIZMAP_DIR}/var/lizmap-modules", target: /www/lizmap/lizmap-modules }
      - { type: bind, source: "${LIZMAP_DIR}/var/lizmap-my-packages", target: /www/lizmap/my-packages }
      - { type: bind, source: "${LIZMAP_DIR}/etc", target: /srv/etc, read_only: true }
    command:
      - php-fpm
    depends_on:
      postgis:
        condition: service_healthy
    restart: unless-stopped
  map:
    image: 3liz/qgis-map-server:${QGIS_VERSION_TAG}
    environment:
      PGSERVICEFILE: /srv/etc/pg_service.conf
      PGSPASSFILE: /srv/etc/pgpass.conf
      QGIS_OPTIONS_PATH: /srv/etc/qgis
      QGIS_SERVER_LIZMAP_REVEAL_SETTINGS: 'yes'
      QGSRV_API_ENABLED_LIZMAP: 'yes'
      QGSRV_CACHE_SIZE: '20'
      QGSRV_CACHE_STRICT_CHECK: 'no'
      QGSRV_CACHE_ROOTDIR: /srv/projects
      QGSRV_LOGGING_LEVEL: DEBUG
      QGSRV_USER: ${LIZMAP_UID}:${LIZMAP_GID}
      QGSRV_SERVER_PLUGINPATH: /srv/plugins
      QGSRV_SERVER_RESTARTMON: /srv/.qgis-restart
      QGSRV_SERVER_WORKERS: ${QGIS_MAP_WORKERS}
    volumes:
      - { type: bind, source: "${LIZMAP_PROJECTS}", target: /srv/projects }
      - { type: bind, source: "${LIZMAP_DIR}/plugins", target: /srv/plugins }
      - { type: bind, source: "${LIZMAP_DIR}/wps-data", target: /srv/data }
      - { type: bind, source: "${LIZMAP_DIR}/etc", target: /srv/etc, read_only: true }
    ports:
      - ${OWS_PORT}:8080
    restart: unless-stopped
  redis:
    image: redis:5-alpine
    volumes:
      - { type: volume, source: redis_data, target: /data }
  web:
    image: nginx:alpine
    user: ${LIZMAP_UID}:${LIZMAP_GID}
    volumes:
      - { type: bind, source: "${LIZMAP_DIR}/etc/nginx.conf", target: /etc/nginx/nginx.conf }
      - { type: bind, source: "${LIZMAP_DIR}/var/log/nginx", target: /var/log/nginx }
      - { type: bind, source: "${LIZMAP_DIR}/var/nginx-cache", target: /var/cache/nginx }
      - { type: bind, source: "${LIZMAP_DIR}", target: /srv/lizmap }
    ports:
      - ${LIZMAP_PORT}:8080
    depends_on:
      - lizmap
  postgis:
    image: 3liz/postgis:${POSTGIS_VERSION}
    volumes:
      - { type: volume, source: postgis_data, target: /var/lib/postgresql/data }
      - { type: bind, source: "${LIZMAP_DIR}/etc/postgres.init.d", target: /docker-entrypoint-initdb.d }
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_LIZMAP_DB: ${POSTGRES_LIZMAP_DB}
      POSTGRES_LIZMAP_USER: ${POSTGRES_LIZMAP_USER}
      POSTGRES_LIZMAP_PASSWORD: ${POSTGRES_LIZMAP_PASSWORD}
    ports:
      - ${POSTGIS_PORT}:5432
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres -d ${POSTGRES_LIZMAP_DB} -q || exit 1"]
      interval: 10s
      timeout: 5s
      start_period: 60s
    networks:
      default:
        aliases:
          - ${POSTGIS_ALIAS}

volumes:
    postgis_data:
        driver: local
    redis_data:
        driver: local

生产环境优化方案

1. 端口与网络安全

  • 关闭不必要的对外端口:当前map服务的${OWS_PORT}:8080和postgis的5432:5432都对外暴露,生产环境下这两个服务仅需通过Docker内部网络和其他服务通信,直接删除这两个服务的ports配置即可。仅保留web(NGINX)服务的对外端口,确保用户只能通过NGINX访问Lizmap。
  • 绑定特定公网IP:如果服务器有多网卡,将web服务的端口绑定到指定公网IP,比如ports: - 1.2.3.4:8090:8080,避免监听所有IP带来的安全风险。

2. 日志与调试

  • 调整日志级别:map服务的QGSRV_LOGGING_LEVEL设为DEBUG,生产环境建议改为INFO或WARNING,减少日志输出量,降低磁盘占用和敏感信息泄露风险。
  • 配置日志轮转:给所有服务的日志目录配置日志轮转规则(比如NGINX用logrotate),防止日志文件无限增长。

3. 性能优化

  • 升级Redis版本:当前使用redis:5-alpine,建议升级到稳定新版本(如redis:7-alpine),获得更好的性能和安全性。
  • 调整QGIS Worker数量:根据服务器CPU核心数设置QGSRV_SERVER_WORKERS,一般为核心数的1-2倍,避免资源浪费或过载。
  • 优化NGINX缓存:检查nginx.conf中的缓存配置,针对静态资源(地图瓦片、CSS/JS)设置合理的缓存大小和过期时间,提升访问速度。

4. 安全性增强

  • 添加Redis认证密码:当前Redis无密码,生产环境必须添加。修改redis服务配置:
    redis:
      image: redis:7-alpine
      command: redis-server --requirepass ${REDIS_PASSWORD}
      volumes:
        - { type: volume, source: redis_data, target: /data }
    
    同时在lizmap服务的环境变量中添加LIZMAP_CACHEREDISPASSWORD: ${REDIS_PASSWORD}。
  • 启用HTTPS:生产环境必须配置HTTPS,修改NGINX配置添加SSL证书(可使用Let's Encrypt免费证书),将80端口重定向到443端口。
  • 锁定镜像版本:确保LIZMAP_VERSION_TAG、QGIS_VERSION_TAG、POSTGIS_VERSION为具体稳定版本号(如3.6.0),避免自动更新导致兼容性问题。
  • 限制容器用户权限:确保LIZMAP_UID和LIZMAP_GID对应的宿主机用户权限最小化,避免容器内用户拥有过高宿主机权限。

5. 可靠性配置

  • 添加资源限制:给每个服务配置CPU和内存使用限制,防止单个服务耗尽服务器资源,示例:
    lizmap:
      # 其他配置不变
      deploy:
        resources:
          limits:
            cpus: '2.0'
            memory: 2G
          reservations:
            cpus: '0.5'
            memory: 512M
    
  • 添加健康检查:给lizmap、web服务补充健康检查,确保服务异常时自动重启,示例:
    web:
      # 其他配置不变
      healthcheck:
        test: ["CMD-SHELL", "curl -f http://localhost:8080/ || exit 1"]
        interval: 30s
        timeout: 10s
        retries: 3
    

防火墙端口问题解答

  • 原因:Docker启动容器时会自动通过iptables添加端口转发规则,这些规则优先级高于系统防火墙(如ufw、firewalld)的规则,所以即使你没在系统防火墙添加规则,Docker已经通过iptables开放了端口。另外如果系统防火墙未启动,端口也会处于开放状态。
  • 解决方法:
    1. 禁止Docker自动修改iptables:在Docker配置文件/etc/docker/daemon.json中添加:
      {
        "iptables": false
      }
      
      重启Docker服务:systemctl restart docker,之后系统防火墙规则会生效。注意此操作可能影响容器间通信,需手动配置iptables规则允许容器内部网络交互。
    2. 关闭不必要的端口暴露:直接删除map和postgis服务的ports配置,仅保留web服务的对外端口,即使Docker自动开放端口,也只有必要端口对外可见。
    3. 检查防火墙状态:执行ufw status或firewall-cmd --state确认系统防火墙是否正常运行,若未启动则启动防火墙服务。

内容的提问来源于stack exchange,提问作者JAY EFFE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 16:49:58