網頁

顯示具有 nginx 標籤的文章。 顯示所有文章
顯示具有 nginx 標籤的文章。 顯示所有文章

2025年2月19日 星期三

安裝 ollama open-webui nginx

參考 https://github.com/ollama/ollama
參考 https://hub.docker.com/r/ollama/ollama
參考 https://www.53ai.com/news/OpenSourceLLM/2024072585037.html

$ docker run -d --gpus=all -p 11434:11434 --name ollama \
  -v /mnt/Data/ollama/ollama_volume:/root/.ollama \
  ollama/ollama
$ docker exec -it ollama ollama run deepseek-r1
$ git clone https://github.com/ggerganov/llama.cpp.git
$ cd llama.cpp
$ cmake -B build
$ cmake --build build --config Release
$ pip install huggingface_hub

轉換 huggingface 上的 model, 成為 GGUF 格式
vi download.py 
from huggingface_hub import snapshot_download, login

login("hf_BqLATKBqbVzOWNBJcFMwHKzCJfu")

# 下载模型
snapshot_download(
    "taide/Llama-3.1-TAIDE-LX-8B-Chat",
    local_dir="taide_Llama-3.1-TAIDE-LX-8B-Chat",
    local_dir_use_symlinks=False,
    ignore_patterns=["*.gguf"]
)

$ vi convert_hf_to_gguf_update.py
在 models 中, 加入下行, 注意 TOKENIZER_TYPE 的選擇
    {"name": "taide_Llama-3.1-TAIDE-LX-8B-Chat", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/taide/Llama-3.1-TAIDE-LX-8B-Chat"},
    {"name": "yentinglin_Llama-3-Taiwan-8B-Instruct", "tokt": TOKENIZER_TYPE.BPE, "repo": "https://huggingface.co/yentinglin/Llama-3-Taiwan-8B-Instruct"},
$ python convert_hf_to_gguf_update.py hf_BqLATKBqbVzOWNBJcFMwHKzCJfu
$ python convert_hf_to_gguf.py taide_Llama-3.1-TAIDE-LX-8B-Chat --outtype f16 --outfile taide_Llama-3.1-TAIDE-LX-8B-Chat.fp16.gguf
$ llama.cpp/build/bin/llama-quantize taide_Llama-3.1-TAIDE-LX-8B-Chat.fp16.gguf Q4_K_M
$ mv ggml-model-Q4_K_M.gguf taide_Llama-3.1-TAIDE-LX-8B-Chat-Q4_K_M.gguf
$ vi Modelfile.taide-8b
FROM ./yentinglin_Llama-3-Taiwan-8B-Instruct.Q4_K_M.gguf
# set the temperature to 1 [higher is more creative, lower is more coherent]
PARAMETER temperature 1
# set the system message
SYSTEM """
我是一個萬事通
"""

$ docker exec -it ollama /bin/bash
# cd /root/.ollama
# ollama create taide-8b -f ./Modelfile.taide-8b
# ollama list
# ollama show taide-8b
# ollama rm taide-8b
# ollama ps
# ollama run taide-8b
>>> /bye
# OLLAMA_HOST=127.0.0.1:11434 ollama serve
$ curl http://localhost:11434/api/generate -d '{
  "model": "yentinglin-8b", 
  "prompt": "建議適合ai的程式語言"
}'
$ curl http://localhost:11434/api/generate -d '{
  "model": "yentinglin-8b", 
  "prompt": "建議適合ai的程式語言",
  "stream", false
}'
$ curl http://localhost:11434/api/chat -d '{
  "model": "yentinglin-8b", 
  "messages": [
    {"role": "user", "content": "建議適合ai的程式語言"}
  ]
}'
$ curl http://localhost:11434/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "yentinglin-8b",
        "messages": [
            {
                "role": "system",
                "content": "你是一個萬事通"
            },
            {
                "role": "user",
                "content": "眼睛酸痛,怎麼辦?"
            }
        ]
    }'

$ docker logs ollama

$ python ../llama.cpp/convert_hf_to_gguf.py yentinglin_Llama-3-Taiwan-8B-Instruct --outtype f16 --outfile yentinglin_Llama-3-Taiwan-8B-Instruct.fp16.gguf
$ llama.cpp/build/bin/llama-quantize yentinglin_Llama-3-Taiwan-8B-Instruct.fp16.gguf Q4_K_M


建議適合ai的程式語言

$ docker run -d -p 3000:8080 --gpus all \
  --add-host=host.docker.internal:host-gateway \
  -v /mnt/Data/ollama/open-webui_volume:/app/backend/data \
  --name open-webui \
  --restart always \
  ghcr.io/open-webui/open-webui:cuda
  
Firefox Web Browser 輸入 http://localhost:3000
出現 This address is restricted 錯誤
進入 Firefox Web Browser 設定
網址列輸入 about:config, 按 "Accept the Risk and Continue" 按鈕
在收尋欄輸入 network.security.ports.banned.override, 點選 "String", 按 +
輸入 port 3000, 按 V
重新載入 http://localhost:3000

chrome 設定
chrome://flags/#unsafely-treat-insecure-origin-as-secure
輸入網址 http://localhost:3000

安裝 nginx
參考 https://docs.openwebui.com/tutorials/https-nginx/
參考 https://yingrenn.blogspot.com/2020/07/ssl-nginx.html
vi nginx.conf
server {
    listen 443 ssl;
    server_name  www.domain.com.tw;
    ssl_certificate /etc/nginx/conf/Certs/server.pem;
    ssl_certificate_key /etc/nginx/conf/Certs/server.key;
    ssl_trusted_certificate /etc/nginx/conf/Certs/caChain.crt;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_session_timeout 5m;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
    ssl_prefer_server_ciphers on;
    
    location / {
        proxy_set_header HOST $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://host.docker.internal:3000;
        
        # Add WebSocket support (Necessary for version 0.5.0 and up)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        
        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;
        
        # (Optional) Disable proxy buffering for better streaming response from models
        proxy_buffering off;
    }
}
server {
     listen 80;
     server_name www.domain.com.tw;
     return 301 https://$host$request_uri; 
}

docker run -itd --name nginx \
  -p 80:80 -p 443:443 \
  --add-host=host.docker.internal:host-gateway \
  -v /mnt/Data/ollama/nginx/conf.d/nginx.conf:/etc/nginx/conf.d/nginx.conf \
  -v /mnt/Data/ollama/nginx/conf:/etc/nginx/conf \
  -m 100m library/nginx:latest

https://www.domain.com.tw

2021年11月23日 星期二

nginx, tomcat and mariadb on QNAP

[/share/Dockers/mariadb] # cat 0_run.sh
docker run --detach --name mariadb \
--env MARIADB_ROOT_PASSWORD=mark1234 \
-v /share/Dockers/mariadb/test:/test \
-v /share/Dockers/mariadb/conf.d:/etc/mysql/conf.d \
mariadb:latest

/share/Dockers/mariadb/test 可放置一些 create database sql

[/share/Dockers/mariadb] # cat conf.d/char.cnf
[client]
# Default is Latin1, if you need UTF-8 set this (also in server section)
default-character-set = utf8mb4

[mysql]
# Default is Latin1, if you need UTF-8 set this (also in server section)
default-character-set = utf8mb4

[/share/Dockers/mariadb] # cat cs_get.sh
CONTAINER_ID=$(docker ps -qf "name=mariadb")
echo ${CONTAINER_ID}
CONTAINER_ID=$(cd /var/lib/docker/containers && ls -d ${CONTAINER_ID}*)
echo ${CONTAINER_ID}
QIP=127.0.0.1
QPORT=8080
curl -sq -XPOST -c cookies.txt -d '{"username": "admin", "password": "password"}' http://${QIP}:${QPORT}/container-station/api/v1/login
curl -sq -XGET -b cookies.txt http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/all

[/share/Dockers/mariadb] # cat cs_set.sh
CONTAINER_ID=$(docker ps -qf "name=mariadb")
echo ${CONTAINER_ID}
CONTAINER_ID=$(cd /var/lib/docker/containers && ls -d ${CONTAINER_ID}*)
echo ${CONTAINER_ID}
QIP=127.0.0.1
QPORT=8080
curl -sq -XPOST -c cookies.txt -d '{"username": "admin", "password": "password"}' http://${QIP}:${QPORT}/container-station/api/v1/login
curl -sq -XPUT -b cookies.txt http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/autostart/on
curl -sq -XPOST -b cookies.txt -d \
    '{
        "cputime": 500,
        "memory": "1024m"
    }' http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/resource/limit

因為此版本已經不建議使用 manager-gui
直接利用 webapps
[/share/Dockers/tomcat] # ls
0_run.sh*  build_docker/  cookies.txt  cs_set.sh*  webapps/
aa.sh*     conf/          cs_get.sh*   test.war
[/share/Dockers/tomcat] # cat 0_run.sh
rm -rf webapps/*
cp test.war webapps

docker run -d \
--link mariadb:mariadb \
-p 8888:8080 \
-v /share/Dockers/tomcat/webapps:/usr/local/tomcat/webapps \
-v /share/Dockers/tomcat/conf/context.xml:/usr/local/tomcat/conf/context.xml \
-v /share/Dockers/tomcat/conf/server.xml:/usr/local/tomcat/conf/server.xml \
--name tomcat tomcat:9.0.46

新增 Resource 部分
[/share/Dockers/tomcat] # cat conf/context.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
...
<Context>

    <!-- Default set of monitored resources. If one of these changes, the    -->
    <!-- web application will be reloaded.                                   -->
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
    <WatchedResource>WEB-INF/tomcat-web.xml</WatchedResource>
    <WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>

    <!-- Uncomment this to disable session persistence across Tomcat restarts -->
    <!--
    <Manager pathname="" />
    -->
    <Resource
        name="jdbc/MyDb"
        auth="Container"
        type="javax.sql.DataSource"
        maxActive="100"
        maxIdle="30"
        maxWait="500"
        driverClassName="org.mariadb.jdbc.Driver"
        url="jdbc:mariadb://mariadb:3306"
        username="mast"
        password="mast"
    />
</Context>

新增 maxDays 防止 log 太大
[/share/Dockers/tomcat] # cat conf/server.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--
...
        <!-- Access log processes all example.
             Documentation at: /docs/config/valve.html
             Note: The pattern used is equivalent to using pattern="common" -->
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               rotatable="true" renameOnRotate="true" maxDays="3"
               prefix="localhost_access_log" suffix=".txt"
               pattern="%h %l %u %t &quot;%r&quot; %s %b" />

      </Host>
    </Engine>
  </Service>
</Server>


[/share/Dockers/tomcat] # cat cs_get.sh
CONTAINER_ID=$(docker ps -qf "name=tomcat")
echo ${CONTAINER_ID}
CONTAINER_ID=$(cd /var/lib/docker/containers && ls -d ${CONTAINER_ID}*)
echo ${CONTAINER_ID}
QIP=127.0.0.1
QPORT=8080
curl -sq -XPOST -c cookies.txt -d '{"username": "admin", "password": "password"}' http://${QIP}:${QPORT}/container-station/api/v1/login
curl -sq -XGET -b cookies.txt http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/all

[/share/Dockers/tomcat] # cat cs_set.sh
CONTAINER_ID=$(docker ps -qf "name=tomcat")
echo ${CONTAINER_ID}
CONTAINER_ID=$(cd /var/lib/docker/containers && ls -d ${CONTAINER_ID}*)
echo ${CONTAINER_ID}
QIP=127.0.0.1
QPORT=8080
curl -sq -XPOST -c cookies.txt -d '{"username": "admin", "password": "password"}' http://${QIP}:${QPORT}/container-station/api/v1/login
curl -sq -XPUT -b cookies.txt http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/autostart/on
curl -sq -XPOST -b cookies.txt -d \
    '{
        "cputime": 500,
        "memory": "1024m"
    }' http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/resource/limit

[/share/Dockers/nginx] # cat 0_run.sh
docker run -d \
--link tomcat:tomcat \
-p 8443:80 \
-v /share/Dockers/nginx/conf.d:/etc/nginx/conf.d \
-v /share/Dockers/nginx/conf:/etc/nginx/conf \
--name nginx nginx:1.14

[/share/Dockers/nginx] # ls conf
Certs/

[/share/Dockers/nginx] # cat conf.d/default.conf
upstream tomcat_server {
    server tomcat:8080 weight=1;
}
server {
    #listen       80;
    listen       80 ssl;
    ssl_certificate /etc/nginx/conf/Certs/server.pem;
    ssl_certificate_key /etc/nginx/conf/Certs/server.key;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/nginx/conf/Certs/caChain.crt;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    #server_name  localhost;
    server_name  www.sunhousetechnology.com.tw;

    #charset koi8-r;
    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        #proxy_pass http://tomcat_server;
    }
    location ^~ /test/ {
        proxy_redirect off;
        proxy_set_header Host $host:$server_port;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # for https
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://tomcat_server;
    }
    client_max_body_size 20M;

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on 127.0.0.1:80
    #
    #location ~ \.php$ {
    #    proxy_pass   http://127.0.0.1;
    #}

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}

[/share/Dockers/nginx] # cat cs_get.sh
CONTAINER_ID=$(docker ps -qf "name=nginx")
echo ${CONTAINER_ID}
CONTAINER_ID=$(cd /var/lib/docker/containers && ls -d ${CONTAINER_ID}*)
echo ${CONTAINER_ID}
QIP=127.0.0.1
QPORT=8080
curl -sq -XPOST -c cookies.txt -d '{"username": "admin", "password": "password"}' http://${QIP}:${QPORT}/container-station/api/v1/login
curl -sq -XGET -b cookies.txt http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/all

[/share/Dockers/nginx] # cat cs_set.sh
CONTAINER_ID=$(docker ps -qf "name=nginx")
echo ${CONTAINER_ID}
CONTAINER_ID=$(cd /var/lib/docker/containers && ls -d ${CONTAINER_ID}*)
echo ${CONTAINER_ID}
QIP=127.0.0.1
QPORT=8080
curl -sq -XPOST -c cookies.txt -d '{"username": "admin", "password": "password"}' http://${QIP}:${QPORT}/container-station/api/v1/login
curl -sq -XPUT -b cookies.txt http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/autostart/on
curl -sq -XPOST -b cookies.txt -d \
    '{
        "cputime": 500,
        "memory": "1024m"
    }' http://${QIP}:${QPORT}/container-station/api/v1/container/docker/${CONTAINER_ID}/resource/limit


2021年2月25日 星期四

解決 跨網站 webapi 出現 blocked by CORS policy

因為跨網站使用 webapi 出現
Access to XMLHttpRequest at 'https://webapi.url' from origin 'https://web.url' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

因為使用 nginx 轉到 tomcat
不用修改 /etc/nginx/sites-available/config
要修改 tomcat 的 WEB-INF/web.xml 在 <web-app> 內加上如下內容
        <filter>
                <filter-name>CorsFilter</filter-name>
                <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
                <init-param>
                        <param-name>cors.allowed.origins</param-name>
                        <param-value>https://www.yoursite:8443,http://yoursite2.com</param-value>
                </init-param>
                <init-param>
                        <param-name>cors.allowed.methods</param-name>
                        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
                </init-param>
                <init-param>
                        <param-name>cors.allowed.headers</param-name>
                        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
                </init-param>
                <init-param>
                        <param-name>cors.exposed.headers</param-name>
                        <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
                </init-param>
                <init-param>
                        <param-name>cors.support.credentials</param-name>
                        <param-value>true</param-value>
                </init-param>
                <init-param>
                        <param-name>cors.preflight.maxage</param-name>
                        <param-value>10</param-value>
                </init-param>
        </filter>
        <filter-mapping>
                <filter-name>CorsFilter</filter-name>
                <url-pattern>/*</url-pattern>
        </filter-mapping>


2021年1月11日 星期一

Ubuntu 18.04 重灌

依據 https://developer.nvidia.com/deepstream-getting-started
選擇各個版本

https://docs.nvidia.com/metropolis/deepstream/dev-guide/index.html

sudo apt-get install ssh
sudo apt install python3-pip
sudo ln -s /usr/bin/python3 /usr/bin/python

安裝 NVIDIA Driver
https://www.linuxbabe.com/ubuntu/install-nvidia-driver-ubuntu-18-04
sudo lshw -c display
sudo lshw -c video
sudo ubuntu-drivers devices
sudo ubuntu-drivers autoinstall
sudo reboot
sudo lshw -c display

安裝 CUDA Toolkit
https://developer.nvidia.com/cuda-downloads
請選擇 CUDA Toolkit 10.2
Linux/x86_64/Ubuntu/18.04/deb(local)
vi ~/.bashrc
export PATH=/usr/local/cuda-10.2:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-10.2/lib64:$LD_LIBRARY_PATH

安裝 CUDNN
https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html
https://developer.nvidia.com/cudnn
選擇 cuDNN v8.0.5 for CUDA 10.2
選擇 cuDNN Library for Linux (x86)
tar -xzvf cudnn-10.2-linux-x64-v8.0.5.39.tgz
sudo cp cuda/include/cudnn*.h /usr/local/cuda/include
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64
sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*
sudo ldconfig
/sbin/ldconfig.real: /usr/local/cuda-10.2/targets/x86_64-linux/liblibcudnn.so.8 is not a symbolic link
cd /usr/local/cuda-10.2/targets/x86_64-linux/lib
sudo rm liblibcudnn.so.8 liblibcudnn.so
sudo ln -s libcudnn.so.8.0.5 libcudnn.so.8
sudo ln -s libcudnn.so.8 libcudnn.so
sudo ldconfig

安裝 TensorRT
下載 TensorRT binary
https://developer.nvidia.com/nvidia-tensorrt-7x-download
選擇 TensorRT 7.1.3.4 for Ubuntu 18.04 and CUDA 10.2 TAR package
version="7.1.3.4"
os="Ubuntu-18.04"
arch=$(uname -m)
cuda="cuda-10.2"
cudnn="cudnn8.0"
tar -xvzf TensorRT-7.1.3.4.Ubuntu-18.04.x86_64-gnu.cuda-10.2.cudnn8.0.tar.gz
vi ~/.bashrc
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:~/Data/TensorRT/TensorRT-7.1.3.4/lib
source ~/.bashrc
cd TensorRt-7.1.3.4/python
sudo pip3 install tensorrt-7.1.3.4-cp36-none-linux_x86_64.whl
cd ../uff
sudo pip3 install uff-0.6.9-py2.py3-none-any.whl
cd ../graphsurgeon/
sudo pip3 install graphsurgeon-0.4.5-py2.py3-none-any.whl

安裝 GStreamer
https://yingrenn.blogspot.com/2020/09/gstreamer.html

安裝 DeepStream
https://docs.nvidia.com/metropolis/deepstream/dev-guide/text/DS_Quickstart.html#dgpu-setup-for-ubuntu
sudo apt install \
 libssl1.0.0 \
 libgstreamer1.0-0 \
 gstreamer1.0-tools \
 gstreamer1.0-plugins-good \
 gstreamer1.0-plugins-bad \
 gstreamer1.0-plugins-ugly \
 gstreamer1.0-libav \
 libgstrtspserver-1.0-0 \
 libgstrtspserver-1.0-dev \
 libjansson4
git clone https://github.com/edenhill/librdkafka.git
cd librdkafka
git reset --hard 7101c2310341ab3f4675fc565f64f0967e135a6a
./configure
make
sudo make install
sudo mkdir -p /opt/nvidia/deepstream/deepstream-5.0/lib
sudo cp /usr/local/lib/librdkafka* /opt/nvidia/deepstream/deepstream-5.0/lib
下載 DeepStream
https://developer.nvidia.com/assets/Deepstream/5.0/ga/secure/deepstream_sdk_5.0.1_x86_64.tbz2
sudo tar -xvf deepstream_sdk_v5.0.1_x86_64.tbz2 -C /
cd /opt/nvidia/deepstream/deepstream-5.0/
sudo ./install.sh
sudo ldconfig

安裝 CMake v3.13
wget http://www.cmake.org/files/v3.13/cmake-3.13.5.tar.gz
tar xpvf cmake-3.13.5.tar.gz cmake-3.13.5
cd cmake-3.13.5
sudo apt-get install zlib1g-dev
sudo apt-get install curl
sudo apt-get install libcurl3
sudo apt-get install libcurl4 libcurl4-openssl-dev
./bootstrap --system-curl
make -j$(nproc)
sudo make install

安裝 Docker
https://docs.docker.com/engine/install/ubuntu/
sudo apt-get update
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io

安裝 NVIDIA Docker
https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker
curl https://get.docker.com | sh \
  && sudo systemctl start docker \
  && sudo systemctl enable docker
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) \
   && curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - \
   && curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list
sudo apt-get update
sudo apt-get install -y nvidia-docker2
sudo systemctl restart docker
sudo groupadd docker
sudo usermod -a -G docker $USER
sudo reboot

若 sudo apt update 出現
W: Target CNF (stable/cnf/Commands-all) is configured multiple times in /etc/apt/sources.list:52 and /etc/apt/sources.list.d/docker.list:1
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4773BD5E130D1D45
sudo rm /etc/apt/sources.list.d/docker.list

安裝 TensorRT 7.1 OSS
https://docs.nvidia.com/deeplearning/tensorrt/install-guide/index.html
https://github.com/NVIDIA/TensorRT/tree/master
從 master 切換到 release/7.1
下載 TensorRT OSS
TensorRT OSS: 包含 TensorRT plugins, Caffe 和 ONNX parsers 等
git clone -b master https://github.com/nvidia/TensorRT TensorRT
cd TensorRT
git submodule update --init --recursive
參考之前的 TensorRT binary
cd TensorRT-7.1.3.4
export TRT_RELEASE=`pwd`
cd $TRT_SOURCE
./docker/build.sh --file docker/ubuntu.Dockerfile --tag tensorrt-ubuntu --os 18.04 --cuda 10.2
./docker/launch.sh --tag tensorrt-ubuntu --gpus all --release $TRT_RELEASE --source $TRT_SOURCE
cd $TRT_SOURCE
mkdir -p build && cd build
cmake .. -DTRT_LIB_DIR=$TRT_RELEASE/lib -DTRT_OUT_DIR=`pwd`/out
make -j$(nproc)
exit
mkdir backup
mv $TRT_RELEASE/targets/x86_64-linux-gnu/lib/libnvinfer_plugin.so.7.1.3 backup
cp $TRT_SOURCE/build/out/libnvinfer_plugin.so.7.2.1 $TRT_RELEASE/targets/x86_64-linux-gnu/lib/libnvinfer_plugin.so.7.1.3

安裝 OpenCV 4.4
git clone https://github.com/opencv/opencv.git opencv-4.4.0 -b 4.4.0 --depth 1
git clone https://github.com/opencv/opencv_contrib.git opencv_contrib-4.4.0 -b 4.4.0 --depth 1
sudo apt-get update
sudo add-apt-repository ppa:alex-p/tesseract-ocr
sudo apt install tesseract-ocr libtesseract-dev
sudo apt-get install libleptonica-dev
sudo apt-get install qt5-default
sudo apt-get install qtcreator
sudo apt-get install build-essential cmake unzip pkg-config
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
sudo apt-get install libxvidcore-dev libx264-dev
sudo apt-get install libgtk-3-dev
sudo apt-get install libatlas-base-dev gfortran
sudo apt-get install libhdf5-dev
sudo apt-get install python3-dev
mkdir build; cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/usr/local \
-D INSTALL_PYTHON_EXAMPLES=ON \
-D INSTALL_C_EXAMPLES=OFF \
-D WITH_TBB=ON \
-D BUILD_opencv_cudacodec=OFF \
-D ENABLE_FAST_MATH=1 \
-D CUDA_FAST_MATH=1 \
-D WITH_CUDA=ON \
-D WITH_CUBLAS=ON \
-D WITH_LIBV4L=ON \
-D BUILD_opencv_python3=ON \
-D BUILD_opencv_python2=OFF \
-D BUILD_opencv_java=OFF \
-D WITH_V4L=ON \
-D WITH_QT=ON \
-D WITH_OPENGL=ON \
-D WITH_GSTREAMER=ON \
-D WITH_GTK=ON \
-D OPENCV_GENERATE_PKGCONFIG=ON \
-D OPENCV_PC_FILE_NAME=opencv.pc \
-D OPENCV_ENABLE_NONFREE=OFF \
-D OPENCV_EXTRA_MODULES_PATH=/your_path_to/opencv/opencv_contrib-4.4.0/modules \
-D BUILD_EXAMPLES=ON \
-D WITH_CUDNN=ON \
-D CUDNN_VERSION="8.0.5" \
-D OPENCV_DNN_CUDA=ON \
-D CUDNN_INCLUDE_DIR=/usr/local/cuda/include \
-D CUDNN_LIBRARY=/usr/local/cuda/lib64/libcudnn.so.8.0.5 \
-D CUDA_ARCH_BIN=7.5 \
../opencv-4.4.0
#-D OPENCV_ENABLE_NONFREE=ON \
#-D OpenGL_GL_PREFERENCE=LEGACY \

make -j$(nproc)
sudo make install
sudo ldconfig
opencv_version -v

下載 Tesseract 的中文字 chi_tra.traineddata, chi_tra_vert.traineddate
https://github.com/tesseract-ocr/tessdata
放至 /usr/share/tesseract-ocr/4.00/tessdata

安裝 Xpra
https://www.xpra.org/trac/wiki/Building/Debian
sudo apt-get install libx11-dev libxtst-dev libxcomposite-dev libxdamage-dev \
 libxkbfile-dev python-all-dev
sudo apt-get install libgtk-3-dev python3-dev python3-cairo-dev python-gi-dev cython3
sudo apt-get install xauth x11-xkb-utils
sudo apt-get install libx264-dev libvpx-dev yasm
sudo apt-get install libnvidia-encode-440
sudo apt-get install libavformat-dev libavcodec-dev libswscale-dev
sudo apt-get install libturbojpeg-dev
sudo apt-get install libwebp-dev
sudo apt-get install uglifyjs brotli libjs-jquery libjs-jquery-ui gnome-backgrounds
sudo apt-get install python3-opengl python3-numpy python3-pil
sudo apt-get install python3-rencode python3-lz4 python3-dbus python3-cryptography \
 python3-netifaces python3-yaml
sudo apt-get install python3-setproctitle python3-xdg python3-pyinotify python3-opencv
sudo apt-get install libpam-dev quilt xserver-xorg-dev xutils-dev xvfb keyboard-configuration
sudo apt-get install python3-kerberos python3-gssapi
sudo apt-get install gstreamer1.0-pulseaudio gstreamer1.0-alsa \
 gstreamer1.0-plugins-base gstreamer1.0-plugins-good \
 gstreamer1.0-plugins-ugly
sudo apt-get install cups-filters cups-common cups-pdf python3-cups
sudo apt-get install openssh-client sshpass python3-paramiko
sudo apt-get install devscripts build-essential lintian debhelper
wget https://www.xpra.org/src/xpra-4.0.4.tar.xz
tar -xf xpra-4.0.6.tar.xz
cd xpra-4.0.6
vi setup.py
#!/usr/bin/env python3
sudo ./setup.py install

安裝 frp
https://yingrenn.blogspot.com/2020/03/frp.html
vi frps.ini
[common]
bind_port = 7000
dashboard_port = 7001
dashboard_user = user
dashboard_pwd = password

vi /etc/systemd/system/frps.service
[Unit]
Description=FRP Server Daemon

[Service]
Type=simple
ExecStartPre=-/usr/sbin/setcap cap_net_bind_service=+ep /home/mark/Data/frp/frp_0.34.3_linux_amd64/frps
ExecStart=/path_to_frp/frp_0.34.3_linux_amd64/frps -c /path_to_frp/frp_0.34.3_linux_amd64/frps.ini
Restart=always
RestartSec=20s
User=nobody
PermissionsStartOnly=true
LimitNOFILE=infinity

[Install]
WantedBy=multi-user.target

sudo systemctl start frps
sudo systemctl enable ftps

安裝 Gitea Tomcat Nginx
https://yingrenn.blogspot.com/2019/11/gitea-in-ubuntu.html
https://yingrenn.blogspot.com/search/label/tomcat

安裝 x11vnc
因為 Ubuntu 18.04 改 LightDM 到 GDM3, 所以要在 console login 後,才能動作
sudo apt install x11vnc
sudo x11vnc -storepasswd
sudo chown mark.mark ~/.vnc/passwd
sudo vi /etc/systemd/system/x11vnc.service
# Description: Custom Service Unit file
# File: /etc/systemd/system/x11vnc.service
[Unit]
Description="x11vnc"
Requires=display-manager.service
After=display-manager.service

[Service]
ExecStart=/usr/bin/x11vnc -loop -nopw -xkb -repeat -noxrecord -noxfixes -noxdamage -forever -rfbport 5900 -display :1 -auth /run/user/1000/gdm/Xauthority -rfbauth /home/mark/.vnc/passwd
ExecStop=/usr/bin/killall x11vnc
Restart=on-failure
RestartSec=2

[Install]
WantedBy=multi-user.target

安裝 VirtualBox
https://www.virtualbox.org/wiki/Downloads
到官網下載
virtualbox-6.1_6.1.16-140961~Ubuntu~bionic_amd64.deb
Oracle_VM_VirtualBox_Extension_Pack-6.1.16.vbox-extpack
sudo dpkg -i virtualbox-6.1_6.1.16-140961~Ubuntu~bionic_amd64.deb
sudo groupadd win10disk
sudo usermod -a -G win10disk youruser
sudo udevadm info /dev/sdX | grep UUID
E: ID_PART_TABLE_UUID=01234567-89ab-cdef-0123-456789abcde
vi /etc/udev/rules.d/99-win10disk.rules
ENV{ID_PART_TABLE_UUID}=="1234567-89ab-cdef-0123-456789abcde", GROUP="win10disk"
ls -l /dev/sdb
brw-rw---- 1 root win10disk 8, 16 Nov 4 23:33 /dev/sdb
VBoxManage internalcommands createrawvmdk -filename .VirtualBox/Crucial1T.vmdk -rawdisk /dev/sda
sudo usermod -a -G vboxusers youruser
拷貝舊的 VM, 修改 win10.vbox, win10.vbox-prev 內的 uuid
與 .VirtualBox/Crucial1T.vmdk 的 uuid 一致
開啟 VirtualBox
File/Preferences...
Extensions 按 +
選擇剛下載的 Oracle_VM_VirtualBox_Extension_Pack-6.1.16.vbox-extpack


只有登入畫面無法使用滑鼠和鍵盤,其餘正常
sudo apt-get instll xserver-xorg-input-all

2020年7月20日 星期一

SSL 證書安裝於 Nginx

參考 SSL 憑證服務 操作手冊
參考 檢查 HTTPS 伺服器加密協定版本
參考 https on nginx and python flask
參考 https Client and Server

取得三個證書
1. eCA 根憑證 "ROOTeCA_64.crt"
2. PublicCA G2 中繼憑證 "PublicCA2_64.crt"
3. 用戶的 SSL 伺服器憑證 "xxx...(32個英數字).crt"

# mkdir /etc/nginx/conf/Certs
放三個證書於此目錄
# cp * /etc/nginx/conf/Certs
產生可信任的CA憑證串列
# cd /etc/nginx/conf/Certs
# cat PublicCA_64.crt ROOTeCA_64.crt > caChain.crt
因 Nginx 只能使用未加密的 server key
# openssl rsa -in server.key -out server_no_pwd.key
# cat server_no_pwd.key > /etc/nginx/conf/Certs/server.key
# cat xxx...(32個英數字).crt PublicCA2_64.crt > server.pem


修改 /etc/nginx/sites-available/ 下的設定檔
        ssl_certificate /etc/nginx/conf/Certs/server.pem;
        ssl_certificate_key /etc/nginx/conf/Certs/server.key;
        ssl_stapling on;
        ssl_stapling_verify on;

        ssl_trusted_certificate /etc/nginx/conf/Certs/caChain.crt;

修改 /etc/nginx/nginx.conf        # 關閉有漏洞的 HTTPS SSLv3, 採用 TLS
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

# ngnix -s reload

測試安全性
$ sudo apt install nmap
$ nmap --script ssl-enum-ciphers -p 8443 www.xxxx.com

Starting Nmap 7.60 ( https://nmap.org ) at 2020-07-20 14:21 CST
Nmap scan report for www.xxxx.com.tw (114.35.104.33)
Host is up (0.00057s latency).
rDNS record for 114.35.14.313: 114-35-104-33.HINET-IP.hinet.net

PORT     STATE SERVICE
8443/tcp open  https-alt
| ssl-enum-ciphers:
|   TLSv1.0:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.1:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|   TLSv1.2:
|     ciphers:
|       TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CCM_8 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CCM (rsa 2048) - A
|       TLS_RSA_WITH_ARIA_256_GCM_SHA384 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CCM_8 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CCM (rsa 2048) - A
|       TLS_RSA_WITH_ARIA_128_GCM_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 (rsa 2048) - A
|       TLS_RSA_WITH_AES_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_256_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_AES_128_CBC_SHA (rsa 2048) - A
|       TLS_RSA_WITH_CAMELLIA_128_CBC_SHA (rsa 2048) - A
|     compressors:
|       NULL
|     cipher preference: server
|_  least strength: A

Nmap done: 1 IP address (1 host up) scanned in 0.41 seconds

測試結果分為等級 A-F


下載 認證標章,並放置下列HTML語法到網頁
<a href="javascript:location.href='https://publicca.hinet.net/SSLQueryCert/ SSLQueryCert.jsp?Domain_name='+document.location.hostname">
<img height="126" src="SSLSeal.gif" width="90" />
</a>

2020年3月18日 星期三

https on nginx and python flask

建立 python flask 的網頁伺服器
$ cat server.py
@app.route('/api/PostTime', methods=['POST'])
def post_time():
    print(request.headers)
    print(request.json)
    result = '\n'.join([request.json['updDate'],
            request.json['camera']])
    print(result)
    return str(result)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port="5000", debug=True,
            # 下兩行可以啟動 https
            #ssl_context=("/home/user1/Data/webapi/openssl/web1/server.crt",
            #    "/home/user1/Data/webapi/openssl/web1/server.key")
            )

$ python3 server.py

$ cat PostTime.py
import requests
import os

data = {
    'updDate': '2019-01-02T15:10:11',
    'camera': 'A001',
}

os.environ['REQUESTS_CA_BUNDLE'] = '/home/user1/Data/webapi/openssl/ca/cacert.pem'
#url = 'https://127.0.0.1:5000/api/PostTime'
url = 'https://127.0.0.1:8443/api/PostTime'
headers = {'Content-Type': 'application/json'}
response = requests.post(url=url,
        headers=headers,
        #verify=False,
        json=data)
if response.ok:
    print("PostTime ok")
    print(response.status_code)
    print(response.text)
else:
    print(response.status_code)
    print(response.text)

$ python3 PostTime.py

# cat /etc/nginx/sites-available/config
server {
        listen 80 default_server;
        listen [::]:80 default_server;

        # SSL configuration
        #
        listen 8443 ssl default_server;
        listen [::]:8443 ssl default_server;
        ssl_certificate /home/user1/Data/webapi/openssl/web1/server.crt;
        ssl_certificate_key /home/user1/Data/webapi/openssl/web1/server.key;
        root /var/www/html;

        # Add index.php to the list if you are using PHP
        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location ^~ /api/ {
                # 當 https 由 nginx 管控,python flask 就要走一般的 http
                proxy_pass http://127.0.0.1:5000;
                proxy_set_header Host $host;
        }
        # 設定上傳限制
        client_max_body_size 10M;
}

重新啟動 nginx
# sudo nginx -s reload

2019年11月6日 星期三

gitea in ubuntu

參考 如何在Ubuntu 18.04上安裝Gitea

安裝 Nginx
$ sudo apt update
$ sudo apt -y install nginx
安裝完成可以用瀏覽器測試 http://localhost
自動啟動 nginx
$ sudo systemctl stop nginx.service
$ sudo systemctl start nginx.service
$ sudo systemctl restart nginx.service
$ sudo systemctl reload nginx.service
$ sudo systemctl enable nginx.service

安裝 Git
$ sudo apt -y install git
$ git --version

安裝 MariaDB
$ sudo apt -y install mariadb-server mariadb-client
$ sudo systemctl stop mariadb.service
$ sudo systemctl start mariadb.service
$ sudo systemctl restart mariadb.service
$ sudo systemctl reload mariadb.service
$ sudo systemctl enable mariadb.service

建立 MariaDB root 密碼,並禁止遠端連接
$ sudo mysql_secure_installation
Enter current password for root (enter for none): Just press the Enter
Set root password? [Y/n]: Y
New password: Enter password
Re-enter new password: Repeat password
Remove anonymous users? [Y/n]: Y
Disallow root login remotely? [Y/n]: Y
Remove test database and access to it? [Y/n]: Y
Reload privilege tables now? [Y/n]: Y

重新啟動 MariaDB
$ sudo systemctl restart mariadb.service

建立 gitea 資料庫, giteauser 使用者
$ sudo mysql -u root -p
CREATE DATABASE gitea;
CREATE USER 'giteauser'@'localhost' IDENTIFIED BY 'password';
GRANT ALL ON gitea.* TO 'giteauser'@'localhost' IDENTIFIED BY 'password' WITH GRANT OPTION;
FLUSH PRIVILEGES;
EXIT;

建立 git 使用者,以便運行 gitea
$ sudo adduser --system --shell /bin/bash --gecos 'Git Version Control' --group --disabled-password --home /home/git git
$ sudo mkdir -p /var/lib/gitea/{custom,data,indexers,public,log}
$ sudo chown git:git /var/lib/gitea/{data,indexers,log}
$ sudo chmod 750 /var/lib/gitea/{data,indexers,log}
$ sudo mkdir /etc/gitea
$ sudo chown root:git /etc/gitea
$ sudo chmod 770 /etc/gitea

下載並安裝 gitea
$ sudo wget -O gitea https://dl.gitea.io/gitea/1.5.0/gitea-1.5.0-linux-amd64
$ sudo chmod +x gitea
$ sudo cp gitea /usr/local/bin/gitea
$ sudo vi /etc/systemd/system/gitea.service
[Unit]
Description=Gitea (Git with a cup of tea)
After=syslog.target
After=network.target
#After=mysqld.service
#After=postgresql.service
#After=memcached.service
#After=redis.service

[Service]
# Modify these two values and uncomment them if you have
# repos with lots of files and get an HTTP error 500 because
# of that
###
#LimitMEMLOCK=infinity
#LimitNOFILE=65535
RestartSec=2s
Type=simple
User=git
Group=git
WorkingDirectory=/var/lib/gitea/
ExecStart=/usr/local/bin/gitea web -c /etc/gitea/app.ini
Restart=always
Environment=USER=git HOME=/home/git GITEA_WORK_DIR=/var/lib/gitea
# If you want to bind Gitea to a port below 1024 uncomment
# the two values below
###
#CapabilityBoundingSet=CAP_NET_BIND_SERVICE
#AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

$ sudo systemctl daemon-reload
$ sudo systemctl enable gitea
$ sudo systemctl start gitea
$ sudo system status gitea

使用 Nginx 代理 gitea
$ sudo vi /etc/nginx/sites-available/git
upstream gitea {
 server 127.0.0.1:3000;
}

server {
 listen 80 default_server;
 listen [::]:80 default_server;
 server_name example.com;
 root /var/lib/gitea/public;
 access_log off;
 error_log off;

 location / {
 try_files maintain.html $uri $uri/index.html @node;
 }

 location @node {
 client_max_body_size 0;
 proxy_pass http://localhost:3000;
 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 proxy_set_header X-Real-IP $remote_addr;
 proxy_set_header Host $http_host;
 proxy_set_header X-Forwarded-Proto $scheme;
 proxy_max_temp_file_size 0;
 proxy_redirect off;
 proxy_read_timeout 120;
 }
}

$ sudo ln -s /etc/nginx/sites-available/git /etc/nginx/sites-enabled
$ sudo systemctl reload nginx.service

開啟網頁設定 Gitea
http://localhost/install


錯誤排除

最後安裝動作 http://localhost:3000 出現下列錯誤
Index column size too large. The maximum column size is 767 bytes

sudo mysql -u root -p
[sudo] password for user: (os 的密碼)
Enter password:(mysql 的密碼)
MariaDB [(none)]> show global variables like 'innodb_large%';
MariaDB [(none)]> set global innodb_large_prefix = ON;
MariaDB [(none)]> set global innodb_default_row_format=dynamic;

MariaDB [(none)]> select user, host from mysql.user;
MariaDB [(none)]> show grants for 'giteauser'@'localhost';
MariaDB [(none)]> revoke all privileges, grant option from 'giteauser'@'localhost';
MariaDB [(none)]> drop user 'giteauser'@'localhost';
MariaDB [(none)]> drop database gitea;

http://localhost:3000/install
只能執行一次,下一次就回 404
sudo vi /etc/gitea/app.ini
INSTALL_LOCK=false
sudo systemctl stop gitea
sudo systemctl start gitea

http://localhost:3000/install
主要填寫 Database
Username=giteauser
Password=
點開 Server and Third-Party Service Settings
Disable Self-Registration
Require Sign-In to View Pages
點開 Administrator Account Settings
建立第一個 gitea 管理者