Step1:Create one git hub repository
step2:give production path
GCP_CREDENTIALS_JSON = "/opt/lampp/htdocs/motoshare.jp/motoshare-web/gcp-service.json"
step3: git clone repository
git clone git@github.com:Motosharein/motoshare_flask.git
Also install system dependencies in Linux server
sudo apt-get update
sudo apt-get install -y tesseract-ocr libtesseract-dev
Check binary path:
which tesseract
Should return:
/usr/bin/tesseract
Install python
specific version
sudo apt update
sudo apt install python3-pip -y
Check python version
python3 --version
apt install python3.12-venv
Use Python 3.12 safely (venv)
# Check 3.12 exists
which python3.12 || sudo apt install -y python3.12 python3.12-venv
# Create venv with 3.12
cd /opt/lampp/htdocs/motoshare_flask
python3.12 -m venv venv
source venv/bin/activate
# Verify you're inside the venv
which python
python --version
# Install deps inside the venv
pip install --upgrade pip
pip install -r requirements.txt
pip install gunicorn
# 4A) run with gunicorn (recommended)
gunicorn --bind 127.0.0.1:5000 "app:create_app()"
sudo apt install -y libgl1 libglib2.0-0 libsm6 libxext6 libxrender1
Notes
See what your module actually exposes
Run this in your project folder:
cd /opt/lampp/htdocs/motoshare.jp/motoshare_flask
source venv/bin/activate
python -c "import app; print('attrs:', [a for a in dir(app) if a in ('app','application','create_app')])"
Virtual host setup
http_vhost
<VirtualHost *:80>
ServerName motoshare.jp
ServerAlias www.motoshare.jp
DocumentRoot "/opt/lampp/htdocs/motoshare.jp/motoshare-web/public"
# ...your existing Directory + Alias blocks...
# --- Proxy /image/* to Flask on localhost:5000 ---
ProxyRequests Off
ProxyPreserveHost On
# Put these BEFORE any other ProxyPass lines; keep trailing slashes
ProxyPass /image/ http://127.0.0.1:5000/image/
ProxyPassReverse /image/ http://127.0.0.1:5000/image/
# No X-Forwarded-Prefix or Location rewrites (prevents double prefix)
ProxyTimeout 120
Timeout 120
</VirtualHost>
httpd-ssl.conf
<VirtualHost *:443>
ServerName motoshare.jp
ServerAlias www.motoshare.jp
DocumentRoot "/opt/lampp/htdocs/motoshare.jp/motoshare-web/public"
SSLEngine On
SSLCertificateFile "/opt/lampp/etc/certs/motoshare.jp/motoshare.jp.cer"
SSLCertificateKeyFile "/opt/lampp/etc/certs/motoshare.jp/motoshare.jp.key"
SSLCACertificateFile "/opt/lampp/etc/certs/motoshare.jp/fullchain.cer"
# ...your existing Directory + Alias blocks...
# --- Proxy /image/* to Flask on localhost:5000 ---
ProxyRequests Off
ProxyPreserveHost On
ProxyPass /image/ http://127.0.0.1:5000/image/
ProxyPassReverse /image/ http://127.0.0.1:5000/image/
ProxyTimeout 120
Timeout 120
</VirtualHost>
Run it directly in your Ubuntu server terminal (SSH or local):
# paths you already use
APP_DIR=/opt/lampp/htdocs/motoshare.jp/motoshare_flask
VENV=$APP_DIR/venv
# write the unit file
sudo bash -c 'cat >/etc/systemd/system/motoshare-flask.service' <<EOF
[Unit]
Description=MotoShare Flask (Gunicorn)
After=network-online.target
Wants=network-online.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=$APP_DIR
Environment=FLASK_ENV=production
Environment=UPLOAD_FOLDER=$APP_DIR/uploads
Environment=GOOGLE_APPLICATION_CREDENTIALS=/opt/lampp/htdocs/motoshare-web/gcp-service.json
Environment=TESSERACT_CMD=/usr/bin/tesseract
Environment=SECRET_KEY=change-me-to-a-strong-secret
ExecStart=$VENV/bin/gunicorn --workers 2 --bind 127.0.0.1:5000 "app:create_app()"
Restart=always
[Install]
WantedBy=multi-user.target
EOF
After creating the file, run:
sudo systemctl daemon-reload
sudo systemctl enable motoshare-flask
sudo systemctl start motoshare-flask
sudo systemctl status motoshare-flask --no-pager
To see live logs:
sudo journalctl -u motoshare-flask -f
Give Permission
sudo chown -R www-data:www-data /opt/lampp/htdocs/motoshare.jp/motoshare_flask/uploads
# keep it secure but writable: setgid bit so new files inherit the group
sudo chmod 2775 /opt/lampp/htdocs/motoshare.jp/motoshare_flask/uploads
# if you want to be extra sure:
sudo find /opt/lampp/htdocs/motoshare.jp/motoshare_flask/uploads -type d -exec chmod 2775 {} \;
sudo find /opt/lampp/htdocs/motoshare.jp/motoshare_flask/uploads -type f -exec chmod 664 {} \;
In env
IMAGE_API_BASE=https://motoshare.jp
IMAGE_API_TIMEOUT=20
GOOGLE_APPLICATION_CREDENTIALS=/opt/lampp/htdocs/motoshare-web/gcp-service.json
In services.php
'image' => [
// use public domain (HTTPS) in production
'base_url' => env('IMAGE_API_BASE', 'https://motoshare.jp'),
'timeout' => env('IMAGE_API_TIMEOUT', 30),
// keep the exact Flask route path
'qr_path' => env('IMAGE_API_QR_PATH', '/image/qr/scan'),
],
finally check:
https://motoshare.jp/image/hello
===========================================================
if my route
C:\IMAGE_VERIFICATION\views_init_.py
Case A — Only /image
Flask
# C:\IMAGE_VERIFICATION\views\__init__.py
from .image_views import image_bp
def register_blueprints(app):
app.register_blueprint(image_bp, url_prefix="/image")
Apache vhost (works exactly as you wrote)
<VirtualHost *:80>
ServerName motoshare.jp
ServerAlias www.motoshare.jp
DocumentRoot "/opt/lampp/htdocs/motoshare.jp/motoshare-web/public"
ProxyRequests Off
ProxyPreserveHost On
ProxyPass /image/ http://127.0.0.1:5000/image/
ProxyPassReverse /image/ http://127.0.0.1:5000/image/
ProxyTimeout 120
Timeout 120
</VirtualHost>
Case B — /image and /machinelearning
Flask
# in __init__.py
from .image_views import image_bp
def register_blueprints(app):
app.register_blueprint(image_bp, url_prefix="/image")
app.register_blueprint(image_bp, url_prefix="/machinelearning") # ensure spelling
Note: If Flask complains about registering the same blueprint twice, create a second blueprint instance with a different name:
from flask import Blueprint
from .image_views import image_bp as _image_bp
image_bp_ml = Blueprint("image_bp_ml", __name__)
image_bp_ml.deferred_functions = _image_bp.deferred_functions # reuse routes/handlers
def register_blueprints(app):
app.register_blueprint(_image_bp, url_prefix="/image")
app.register_blueprint(image_bp_ml, url_prefix="/machinelearning")
Apache vhost
<VirtualHost *:80>
ServerName motoshare.jp
ServerAlias www.motoshare.jp
DocumentRoot "/opt/lampp/htdocs/motoshare.jp/motoshare-web/public"
ProxyRequests Off
ProxyPreserveHost On
# /image/*
ProxyPass /image/ http://127.0.0.1:5000/image/
ProxyPassReverse /image/ http://127.0.0.1:5000/image/
# /machinelearning/*
ProxyPass /machinelearning/ http://127.0.0.1:5000/machinelearning/
ProxyPassReverse /machinelearning/ http://127.0.0.1:5000/machinelearning/
ProxyTimeout 120
Timeout 120
</VirtualHost>
Top comments (0)