diff --git a/.conf/nginx/conf.d/http/main.conf b/.conf/nginx/conf.d/http/main.conf new file mode 100644 index 0000000..09a29aa --- /dev/null +++ b/.conf/nginx/conf.d/http/main.conf @@ -0,0 +1,8 @@ +server { + listen 80; + location / { + root /var/www/build; + autoindex off; + try_files $uri $uri/ =404; + } +} diff --git a/.conf/nginx/nginx.conf b/.conf/nginx/nginx.conf new file mode 100644 index 0000000..eac684b --- /dev/null +++ b/.conf/nginx/nginx.conf @@ -0,0 +1,69 @@ +worker_processes 4; +pid /run/nginx.pid; + + +error_log /dev/stderr info; + + +events { + worker_connections 1024; + multi_accept off; +} + +http { + + + ## asynchronous input/output policy. + tcp_nopush on; + sendfile on; + + + ## Security policy + ssl_protocols TLSv1.3 TLSv1.2; + ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA HIGH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; + server_tokens off; # disable server version response header. + add_header X-Content-Type-Options nosniff; # Disable sniffing + add_header X-Frame-Options SAMEORIGIN always; # Prevent clickjacking. + add_header "X-XSS-Protection" "1; mode=block"; # Prevent cross-site-scripting + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; # Force HSTS, prevent mitm attack between 301 redirect for http, and https server. + + + ## Log file policy. + log_format logformat '$remote_addr - $remote_user [$time_local] "$request" ' + '$status $body_bytes_sent "$http_referer" ' + '"$http_user_agent" "$http_x_forwarded_for"'; + access_log /dev/stdout logformat; + + + ## Temp file policy. + client_body_temp_path /tmp/client_temp; + fastcgi_temp_path /tmp/fastcgi_temp; + uwsgi_temp_path /tmp/uwsgi_temp; + proxy_temp_path /tmp/proxy_temp; + scgi_temp_path /tmp/scgi_temp; + + + ## Buffer Policy. + client_body_buffer_size 1K; + client_header_buffer_size 1k; + client_max_body_size 1k; + large_client_header_buffers 2 1k; + + + ## Client timeout policy + client_body_timeout 10; + client_header_timeout 10; + keepalive_timeout 5 5; + send_timeout 10; + + + ## Default mime type. + include snippets/mime-types.conf; + default_type text/html; + + + ## http vhosts + include conf.d/http/*.conf; + + +} \ No newline at end of file diff --git a/.conf/nginx/snippets/fastcgi.conf b/.conf/nginx/snippets/fastcgi.conf new file mode 100644 index 0000000..091738c --- /dev/null +++ b/.conf/nginx/snippets/fastcgi.conf @@ -0,0 +1,26 @@ + +fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; +fastcgi_param QUERY_STRING $query_string; +fastcgi_param REQUEST_METHOD $request_method; +fastcgi_param CONTENT_TYPE $content_type; +fastcgi_param CONTENT_LENGTH $content_length; + +fastcgi_param SCRIPT_NAME $fastcgi_script_name; +fastcgi_param REQUEST_URI $request_uri; +fastcgi_param DOCUMENT_URI $document_uri; +fastcgi_param DOCUMENT_ROOT $document_root; +fastcgi_param SERVER_PROTOCOL $server_protocol; +fastcgi_param REQUEST_SCHEME $scheme; +fastcgi_param HTTPS $https if_not_empty; + +fastcgi_param GATEWAY_INTERFACE CGI/1.1; +fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; + +fastcgi_param REMOTE_ADDR $remote_addr; +fastcgi_param REMOTE_PORT $remote_port; +fastcgi_param SERVER_ADDR $server_addr; +fastcgi_param SERVER_PORT $server_port; +fastcgi_param SERVER_NAME $server_name; + +# PHP only, required if PHP was built with --enable-force-cgi-redirect +fastcgi_param REDIRECT_STATUS 200; diff --git a/.conf/nginx/snippets/mime-types.conf b/.conf/nginx/snippets/mime-types.conf new file mode 100644 index 0000000..62bd4b6 --- /dev/null +++ b/.conf/nginx/snippets/mime-types.conf @@ -0,0 +1,48 @@ +types { + text/html html htm shtml; + text/css css; + text/xml xml rss; + image/gif gif; + image/jpeg jpeg jpg; + application/x-javascript js; + text/plain txt; + text/x-component htc; + text/mathml mml; + image/png png; + image/x-icon ico; + image/x-jng jng; + image/vnd.wap.wbmp wbmp; + application/java-archive jar war ear; + application/mac-binhex40 hqx; + application/pdf pdf; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/zip zip; + application/octet-stream deb; + application/octet-stream bin exe dll; + application/octet-stream dmg; + application/octet-stream eot; + application/octet-stream iso img; + application/octet-stream msi msp msm; + audio/mpeg mp3; + audio/x-realaudio ra; + video/mpeg mpeg mpg; + video/quicktime mov; + video/x-flv flv; + video/x-msvideo avi; + video/x-ms-wmv wmv; + video/x-ms-asf asx asf; + video/x-mng mng; +} \ No newline at end of file diff --git a/.conf/nginx/snippets/proxy.conf b/.conf/nginx/snippets/proxy.conf new file mode 100644 index 0000000..34af2fe --- /dev/null +++ b/.conf/nginx/snippets/proxy.conf @@ -0,0 +1,10 @@ +proxy_redirect off; +proxy_set_header Host $host; +proxy_set_header X-Real-IP $remote_addr; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +client_max_body_size 10m; +client_body_buffer_size 128k; +proxy_connect_timeout 90; +proxy_send_timeout 90; +proxy_read_timeout 90; +proxy_buffers 32 4k; \ No newline at end of file diff --git a/.conf/nginx/snippets/scgi.conf b/.conf/nginx/snippets/scgi.conf new file mode 100644 index 0000000..6d4ce4f --- /dev/null +++ b/.conf/nginx/snippets/scgi.conf @@ -0,0 +1,17 @@ + +scgi_param REQUEST_METHOD $request_method; +scgi_param REQUEST_URI $request_uri; +scgi_param QUERY_STRING $query_string; +scgi_param CONTENT_TYPE $content_type; + +scgi_param DOCUMENT_URI $document_uri; +scgi_param DOCUMENT_ROOT $document_root; +scgi_param SCGI 1; +scgi_param SERVER_PROTOCOL $server_protocol; +scgi_param REQUEST_SCHEME $scheme; +scgi_param HTTPS $https if_not_empty; + +scgi_param REMOTE_ADDR $remote_addr; +scgi_param REMOTE_PORT $remote_port; +scgi_param SERVER_PORT $server_port; +scgi_param SERVER_NAME $server_name; diff --git a/.conf/nginx/snippets/uwsgi.conf b/.conf/nginx/snippets/uwsgi.conf new file mode 100644 index 0000000..09c732c --- /dev/null +++ b/.conf/nginx/snippets/uwsgi.conf @@ -0,0 +1,17 @@ + +uwsgi_param QUERY_STRING $query_string; +uwsgi_param REQUEST_METHOD $request_method; +uwsgi_param CONTENT_TYPE $content_type; +uwsgi_param CONTENT_LENGTH $content_length; + +uwsgi_param REQUEST_URI $request_uri; +uwsgi_param PATH_INFO $document_uri; +uwsgi_param DOCUMENT_ROOT $document_root; +uwsgi_param SERVER_PROTOCOL $server_protocol; +uwsgi_param REQUEST_SCHEME $scheme; +uwsgi_param HTTPS $https if_not_empty; + +uwsgi_param REMOTE_ADDR $remote_addr; +uwsgi_param REMOTE_PORT $remote_port; +uwsgi_param SERVER_PORT $server_port; +uwsgi_param SERVER_NAME $server_name; diff --git a/.conf/supervisor/supervisord.conf b/.conf/supervisor/supervisord.conf new file mode 100644 index 0000000..11c40b8 --- /dev/null +++ b/.conf/supervisor/supervisord.conf @@ -0,0 +1,15 @@ +[supervisord] +nodaemon=true +logfile=/dev/null +logfile_maxbytes=0 +pidfile=/run/supervisord.pid + + +[program:nginx] +command=nginx -g 'daemon off;' +stdout_logfile=/dev/stdout +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/stderr +stderr_logfile_maxbytes=0 +autorestart=true +startretries=3 diff --git a/.gitea/workflows/production/build-deploy-docs.yml b/.gitea/workflows/production/build-deploy-docs.yml new file mode 100644 index 0000000..cc6ba08 --- /dev/null +++ b/.gitea/workflows/production/build-deploy-docs.yml @@ -0,0 +1,129 @@ +on: + push: + paths: + - "content/**" + - "static/**" + - "templates/**" + branches: + - "main" + + +jobs: + job1: + name: Build static site, docker image, upload artifact... + runs-on: catthehacker-ubuntu + steps: + - + name: Get current date + id: date + run: echo "::set-output name=date::$(date +'%Y%m%d%H%M%S')" + - + name: Checkout the git repo... + uses: actions/checkout@v3 + - + name: Set up docker buildx... + uses: docker/setup-buildx-action@v3 + - + name: Login to gitea registry + uses: docker/login-action@v3 + with: + registry: gitea.raer.me + username: ${{ secrets.PRODUCTION_REGISTRY_USERNAME }} + password: ${{ secrets.PRODUCTION_REGISTRY_TOKEN }} + - + name: Install required system packages... + run: | + export DEBIAN_FRONTEND=noninteractive + apt update + apt upgrade -y + apt install -y curl tar p7zip-full python3 pip pipx + - + name: Install pipenv, build blog... + run: | + pip install pipenv + pipenv install + pipenv run blag build + - + name: Create artifact... + run: 7z a -mx=9 ./artifact.7z build + - + name: Upload artifact... + uses: actions/upload-artifact@v3 + with: + name: artifact_${{ steps.date.outputs.date }} + path: ./artifact.7z + retention-days: 7 + - + name: Build and push docker image to gitea package store + uses: docker/build-push-action@v5 + with: + context: . + push: true + platforms: linux/amd64 + tags: gitea.raer.me/${{ gitea.repository }}:${{ gitea.ref_name }} + job2: + needs: job1 + name: Connect to deployment host, update, and redeploy docs website. + runs-on: ubuntu-latest + steps: + - + name: Install required system packages... + run: | + export DEBIAN_FRONTEND=noninteractive + apt update + apt upgrade -y + apt install -y iputils-ping + - + name: Configure SSH... + env: + SSH_USER: ${{ secrets.PRODUCTION_SSH_USER }} + SSH_KEY: ${{ secrets.PRODUCTION_SSH_KEY }} + SSH_HOST: ${{ secrets.PRODUCTION_SSH_HOST }} + run: | + mkdir -p ~/.ssh/ + echo "$SSH_KEY" > ~/.ssh/staging.key + chmod 600 ~/.ssh/staging.key + cat >> ~/.ssh/config <