1. Pre-Preparation
- Open ports 80, 443, 5000 (🪟 > Windows Defender Firewall with Advanced Security > Inbound Rules > New Rules …
- Install Microsoft C++ Build Tools, Please refer to https://github.com/bycloudai/InstallVSBuildToolsWindows for detail. Windows 11 SDK is pretty large yet is still needed.
- Install Microsoft Visual C++ Redistributable (Maybe not needed if the above step has already finished doing so)
2. Install & Test Run Apache
- Dowload Apache from Apache 2.4 VS17 Windows Binaries and Modules, Unzip the file you will find a ReadMe.txt, on it will be the instructions about how to install it.
- After copying files over to C:/Apache24, open a CMD terminal as Administrator.
cd C:\Apache24\bin httpd.exe # Test your installation open address http://localhost at local and open address http://[ip address] at remote. You can shut down Apache by pressing Ctrl+C (It may take a few seconds). httpd.exe -k install httpd.exe -k start httpd.exe -k stop httpd.exe -k restart
- Restart the computer and test the server local and remote again. Make sure it’s
http://[ip address] not https://[ip_address]
.
E: (OS 10048)Only one usage of each socket address (protocol/network address/port) is normally permitted. :
AH00072: make_sock: could not bind to address [::]:80
(OS 10048)Only one usage of each socket address (protocol/network address/port) is normally permitted. :
AH00072: make_sock: could not bind to address 0.0.0.0:80
AH00451: no listening sockets available, shutting down
AH00015: Unable to open logsnetstat -aon | findstr :80 TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 2660 TCP [::]:80 [::]:0 LISTENING 2660 taskkill /PID 2660 /F SUCCESS: The process with PID 2660 has been terminated.
3. Install Python, MySQL, etc
python -m venv venv
venv\Scripts\activate
pip install -r requirements.txt
# Test flask test server local and remote on port 5000
pip install mod_wsgi
mod_wsgi-express module-config
LoadFile "C:/Users/Developer/AppData/Local/Programs/Python/Python312/python312.dll"
LoadModule wsgi_module "C:/flask_blog/venv/Lib/site-packages/mod_wsgi/server/mod_wsgi.cp312-win_amd64.pyd"
WSGIPythonHome "C:/flask_blog/venv"
4. Copy the flask application into server and here is the project structure
C:\flask_blog\
+-- flaskblog
| +-- __init__.py
+-- deploy
| +-- flaskblog.wsgi
+-- logs
+-- venv
+-- requirements.txt
+-- run.py
+-- flaskblog.conf
flaskblog.wsgi
import sys
sys.path.insert(0, 'C:\\flask_blog')
from flaskblog import create_app
application = create_app()
flaskblog.conf
<VirtualHost *:80>
ServerName 104.208.86.219
WSGIScriptAlias / C:/flask_blog/deploy/flaskblog.wsgi
<Directory C:/flask_blog>
Require all granted
</Directory>
Alias /static C:/flask_blog/flaskblog/static
ErrorLog C:/flask_blog/logs/error.log
CustomLog C:/flask_blog/logs/access.log combined
</VirtualHost>
5. Configure Apache httpd.conf
......
LoadFile "C:/Users/Developer/AppData/Local/Programs/Python/Python312/python312.dll"
LoadModule wsgi_module "C:/flask_blog/venv/Lib/site-packages/mod_wsgi/server/mod_wsgi.cp312-win_amd64.pyd"
WSGIPythonHome "C:/flask_blog/venv"
Include C:/flask_blog/flaskblog.conf
6. Restart Apache server and test open the webpage on a remote browser
E: In the error.log: ModuleNotFoundError: No module named ‘_socket’\r
S: Add WSGIPythonPath in httpd.conf file under WSGIPythonHome
WSGIPythonHome "C:/Users/12506/AppData/Local/Programs/Python/Python311"
WSGIPythonPath "C:/Users/12506/AppData/Local/Programs/Python/Python311\DLLs"
E: httpd.exe: Syntax error on line 538 of C:/Apache24/conf/httpd.conf: Cannot load C:/flask_blog/venv/Lib/site-packages/mod_wsgi/server/mod_wsgi.cp312-win_amd64.pyd into server: The specified module could not be found. .
S: Get rid of virtual environment
7. Enable HTTPS after adding a domain name
- Get a free SSL certificate from ZeroSSL
Troubleshooting - DNS (CNAME) Verification Please check if you have added the correct Name record: For example, your Name record in ZeroSSL is _D5856C5EEC87E5505EF3F53E95B414EB.domain.com, please enter only_D5856C5EEC87E5505EF3F53E95B414EB without the domain part as most DNS providers filter this part out automatically.
- Download the certificate files and paste it into C:\Apache24\conf directory
- Edit C:\Apache24\conf\httpd.conf by un-commenting these 3 lines
and comment out the original “Include” (We will stop using flaskblog.conf config setups from now on)LoadModule socache_shmcb_module modules/mod_socache_shmcb.so LoadModule ssl_module modules/mod_ssl.so Include conf/extra/httpd-ssl.conf
LoadFile "C:/Users/Developer/AppData/Local/Programs/Python/Python312/python312.dll" LoadModule wsgi_module "C:/Users/Developer/AppData/Local/Programs/Python/Python312/Lib/site-packages/mod_wsgi/server/mod_wsgi.cp312-win_amd64.pyd" WSGIPythonHome "C:/Users/Developer/AppData/Local/Programs/Python/Python312" # Include C:/flask_blog/flaskblog.conf
- Edit C:\Apache24\conf\extra\httpd-ssl.con
<VirtualHost *:80> ServerName www.peng.codes Redirect / https://www.peng.codes/ </VirtualHost> <VirtualHost _default_:443> ServerName www.peng.codes:443 WSGIScriptAlias / C:/flask_blog/deploy/flaskblog.wsgi <Directory C:/flask_blog> Require all granted </Directory> Alias /static C:/flask_blog/flaskblog/static ErrorLog C:/flask_blog/logs/error.log CustomLog C:/flask_blog/logs/access.log combined SSLEngine on SSLCertificateFile "${SRVROOT}/conf/certificate.crt" SSLCertificateKeyFile "${SRVROOT}/conf/private.key" SSLCertificateChainFile "${SRVROOT}/conf/ca_bundle.crt" # Since I don't know what below lines mean, I will keep them for safety. <FilesMatch "\.(cgi|shtml|phtml|php)$"> SSLOptions +StdEnvVars </FilesMatch> <Directory "${SRVROOT}/cgi-bin"> SSLOptions +StdEnvVars </Directory> BrowserMatch "MSIE [2-5]" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 CustomLog "${SRVROOT}/logs/ssl_request.log" \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost>
- Restart the apache service and it should work instantly.
8. References
- https://dev.to/willmvs/flask-deployment-on-windows-139b