├── connect.sh ├── LICENSE ├── guides ├── Hello Linux Dependencies.md └── 1. Push Local Code to Live Server via Git.md ├── .gitignore ├── README.md └── setup.sh /connect.sh: -------------------------------------------------------------------------------- 1 | ssh root@104.248.231.241 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Coding For Entrepreneurs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /guides/Hello Linux Dependencies.md: -------------------------------------------------------------------------------- 1 | This is a comprehensive overview of all installations needed for the upcoming __Hello Linux__ series. And yes, these installations will be on a Ubuntu 18.04 server. 2 | 3 | In __Hello Linux__, we want to have the following implemented: 4 | 5 | - __Git__ for pushing, building, & deploying ([Guide](https://www.codingforentrepreneurs.com/blog/git-push-local-code-to-live-linux-server/)) 6 | - __Supervisor__ for managing processes 7 | - __Nginx__ as our web server 8 | - __Redis__ for our task queue datastore / message broker 9 | - __Celery__ as our Python app task queue / scheduler 10 | - __Gunicorn__ as our WSGI web server 11 | - __PostgreSQL__ as our database 12 | - __Django__ as our Python web framework 13 | - __Let's Encrypt__ for HTTPs Certificates 14 | 15 | 16 | 17 | #### Installation Dependencies 18 | Ubuntu 18.04 19 | ``` 20 | sudo apt-get update -y 21 | 22 | sudo apt-get install build-essential libssl-dev libpq-dev libcurl4-gnutls-dev libexpat1-dev gettext unzip -y 23 | 24 | sudo apt-get install supervisor -y 25 | 26 | sudo apt-get install python3-pip python3-dev python3-venv -y 27 | 28 | sudo apt-get install nano -y 29 | 30 | sudo apt install redis-server -y 31 | 32 | sudo apt-get install git -y 33 | 34 | sudo apt-get install postgresql postgresql-contrib -y 35 | 36 | sudo apt-get install nginx curl -y 37 | 38 | sudo apt-get install ufw -y 39 | 40 | sudo ufw allow 'Nginx Full' 41 | 42 | sudo ufw allow ssh 43 | 44 | sudo add-apt-repository ppa:certbot/certbot 45 | 46 | sudo apt-get install python-certbot-nginx -y 47 | 48 | sudo python3 -m pip install virtualenv 49 | 50 | sudo service supervisor start 51 | 52 | sudo apt autoremove -y 53 | ``` -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | src/cfehome/settings/local.py 3 | cfehome/settings/local.py 4 | 5 | # Ingore sublime text 6 | *.sublime-* 7 | 8 | # Byte-compiled / optimized / DLL files 9 | __pycache__/ 10 | *.py[cod] 11 | *$py.class 12 | 13 | # C extensions 14 | *.so 15 | 16 | # Distribution / packaging 17 | .Python 18 | build/ 19 | develop-eggs/ 20 | dist/ 21 | downloads/ 22 | eggs/ 23 | .eggs/ 24 | lib/ 25 | lib64/ 26 | parts/ 27 | sdist/ 28 | var/ 29 | wheels/ 30 | *.egg-info/ 31 | .installed.cfg 32 | *.egg 33 | MANIFEST 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .coverage 49 | .coverage.* 50 | .cache 51 | nosetests.xml 52 | coverage.xml 53 | *.cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | 66 | # Flask stuff: 67 | instance/ 68 | .webassets-cache 69 | 70 | # Scrapy stuff: 71 | .scrapy 72 | 73 | # Sphinx documentation 74 | docs/_build/ 75 | 76 | # PyBuilder 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # pyenv 83 | .python-version 84 | 85 | # celery beat schedule file 86 | celerybeat-schedule 87 | 88 | # SageMath parsed files 89 | *.sage.py 90 | 91 | # Environments 92 | .env 93 | .venv 94 | env/ 95 | venv/ 96 | ENV/ 97 | env.bak/ 98 | venv.bak/ 99 | 100 | # Spyder project settings 101 | .spyderproject 102 | .spyproject 103 | 104 | # Rope project settings 105 | .ropeproject 106 | 107 | # mkdocs documentation 108 | /site 109 | 110 | # mypy 111 | .mypy_cache/ 112 | -------------------------------------------------------------------------------- /guides/1. Push Local Code to Live Server via Git.md: -------------------------------------------------------------------------------- 1 | # Git Push Local Code to Live Linux Server 2 | 3 |
This is the first post of a many part series. Check back for more.
4 | 5 | 6 | Git is a version control system. It's a simple way to track changes in your code. 7 | 8 | It also can be a simple way to deploy your code to a live server. 9 | 10 | > Don't have a live server? Pick one up for $5/mo on [Digital Ocean](https://kirr.co/l8v1n1) ([no referral](https://www.digitalocean.com/)) 11 | 12 | Once you set it up 1 time successfully. You'll never want to user another method (I'm looking at you SFTP). 13 | 14 | Let's do this. 15 | 16 | ********* 17 | **Basic Requirments** 18 | 19 | **Mac / Linux** 20 | - You'll need to use Terminal. 21 | 22 | **Windows** 23 | - use PowerShell or possibly [PuTTY](https://www.putty.org/) (for SSH). This guide *might* not work for your version Windows too. :() 24 | 25 | **Live Server Details** 26 | - **Ubuntu 18.04** is what we use here but not required. 27 | - **Other Linux Distro?** Check how to install git, most/all other things are the same. 28 | 29 | ********* 30 | 31 | #### 1. Install git locally and create local repo 32 | > Did I mention this step is local? 33 | 34 | Download and install via [https://git-scm.com/downloads](https://git-scm.com/downloads) 35 | 36 | Then, 37 | ``` 38 | mkdir Dev 39 | cd Dev 40 | mkdir myproject 41 | cd myproject 42 | git init 43 | ``` 44 | 45 | #### 2. SSH into Live Server 46 | ``` 47 | ssh root@104.248.231.241 48 | ``` 49 | Replace `root@104.248.231.241` with your user / ip 50 | 51 | 52 | #### 3. Install git on Server 53 | ``` 54 | sudo apt-get install git -y 55 | 56 | ``` 57 | 58 | 59 | 60 | #### 4. Create bare git repo 61 | 62 | ``` 63 | cd /var/ 64 | mkdir repo 65 | cd /var/repo/ 66 | mkdir myproject.git 67 | cd myproject.git 68 | ``` 69 | 70 | ##### Starting fresh? 71 | ``` 72 | git init --bare 73 | ``` 74 | 75 | ##### Using previous? 76 | ``` 77 | git clone https://github.com/codingforentrepreneurs/CFE-Blank-Project . --bare 78 | ``` 79 | 80 | 81 | #### 5. Add `post-receive` hook 82 | Hooks are very useful for doing things automatically while working with git. 83 | 84 | In our case, we need a hook for after a successful push aka `post-receive` to unpack our code into a server-side working directory. 85 | 86 | 1. Make initial working directory 87 | ``` 88 | mkdir /var/www/ 89 | mkdir /var/www/myproject/ 90 | ``` 91 | 92 | 2. View all hook samples: 93 | ``` 94 | ls -al /var/repo/myproject.git/hooks/ 95 | ``` 96 | 97 | 3. Create the actual `post-receive` hook. 98 | ``` 99 | cd /var/repo/myproject.git/hooks/ 100 | nano post-recieve 101 | git --work-tree=/var/www/myproject/ --git-dir=/var/repo/myproject.git/ checkout -f 102 | ``` 103 | 4. Make hook executable 104 | ``` 105 | cd /var/repo/myproject.git/hooks/ 106 | chmod +x post-receive 107 | ``` 108 | 109 | 110 | #### 6. Get host name 111 | ``` 112 | myip=$(hostname -I | cut -f1 -d' ') 113 | echo $myip 114 | ``` 115 | This will yield a value of something like `104.248.231.241` but with your actual value. 116 | 117 | 118 | #### 7. Add to local git repo 119 | 1. Exit live server 120 | ``` 121 | exit 122 | ``` 123 | 2. Change into local working directory 124 | 125 | ``` 126 | # on local computer 127 | cd ~/Dev/myproject 128 | ``` 129 | 3. Check git is working... No errors right? 130 | ``` 131 | git status 132 | ``` 133 | 134 | 4. Add live remote 135 | ``` 136 | git remote add live ssh://root@104.248.231.241/var/repo/myproject.git 137 | ``` 138 | The format is this: 139 | 140 | `git remote add ssh://@/var/repo/.git` 141 | 142 | 143 | #### 8. Make Changes Locally and Push 144 | 145 | ``` 146 | cd ~/Dev/myproject 147 | echo "hello there" > test.txt 148 | git add 'test.txt' 149 | git commit -m "Local file test" 150 | git push live master 151 | ``` 152 | 153 | 154 | #### 9. SSH into your Server, How did it go? 155 | 156 | 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Hello Linux 2 | 3 | 4 | This series is all about deploying a Python web application on Ubuntu 18.04 LTS. 5 | 6 | 7 | You can spin up a virtual machine with Ubuntu at a variety of places: 8 | 9 | - [Digital Ocean](https://kirr.co/l8v1n1) | ([without referral code](https://www.digitalocean.com)) 10 | 11 | - Google Cloud Compute Engine (https://cloud.google.com/compute/) 12 | 13 | - Amazon Web Services EC2 (https://aws.amazon.com/ec2/) 14 | 15 | 16 | We'll be using Digital Ocean since it's really easy to get started. What you'll learn here can also be applied to deploying Python projects on any Ubuntu server. In some cases, this setup will work with other Linux distributions too albeit different methods of installation (ie not using `apt-get`). 17 | 18 | 19 | Here's the plan: 20 | 21 | - Launch a virtual machine (droplet) with [Digital Ocean](https://kirr.co/l8v1n1) 22 | - Access our droplet via SSH 23 | - Install Updates & Dependancies via bash script which is [here](./setup.sh) 24 | - Configure & Implement: 25 | - Git (for push, build, & deploy) [[docs](https://git-scm.com/)] 26 | - Supervisor (process manager) [[docs](http://supervisord.org)] 27 | - Nginx (web server / load balancer) [[docs](http://nginx.org/en/docs/)] 28 | - Redis (task queue datastore / message broker) [[docs](https://redis.io/documentation)] 29 | - Celery (worker / task queues) [[docs](http://www.celeryproject.org/)] 30 | - Gunicorn (WSGI web server for python) [[docs](https://gunicorn.org/)] 31 | - PostgreSQL (database) [[docs](https://www.postgresql.org/docs/)] 32 | - Django (Python web framework) [[docs](https://www.djangoproject.com)] 33 | - Let's Encrypt for HTTPs Certificates 34 | 35 | 36 | ### 1. Automatic Virtual Machine Setup 37 | After you run the below command, you'll see an endpoint to add to your local git remote. 38 | 39 | ```shell 40 | wget https://raw.githubusercontent.com/codingforentrepreneurs/Hello-Linux/master/setup.sh 41 | chmod +x setup.sh 42 | ./setup.sh 43 | ``` 44 | 45 | 46 | ### 2. Production-Ready Django Project 47 | We'll be using a bare bones Django project that's mostly ready for production. It's just an example but an important one to get this working. 48 | 49 | Go to [this guide](https://kirr.co/8mjnna) to get started. 50 | 51 | 52 | ### 3. Create PostgreSQL Database for Django 53 | 54 | To create a PostgreSQL database, **it's recommended to use [setup.sh](./setup.sh) on Server**. 55 | 56 | Another option is to run: 57 | 58 | ```shell 59 | 60 | # enable current logged in user as a default user for postgres 61 | sudo -u postgres createuser $USER 62 | 63 | sudo -u postgres psql --command="CREATE DATABASE ${projectDB};" 64 | 65 | sudo -u postgres psql --command="CREATE USER ${projectDBuser} WITH PASSWORD '${newPassword}';" 66 | 67 | sudo -u postgres psql --command="ALTER ROLE ${projectDBuser} SET client_encoding TO 'utf8';" 68 | 69 | sudo -u postgres psql --command="ALTER ROLE ${projectDBuser} SET default_transaction_isolation TO 'read committed';" 70 | 71 | sudo -u postgres psql --command="ALTER ROLE ${projectDBuser} SET timezone TO 'UTC';" 72 | 73 | sudo -u postgres psql --command="GRANT ALL PRIVILEGES ON DATABASE ${projectDB} TO ${projectDBuser};" 74 | 75 | 76 | ``` 77 | 78 | Be sure to replace `${projectDB}`, `${projectDBuser}`, and `${newPassword}` to the values you want to use. The setup script does this automatically. 79 | 80 | #### Update Django Production Settings (`src/cfehome/settings/production.py`) 81 | ```python 82 | DATABASES = { 83 | 'default': { 84 | 'ENGINE': 'django.db.backends.sqlite3', 85 | 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), 86 | } 87 | } 88 | 89 | DATABASES = { 90 | 'default': { 91 | 'ENGINE': 'django.db.backends.postgresql', 92 | 'NAME': '${projectDB}', 93 | 'USER': '${projectDBuser}', 94 | 'PASSWORD': '{newPassword}', 95 | 'HOST': 'localhost', 96 | 'PORT': '', 97 | } 98 | } 99 | ``` 100 | 101 | #### Activate Virtual Environment & Migrate Django 102 | ```shell 103 | $ cd path/to/django/proj 104 | $ pipenv shell 105 | (venv) $ pipenv install psycopg2-binary # you might need this 106 | (venv) $ python manage.py migrate 107 | ``` 108 | 109 | Our example 110 | ```shell 111 | $ cd /var/www/hello_linux/src/ 112 | $ pipenv shell 113 | (src) $ python manage.py migrate 114 | ``` 115 | 116 | 117 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | echo 2 | 3 | echo "What is your project name?" 4 | read projectname 5 | 6 | 7 | # lowercase name, convert spaces to _ 8 | projectslug="$(echo -n "${projectname}" | sed -e 's/[^[:alnum:]]/_/g' \ 9 | | tr -s '_' | tr A-Z a-z)" 10 | echo "Using ${projectslug} (formatted automatically)" 11 | echo 12 | echo 13 | 14 | projectgit=${projectslug}.git 15 | localip=$(hostname -I | cut -f1 -d' ') 16 | projectDB="${projectslug}_db" 17 | projectDBuser="${projectslug}_user" 18 | 19 | 20 | 21 | echo "Install system dependencies? y/n" 22 | read doInstalls 23 | doInstallsResponse="$(echo -n "${doInstalls}" | sed -e 's/[^[:alnum:]]/-/g' \ 24 | | tr -s '_' | tr A-Z a-z)" 25 | 26 | echo "Use default blank django project? (y/n)" 27 | read defaultDjangoProject 28 | defaultDjangoProjectResponse="$(echo -n "${defaultDjangoProject}" | sed -e 's/[^[:alnum:]]/-/g' \ 29 | | tr -s '_' | tr A-Z a-z)" 30 | 31 | 32 | if [ "$defaultDjangoProject" != 'y' ] 33 | then 34 | echo "Setup production-ready git repo for project? y/n" 35 | read createGitRepo 36 | createGitRepoResponse="$(echo -n "${createGitRepo}" | sed -e 's/[^[:alnum:]]/-/g' \ 37 | | tr -s '_' | tr A-Z a-z)" 38 | fi 39 | 40 | echo "Create a postgresql database? (y/n)" 41 | read databaseCreate 42 | databaseCreateResponse="$(echo -n "${databaseCreate}" | sed -e 's/[^[:alnum:]]/-/g' \ 43 | | tr -s '_' | tr A-Z a-z)" 44 | 45 | 46 | customDBPW='false' 47 | newPassword=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) 48 | if [ "$databaseCreateResponse" == 'custom' ] 49 | then 50 | while true; do 51 | echo "What would you like the database password to be?" 52 | read -s -p "Password (typing hidden): " newPassword 53 | echo 54 | read -s -p "Confirm password (typing hidden): " password2 55 | customDBPW='true' 56 | echo 57 | [ "$newPassword" = "$password2" ] && break 58 | echo "Please try again" 59 | done 60 | fi 61 | 62 | 63 | 64 | echo "Add gunicorn service? (y/n)" 65 | read setupGunicorn 66 | setupGunicornResponse="$(echo -n "${setupGunicorn}" | sed -e 's/[^[:alnum:]]/-/g' \ 67 | | tr -s '_' | tr A-Z a-z)" 68 | 69 | 70 | echo "Add nginx? (y/n)" 71 | read setupNginx 72 | setupNginxResponse="$(echo -n "${setupNginx}" | sed -e 's/[^[:alnum:]]/-/g' \ 73 | | tr -s '_' | tr A-Z a-z)" 74 | 75 | 76 | echo "Add celery? (y/n)" 77 | read setupCelery 78 | setupCeleryResponse="$(echo -n "${setupCelery}" | sed -e 's/[^[:alnum:]]/-/g' \ 79 | | tr -s '_' | tr A-Z a-z)" 80 | 81 | 82 | 83 | 84 | echo 85 | echo "Your project name will be used as:" 86 | echo 87 | echo "Name: ${projectslug}" 88 | echo "IP: ${localip}" 89 | 90 | if [ "$defaultDjangoProjectResponse" == 'y' ] 91 | then 92 | echo 93 | echo "Using Default Django Project from:" 94 | echo "https://github.com/codingforentrepreneurs/CFE-Blank-Project" 95 | echo "If you setup git below (recommended)," 96 | echo "you'll be able to pull this project" 97 | echo "to work locally on it." 98 | fi 99 | 100 | 101 | if [ "$createGitRepoResponse" == 'y' ] || [ "$defaultDjangoProjectResponse" == 'y' ] 102 | then 103 | echo 104 | echo "Local Project details" 105 | echo "Repo: /var/repo/${projectgit}/" 106 | echo "Working Dir: /var/www/${projectslug}/" 107 | echo "Working Dir Symlink: ~/${projectslug}" 108 | echo "Remote: ssh://${USER}@${localip}/var/repo/${projectgit}" 109 | fi 110 | 111 | if [ "$databaseCreateResponse" == 'y' ] 112 | then 113 | echo 114 | echo "Database will be created with" 115 | echo "Database Name: ${projectDB}" 116 | echo "Database Username: ${projectDBuser}" 117 | if [ "$customDBPW" == 'false' ] 118 | then 119 | echo "Database password ${newPassword}" 120 | fi 121 | fi 122 | 123 | if [ "$setupNginxResponse" == 'y' ] 124 | then 125 | echo "Celery will be setup." 126 | fi 127 | 128 | if [ "$setupGunicornResponse" == 'y' ] 129 | then 130 | echo "Gunicorn will be setup." 131 | fi 132 | 133 | if [ "$setupCeleryResponse" == 'y' ] 134 | then 135 | echo "Celery will be setup." 136 | fi 137 | 138 | echo 139 | echo "Everything will be generated automatically based on the project name you gave." 140 | echo 141 | 142 | echo "Do you want to continue? y/n" 143 | read runSetup 144 | runSetupResponse="$(echo -n "${runSetup}" | sed -e 's/[^[:alnum:]]/-/g' \ 145 | | tr -s '_' | tr A-Z a-z)" 146 | 147 | if [ "$runSetupResponse" == "n" ] 148 | then 149 | echo 'Setup exited.' 150 | exit 151 | fi 152 | 153 | if [ "$doInstallsResponse" == "y" ] 154 | then 155 | echo 'Installing dependancies' 156 | echo 157 | echo 158 | sudo apt-get update -y 159 | 160 | sudo apt-get install build-essential libssl-dev libpq-dev libcurl4-gnutls-dev libexpat1-dev gettext unzip -y 161 | 162 | sudo apt-get install supervisor -y 163 | 164 | sudo apt-get install python3-pip python3-dev python3-venv -y 165 | 166 | sudo apt-get install nano -y 167 | 168 | sudo apt-get install git -y 169 | 170 | sudo apt-get install postgresql postgresql-contrib -y 171 | 172 | sudo apt-get install nginx curl -y 173 | 174 | sudo apt-get install ufw -y 175 | 176 | sudo ufw allow 'Nginx Full' 177 | 178 | sudo ufw allow ssh 179 | 180 | sudo python3 -m pip install virtualenv 181 | 182 | sudo service supervisor start 183 | 184 | sudo apt autoremove -y 185 | else: 186 | echo "Setup installs skipped" 187 | echo 188 | fi 189 | 190 | 191 | if [ "$createGitRepoResponse" == "y" ] || [ "$defaultDjangoProject" == 'y' ] 192 | then 193 | echo 'Creating working directory and git repo...' 194 | echo 195 | echo 196 | sudo mkdir /var/www/ 197 | sudo mkdir /var/www/${projectslug}/ 198 | cd ~/ 199 | ln -s /var/www/${projectslug}/ ~/ 200 | 201 | 202 | mkdir /var/repo/ 203 | mkdir /var/repo/${projectgit}/ 204 | cd /var/repo/${projectgit}/ 205 | if [ "$defaultDjangoProject" == 'y' ] 206 | then 207 | git clone https://github.com/codingforentrepreneurs/CFE-Blank-Project . --bare 208 | git --work-tree="/var/www/${projectslug}" --git-dir="/var/repo/${projectgit}" checkout -f 209 | virtualenv -p python3.6 /var/www/${projectslug} 210 | sudo rm /var/www/${projectslug}/src/cfehome/settings/local.py 211 | virtualenvbin="/var/www/${projectslug}/bin" 212 | $virtualenvbin/python -m pip install -r "/var/www/${projectslug}/src/requirements.txt" 213 | 214 | cat <> /var/repo/${projectgit}/hooks/post-receive 215 | git --work-tree=/var/www/${projectslug} --git-dir=/var/repo/${projectgit} checkout -f 216 | 217 | ${virtualenvbin}/python -m pip install -r /var/www/${projectslug}/src/requirements.txt 218 | 219 | rm /var/www/${projectslug}/src/cfehome/settings/local.py 220 | 221 | supervisorctl reread 222 | supervisorctl update 223 | 224 | EOT 225 | 226 | else 227 | git init --bare 228 | cat <> /var/repo/${projectgit}/hooks/post-receive 229 | git --work-tree=/var/www/${projectslug} --git-dir=/var/repo/${projectgit} checkout -f 230 | 231 | supervisorctl reread 232 | supervisorctl update 233 | EOT 234 | fi 235 | 236 | 237 | 238 | chmod +x /var/repo/${projectgit}/hooks/post-receive 239 | 240 | echo "Success. You can access your project on your server at:" 241 | echo 242 | echo "Be sure to run this on your local repo:" 243 | echo "git remote add live ssh://${USER}@${localip}/var/repo/${projectgit}" 244 | fi 245 | 246 | if [ "$defaultDjangoProject" == 'y' ] 247 | then 248 | cd /var/www/${projectslug}/ 249 | 250 | fi 251 | 252 | if [ "$databaseCreateResponse" == 'y' ] 253 | then 254 | echo 255 | echo 'Creating postgresql database.' 256 | echo 257 | echo "Create Root postgres user (ignore if fails)" 258 | cd /tmp 259 | 260 | sudo -u postgres createuser $USER 261 | 262 | sudo -u postgres createdb $USER 263 | #su postgres 264 | 265 | sudo -u postgres psql --command="CREATE DATABASE ${projectDB};" 266 | 267 | sudo -u postgres psql --command="CREATE USER ${projectDBuser} WITH PASSWORD '${newPassword}';" 268 | 269 | sudo -u postgres psql --command="ALTER ROLE ${projectDBuser} SET client_encoding TO 'utf8';" 270 | 271 | sudo -u postgres psql --command="ALTER ROLE ${projectDBuser} SET default_transaction_isolation TO 'read committed';" 272 | 273 | sudo -u postgres psql --command="ALTER ROLE ${projectDBuser} SET timezone TO 'UTC';" 274 | 275 | sudo -u postgres psql --command="GRANT ALL PRIVILEGES ON DATABASE ${projectDB} TO ${projectDBuser};" 276 | 277 | cd ~/ 278 | 279 | echo "Database created" 280 | echo "Database name: ${projectDB}" 281 | echo "Database username ${projectDBuser}" 282 | if [ "$customDBPW" == 'false' ] 283 | then 284 | echo "Database password ${newPassword}" 285 | fi 286 | if [ "$defaultDjangoProject" == 'y' ] 287 | then 288 | echo "Updating django project to include database settings" 289 | databaseSettingsPath="/var/www/${projectslug}/src/cfehome/settings/db_conf.py" 290 | databaseSettings="ALLOWED_HOSTS=['${localip}'] 291 | DATABASES = { 292 | 'default': { 293 | 'ENGINE': 'django.db.backends.postgresql', 294 | 'NAME': '${projectDB}', 295 | 'USER': '${projectDBuser}', 296 | 'PASSWORD': '${newPassword}', 297 | 'HOST': 'localhost', 298 | 'PORT': '', 299 | 300 | } 301 | }" 302 | echo "${databaseSettings}" > "${databaseSettingsPath}" 303 | echo "Django updated with Created Database Settings" 304 | 305 | ${virtualenvbin}/python /var/www/${projectslug}/src/manage.py migrate 306 | cd /var/www/${projectslug} 307 | source bin/activate 308 | cd src 309 | djangoPassword=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1) 310 | echo "from django.contrib.auth import get_user_model; User = get_user_model(); User.objects.create_superuser('admin', 'admin@myproject.com', '${djangoPassword}')" | python manage.py shell 311 | echo "Django Username: admin" 312 | echo "Django Password: ${djangoPassword}" 313 | fi 314 | fi 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | if [ "$setupGunicornResponse" == 'y' ] 323 | then 324 | echo 325 | echo 326 | echo "Creating gunicorn service in supervisor" 327 | sudo mkdir /var/log 328 | sudo mkdir /var/log/${projectslug}/ 329 | gunicornConfFile="/etc/supervisor/conf.d/${projectslug}-gunicorn.conf" 330 | echo "Your gunicorn supervisor file will located at:" 331 | echo "${gunicornConfFile}" 332 | echo 333 | supervisorText="[program:${projectslug}_gunicorn] 334 | user=${USER} 335 | directory=/var/www/${projectslug}/src/ 336 | command=${virtualenvbin}/gunicorn --workers 3 --bind unix:${projectslug}.sock cfehome.wsgi:application 337 | 338 | autostart=true 339 | autorestart=true 340 | stdout_logfile=/var/log/${projectslug}/gunicorn.log 341 | stderr_logfile=/var/log/${projectslug}/gunicorn.err.log" 342 | echo "${supervisorText}" > "${gunicornConfFile}" 343 | supervisorctl reread 344 | supervisorctl update 345 | fi 346 | 347 | 348 | 349 | 350 | if [ "$setupCeleryResponse" == 'y' ] 351 | then 352 | echo 353 | echo 354 | echo "Creating celery service in supervisor" 355 | sudo mkdir /var/log 356 | sudo mkdir /var/log/${projectslug}/ 357 | celeryConfFile="/etc/supervisor/conf.d/${projectslug}-celery.conf" 358 | echo "Your celery supervisor file will located at:" 359 | echo "${celeryConfFile}" 360 | echo 361 | supervisorText="[program:${projectslug}_celery] 362 | user=${USER} 363 | directory=/var/www/${projectslug}/src 364 | command=${virtualenvbin}/celery -A ${projectslug}.celery worker 365 | autostart=false 366 | autorestart=false 367 | stdout_logfile=/var/log/${projectslug}/celery.log 368 | stderr_logfile=/var/log/${projectslug}/celery.err.log" 369 | echo "${supervisorText}" > "${celeryConfFile}" 370 | supervisorctl reread 371 | supervisorctl update 372 | fi 373 | 374 | 375 | if [ "$setupNginxResponse" == 'y' ] 376 | then 377 | echo 378 | echo 379 | echo "Creating Nginx configuration file for Project" 380 | echo "Your nginx conf file will located at:" 381 | nginxFilePath="/etc/nginx/sites-available/${projectslug}.conf" 382 | nginxEnabledPath="/etc/nginx/sites-enabled/${projectslug}.conf" 383 | echo "${nginxFilePath}" 384 | echo 385 | nginxConfText="server { 386 | server_name ${localip}; 387 | listen 80; 388 | listen [::]:80; 389 | 390 | location / { 391 | include proxy_params; 392 | proxy_pass http://unix:/var/www/${projectslug}/src/${projectslug}.sock; 393 | proxy_buffer_size 128k; 394 | proxy_buffers 4 256k; 395 | proxy_read_timeout 60s; 396 | proxy_busy_buffers_size 256k; 397 | client_max_body_size 2M; 398 | } 399 | }" 400 | echo "${nginxConfText}" > "${nginxFilePath}" 401 | rm /etc/nginx/sites-enabled/default 402 | cp "${nginxFilePath}" "${nginxEnabledPath}" 403 | 404 | systemctl daemon-reload 405 | 406 | sudo systemctl reload nginx 407 | fi 408 | 409 | 410 | echo 411 | echo 412 | echo 413 | echo "//////// Final Summary \\\\\\\\\\\\\\\\" 414 | echo 415 | echo 416 | if [ "$databaseCreateResponse" == 'y' ] 417 | then 418 | echo "**Postgresql Database Created**" 419 | echo 420 | echo "Database name: ${projectDB}" 421 | echo "Database username ${projectDBuser}" 422 | if [ "$customDBPW" == 'false' ] 423 | then 424 | echo "Database password ${newPassword}" 425 | fi 426 | fi 427 | if [ "$createGitRepoResponse" == "y" ] || [ "$defaultDjangoProjectResponse" == "y" ] 428 | then 429 | echo 430 | echo "**Repo & Project Created**" 431 | echo 432 | echo "Your project is stored in" 433 | echo "/var/www/${projectslug}" 434 | echo "~/${projectslug}" 435 | echo 436 | echo "Update your local git repo to..." 437 | echo 438 | echo "git remote add live ssh://${USER}@${localip}/var/repo/${projectgit}" 439 | echo 440 | fi 441 | 442 | if [ "$defaultDjangoProjectResponse" == "y" ] 443 | then 444 | echo "Login URL: ${localip}/admin" 445 | echo "Django Username: admin" 446 | echo "Django Password: ${djangoPassword}" 447 | echo "You should change this password right away." 448 | fi 449 | 450 | 451 | 452 | --------------------------------------------------------------------------------