diff --git a/doc/source/install/include/configure-ironic-api-mod_wsgi.inc b/doc/source/install/include/configure-ironic-api-mod_wsgi.inc deleted file mode 100644 index 7249e97aea..0000000000 --- a/doc/source/install/include/configure-ironic-api-mod_wsgi.inc +++ /dev/null @@ -1,94 +0,0 @@ -Configuring ironic-api behind mod_wsgi --------------------------------------- - -Bare Metal service comes with an example file for configuring the -``ironic-api`` service to run behind Apache with mod_wsgi. - -.. note:: - This is optional, the ironic APIs can be run using - independent scripts that provide HTTP servers. But it is generally - considered more performant and flexible to run them using a generic - HTTP server that supports WSGI (such as Apache or nginx). - -#. Install the apache service: - - Fedora/RHEL9/CentOS 9:: - - sudo dnf install httpd - - Debian/Ubuntu:: - - apt-get install apache2 - -#. Download the ``etc/apache2/ironic`` file from the - `Ironic project tree `_ - and copy it to the apache sites: - - Fedora/RHEL9/CentOS 9:: - - sudo cp etc/apache2/ironic /etc/httpd/conf.d/ironic.conf - - Debian/Ubuntu:: - - sudo cp etc/apache2/ironic /etc/apache2/sites-available/ironic.conf - -#. Edit the recently copied ``/ironic.conf``: - - #. Modify the ``WSGIDaemonProcess``, ``APACHE_RUN_USER`` and - ``APACHE_RUN_GROUP`` directives to set the user and group values to - an appropriate user on your server. - - #. Modify the ``WSGIScriptAlias`` directive to point to the automatically - generated ``ironic-api-wsgi`` script that is located in `IRONIC_BIN` - directory. - - #. Modify the ``Directory`` directive to set the path to the Ironic API code. - - #. Modify the ``ErrorLog`` and ``CustomLog`` to redirect the logs - to the right directory (on Red Hat systems this is usually under - /var/log/httpd). - -#. Stop and disable the ironic-api service. If ironic-api service is - started, the port will be occupied. Apache will fail to start: - - Fedora/RHEL9/CentOS 9:: - - sudo systemctl stop openstack-ironic-api - sudo systemctl disable openstack-ironic-api - - Debian/Ubuntu:: - - sudo service ironic-api stop - sudo service ironic-api disable - -#. Enable the apache ``ironic`` in site and reload: - - Fedora/RHEL9/CentOS 9:: - - sudo systemctl reload httpd - - Debian/Ubuntu:: - - sudo a2ensite ironic - sudo service apache2 reload - -.. note:: - The file ``ironic-api-wsgi`` is automatically generated by pbr and is - available in `IRONIC_BIN` directory. It should not be modified. - -Configure another WSGI container --------------------------------- - -A slightly different approach has to be used for WSGI containers that cannot -use ``ironic-api-wsgi``. For example, for *gunicorn*: - -.. code-block:: console - - gunicorn -b 0.0.0.0:6385 'ironic.api.wsgi:initialize_wsgi_app(argv=[])' - -If you want to pass a configuration file, use: - -.. code-block:: console - - gunicorn -b 0.0.0.0:6385 \ - 'ironic.api.wsgi:initialize_wsgi_app(argv=["ironic-api", "--config-file=/path/to/_ironic.conf"])' diff --git a/doc/source/install/include/configure-ironic-api-wsgi.inc b/doc/source/install/include/configure-ironic-api-wsgi.inc new file mode 100644 index 0000000000..a248ee9fc1 --- /dev/null +++ b/doc/source/install/include/configure-ironic-api-wsgi.inc @@ -0,0 +1,116 @@ +Configuring ironic-api behind a WSGI server +-------------------------------------------- + +Bare Metal service can be configured to run behind any WSGI-capable +web server like uWSGI or Gunicorn for better performance and scalability. + +.. note:: + This is optional, the ironic APIs can be run using + the standalone ``ironic-api`` command. However, for production deployments, + it is recommended to use a proper WSGI server for better performance, + multiple workers, and integration with existing infrastructure. + +The WSGI application +~~~~~~~~~~~~~~~~~~~~ + +Ironic provides a WSGI application at ``ironic.wsgi:application`` that can +be used with any WSGI server. The below example uses uWSGI, which is used in +Ironic CI jobs. + +Using uWSGI +~~~~~~~~~~~ + +#. Install uWSGI:: + + pip install uwsgi + +#. Create a uWSGI configuration file (e.g., ``/etc/uwsgi/ironic.ini``):: + + [uwsgi] + module = ironic.wsgi:application + http-socket = 127.0.0.1:6385 + processes = 2 + ; allow 60 seconds for graceful shutdown on SIGTERM + die-on-term = true + exit-on-reload = false + hook-master-start = unix_signal:15 gracefully_kill_them_all + worker-reload-mercy = 60 + ; disallow connection reuse + add-header = Connection: close + ; Prevent thundering herd on accept() + thunder-lock = true + ; ensure file descriptors aren't shared between processes + lazy-apps = true + enable-threads = true + master = true + +.. note:: + This uWSGI configuration and comments are based on devstack configuration. + You may need to modify settings depending on your deployment method and + scale. + + +#. Start uWSGI:: + + uwsgi --ini /etc/uwsgi/ironic.ini + +Reverse Proxy Configuration +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +WSGI servers are typically deployed behind a reverse proxy like nginx or +Apache for SSL termination, load balancing, and serving static files. + +Example nginx configuration:: + + upstream ironic-api { + server 127.0.0.1:6385; + } + + server { + listen 443 ssl; + server_name ironic.example.com; + + ssl_certificate /etc/ssl/certs/ironic.crt; + ssl_certificate_key /etc/ssl/private/ironic.key; + + location / { + proxy_pass http://ironic-api; + 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; + } + } + +For detailed reverse proxy configurations, see: + +* `nginx documentation `_ +* `Apache mod_proxy documentation `_ +* `HAProxy documentation `_ + +Passing Configuration Options +------------------------------ + +By default, Ironic will use its standard configuration file search paths. +If you need to specify a custom configuration file: + +For the initialization method with arguments:: + + # uWSGI with custom config (in ini file) + [uwsgi] + module = ironic.api.wsgi:initialize_wsgi_app(argv=["--config-file=/etc/ironic/ironic.conf"]) + +Alternatively, you can set environment variables before starting the WSGI server:: + + export OS_CLOUD=mycloud + # or + export IRONIC_CONF=/etc/ironic/ironic.conf + +Important Considerations +~~~~~~~~~~~~~~~~~~~~~~~~ + +#. Stop and disable the standalone ironic-api service before starting + the WSGI server to avoid port conflicts. + +#. When behind a reverse proxy, ensure ``[oslo_middleware]/enable_proxy_headers_parsing`` + is set to ``True`` in ironic.conf to properly handle X-Forwarded headers. diff --git a/doc/source/install/install.rst b/doc/source/install/install.rst index a3125caf36..602ad3b488 100644 --- a/doc/source/install/install.rst +++ b/doc/source/install/install.rst @@ -58,7 +58,7 @@ On Ubuntu_/Debian: .. include:: include/configure-ironic-api.inc -.. include:: include/configure-ironic-api-mod_wsgi.inc +.. include:: include/configure-ironic-api-wsgi.inc .. include:: include/configure-ironic-conductor.inc diff --git a/etc/apache2/ironic b/etc/apache2/ironic deleted file mode 100644 index c1640393b7..0000000000 --- a/etc/apache2/ironic +++ /dev/null @@ -1,38 +0,0 @@ -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# This is an example Apache2 configuration file for using the -# Ironic API through mod_wsgi. This version assumes you are -# running devstack to configure the software, and PBR has generated -# and installed the ironic-api-wsgi script while installing ironic. - -Listen 6385 - - - WSGIDaemonProcess ironic user=stack group=stack threads=10 display-name=%{GROUP} - WSGIScriptAlias / /usr/local/bin/ironic-api-wsgi - - SetEnv APACHE_RUN_USER stack - SetEnv APACHE_RUN_GROUP stack - WSGIProcessGroup ironic - - ErrorLog /var/log/apache2/ironic_error.log - LogLevel info - CustomLog /var/log/apache2/ironic_access.log combined - - - WSGIProcessGroup ironic - WSGIApplicationGroup %{GLOBAL} - AllowOverride All - Require all granted - - diff --git a/releasenotes/notes/migrate-wsgi-script-to-module-4113e87f202eecab.yaml b/releasenotes/notes/migrate-wsgi-script-to-module-4113e87f202eecab.yaml new file mode 100644 index 0000000000..2795967f16 --- /dev/null +++ b/releasenotes/notes/migrate-wsgi-script-to-module-4113e87f202eecab.yaml @@ -0,0 +1,27 @@ +--- +upgrade: + - | + The ``wsgi_scripts`` entry point ``ironic-api-wsgi`` has been removed + from ``setup.cfg``. WSGI servers should now use the module path + ``ironic.wsgi:application`` directly instead of the generated script. + This change aligns with the OpenStack goal to migrate from WSGI scripts + to module paths and is compatible with modern Python packaging tools. + + For example, with gunicorn:: + + gunicorn ironic.wsgi:application + + Or with uwsgi:: + + [uwsgi] + module = ironic.wsgi:application + - | + The Apache mod_wsgi sample configuration has been removed. Operators + should use modern WSGI servers like uWSGI or Gunicorn instead, which + provide better performance and are simpler to configure. See the + updated deployment documentation for examples. +deprecations: + - | + While the legacy ``ironic.api.wsgi:initialize_wsgi_app()`` function + remains available for backward compatibility, new deployments should + use ``ironic.wsgi:application`` instead. \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index a2ff893fde..29c3decfc1 100644 --- a/setup.cfg +++ b/setup.cfg @@ -48,9 +48,6 @@ console_scripts = ironic-status = ironic.command.status:main ironic-pxe-filter = ironic.command.pxe_filter:main -wsgi_scripts = - ironic-api-wsgi = ironic.api.wsgi:initialize_wsgi_app - ironic.dhcp = dnsmasq = ironic.dhcp.dnsmasq:DnsmasqDHCPApi neutron = ironic.dhcp.neutron:NeutronDHCPApi