惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

C
Check Point Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
W
WeLiveSecurity
T
Troy Hunt's Blog
Project Zero
Project Zero
Security Archives - TechRepublic
Security Archives - TechRepublic
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
T
Tenable Blog
Jina AI
Jina AI
Recorded Future
Recorded Future
T
The Exploit Database - CXSecurity.com
N
News | PayPal Newsroom
P
Palo Alto Networks Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
G
GRAHAM CLULEY
A
Arctic Wolf
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
Last Week in AI
Last Week in AI
P
Privacy & Cybersecurity Law Blog
Microsoft Azure Blog
Microsoft Azure Blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
SecWiki News
SecWiki News
S
Schneier on Security
有赞技术团队
有赞技术团队
IT之家
IT之家
美团技术团队
Cisco Talos Blog
Cisco Talos Blog
NISL@THU
NISL@THU
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
Hacker News: Ask HN
Hacker News: Ask HN
罗磊的独立博客
博客园_首页
Cyberwarzone
Cyberwarzone
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
爱范儿
爱范儿
云风的 BLOG
云风的 BLOG
H
Hackread – Cybersecurity News, Data Breaches, AI and More
Webroot Blog
Webroot Blog
Latest news
Latest news
D
DataBreaches.Net
Know Your Adversary
Know Your Adversary
P
Privacy International News Feed
宝玉的分享
宝玉的分享
Simon Willison's Weblog
Simon Willison's Weblog
N
News and Events Feed by Topic

herrkaefer

"Vibe planning \u003e vibe coding" "Anything to Markdown" "Built anocus: anonymous commenting for static sites" "日记与小说 -- AI 续写小说欣赏" "Any-podcast: from newsletters to a podcast" "Made MicPipe: a simple voice input tool using ChatGPT dictation" "关于 Tools 和 Skills 的一点感想" "Realtime monitoring of ComEd hourly price" "Introducing SwiftEdgeTTS" "Thoughts on the philosophy of building AI-native apps" "jelly鼻屎" "等饭的人" "Use home assistant to motivate my kid to brush teeth" "Migrated Blog to Hugo and Cloudflare Pages" "Easy Aspen monitoring for Chicago parents" "Introducing HabitBuilder: A simple Telegram bot for habit tracking" "鼓捣" "Open folder or file with Sublime Text from Finder toolbar" "Python dev workflow on macOS" "Create new text file from Finder toolbar" "Uno reinvented for 3-year-old kids" "Uno变身儿童数字游戏" "自动转发Twitter到微博" "Handle annoying operations of objects in Realm DB" "Move Jekyll blog to Ubuntu VPS" "Introducing Mole" "Note taking without note taking app" "Setup Shadowsocks / VPN on Ubuntu Server" "Linode Notes - Basic Setup" "CLASS Style Adapted for Embedded Systems" "psycopgr Tutorial" "pgRouting Notes" "PostgreSQL Notes" "阿城三王" "这一年,这一把日子" "另一面的发现——读《坟》" "定理" "封面与腰封" "Google book下载" "lulu最新写真出炉" "The Big Bang Theory第三季" "自拍婚纱照1" "日全食" "期待动画片" "《麦兜响当当》动画电影主题曲" "转:饶毅--“杂志拜物教”:何时发Cell Nature Science 论文害你" "转:饶毅--提醒年轻人:何时SCI害你?" "西安" "3d打印机" "Dropbox" "刷牙" "贴几张照片" "6156167" "永久和凤凰" "老板的想法" "春" "原来奥巴马也是个朗读者" "应邀发Freeware List 2.0" "史上最能睡的淘宝老板" "至少出名的效果是达到了" "错怪了msn" "独立游戏节2009" "114" "馒头" "Crayon Physics Deluxe" "2008,2009" "盖章记" "小虎队附身许巍" "怎么给word文档加索引:排序问题" "怎么给word文档加索引Q\u0026amp;A" "怎么给Word文档加索引" "教我如何不疯掉" "二则" "P" "哦!报告" "蓝天" "萧翰" "lm" "故宫印象" "转:美国历任总统像" "time can kill itself" "嗯" "建议,只是建议哦" "奥地利行记3" "奥地利行记2" "奥地利行记1" "叶子" "GayBoy" "天使教你扔frisbie" "门徒因何面容愁?" "手机教堂" "丝竹管弦之盛" "残奥" "争座位" "秋意浅" "总理府" "流觞曲水" "映带左右引以为" "咚咚咚 续" "茂林修竹又有"
"Deploy Python web application on Ubuntu server"
"herrkaefer" · 2016-10-08 · via herrkaefer

Components used for this article:

Suppose that we already installed an Ubuntu image on a Linode plan.

Update packages




sudo apt-get update && apt-get upgrade

DNS resolution

Add a A record for the domain name of the application.

Nginx

Install Nginx




sudo apt-get install nginx

Configure Ngnix

Create a cofiguration file under /etc/nginx/conf.d/ with name [app_name].conf.




sudo nano /etc/nginx/conf.d/[app_name].conf

Configure without https

Template of /etc/nginx/conf.d/[app_name].conf:




upstream app_server_wsgiapp {



server localhost:8000 fail_timeout=0;



}



server {



listen 80;



# make sure to change the next line to your own domain name!



server_name appname.example.com;



access_log /var/log/nginx/appname.access.log;



error_log /var/log/nginx/appname.error.log info;



keepalive_timeout 5;



# nginx serve up static files and never send to the WSGI server



location /static {



autoindex on;



alias /home/username/appname/static;



}



location / {



proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;



proxy_set_header Host $http_host;



proxy_redirect off;



if (!-f $request_filename) {



proxy_pass http://app_server_wsgiapp;



break;



}



}



# this section allows Nginx to reverse proxy for websockets



location /socket.io {



proxy_pass http://app_server_wsgiapp/socket.io;



proxy_redirect off;



proxy_buffering 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;



proxy_http_version 1.1;



proxy_set_header Upgrade $http_upgrade;



proxy_set_header Connection "Upgrade";



}



}

Configure with https

(to add)

Restart nginx

Delete default website file:




sudo rm /etc/nginx/sites-enabled/default

Apply new configuration:




sudo service nginx restart

PostgreSQL

Install PostgreSQL




sudo apt-get install postgresql libpq-dev postgresql-client-common postgresql-client

then create database and new user




# switch to postgres user



sudo su - postgres



# create database



createdb dbname



# create a non-root database user and set password



createuser --superuser username



psql



ALTER USER username WITH PASSWORD 'password';

(For me, it seems that the last line would take effect, but we can change the password later.)

Press CTRL-D to quit psql, and CTRL-D again to quit postgres user.

Now database dbname is created and user username is able to access the database.




# Connect to database



psql dbname



# Show tables



\dt

Change password of current user:

Redis

Install Redis




sudo apt-get install redis-server

Test using redis-cli.

Python application

Install pip, virtualenv




sudo apt-get install python3-pip



sudo apt-get install python3.4-venv



sudo python3 -m pip install virtualenv virtualenvwrapper

Note: python3.4-venv not python3-venv

Make virtualenv




# set an environment variable to where you want your virtual environment



export VENV=~/env



# create the virtual environment



python3 -m venv $VENV

Upgrade packages in virtualenv




$VENV/bin/pip install --upgrade pip setuptools

“Why use $VENV/bin/pip instead of source bin/activate, then pip?” From Pyramid docs:

>$VENV/bin/pip clearly specifies that pip is run from within the virtual environment and not at the system level.

>

>activate drops turds into the user’s shell environment, leaving them vulnerable to executing commands in the wrong context. deactivate might not correctly restore previous shell environment variables.

>

>Although using source bin/activate, then pip, requires fewer key strokes to issue commands once invoked, there are other things to consider. Michael F. Lamb (datagrok) presents a summary in Virtualenv’s bin/activate is Doing It Wrong.

>Ultimately we prefer to keep things clear and simple, so we use $VENV/bin/pip.

Pyramid

Install Pyramid




# install pyramid



$VENV/bin/pip install pyramid



# or for a specific released version



$VENV/bin/pip install "pyramid==1.7.3"

Demo app

We create a demo app using scaffold provided by Pyramid.




$VENV/bin/pcreate -s starter demo



cd demo



$VENV/bin/pip install -e .

WSGI server

Install Gunicorn




$VENV/bin/pip install gunicorn

Run the demo app:




cd ~/demo



$VENV/bin/gunicorn --paste development.ini -b :8000

8000 is the port gunicorn listens from the nginx reverse proxy, which we set in /etc/nginx/conf.d/demo.conf.

Open a browser and visit the URL and the app should be running.

Start gunicorn server with supervisor

Install supervisor




sudo apt-get install supervisor

Configure supervisor. Create a file /etc/supervisor/conf.d/[app_name].conf, and add lines: (e.g., for demo app, the file name should be demo.conf)




[program:demo]



environment=DEBUG=False



command=/home/[username]/venv/bin/gunicorn --paste [path/to/app/]development.ini -b :8000 --chdir [path/to/app]



directory=/home/[username]/demo



user=[username]



autostart=true



autorestart=true



redirect_stderr=True

Start supervisor service:




sudo service supervisor start

Visit the URL and the app should be running.