Skip to content

Instantly share code, notes, and snippets.

@kiasaki
Last active August 29, 2015 14:03
Show Gist options
  • Save kiasaki/0402aa041c5f53f4b171 to your computer and use it in GitHub Desktop.
Save kiasaki/0402aa041c5f53f4b171 to your computer and use it in GitHub Desktop.
vps-linux-nginx-postgres-php-stack

VPS LNPP Stack setup

Note to self, after fiddling with the same errors again and again while setting this up, I'm writing down what I repeat every time I setup a new droplet @ digitalocean.

1: Droplet creation

Create a new droplet @ cloud.digitalocean.com and, when created, copy the IP address to setup a domain name pointing to it right away.

I go at https://www.hover.com/domains and add an A record, I'll assume dev.domain.com in this guide.

2: Users

# Login by ssh with the root user and the password sent by email.
ssh root@dev.domain.com

# Add a new user called fred (setup a string password)
adduser fred

# Add it to the "sudo" unix group
adduser fred sudo

3: Logging in

Now we have an other user than root we can login with that one, let's do this now and setup a few utilities.

ssh fred@dev.domain.com

# Shell setup
sudo apt-get install git curl
git clone https://github.com/kiasaki/dotfiles.git
cd dotfiles && ./setup.sh

# Upload our public key so we can login easily
mkdir .ssh
sudo vim ~/.ssh/authorized_keys

# Generate an identity file for those private repos we will need to access
# And don't put any password so we can use it whitout interaction
ssh-keygen -t rsa

4: Install libs/dependancies

sudo apt-get install apache2-utils
sudo apt-get install nginx
sudo apt-get install postgres postgres-contrib
sudo apt-get install php5-cli php5-fpm php5-mcrypt php5-gd php5-pgsql php5-curl

5: Setting up git deploy

mkdir -p ~/repo/<app>.git
cd ~/repo/<app>.git
git init --bare
curl -o hooks/post-receive https://gist.githubusercontent.com/kiasaki/00a3044d12956a828e76/raw/1b26f63f309e9afaad89fcb127e8e9c147ee402c/post-receive
vim hooks/post-receive
chmod +x hooks/post-receive

6: Setup composer

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/bin/composer

7: Setup postgres

# Enter postgres
sudo -u postgres psql

Now let's create a user and a database

CREATE USER <dbuser> WITH PASSWORD '<dbpass>';
CREATE DATABASE <dbname>;
GRANT ALL PRIVILEGES ON DATABASE <dbname> TO <dbuser>;
\q

8: Setup web root

sudo mkdir -p /var/www/<app>/current
sudo chmod -R 755 /var/www/<app>/
sudo chown -R www-data:www-data /var/www/<app>/

# Maybee
# setfacl -Rm d:u:userA:rwX,u:userA:rwX /var/www

Now might be the right time to review that post-receive hook to see if it matches the folders newly created.

Next step is to test the deploy hook to bring the app files on the server

# On your local machine
git remote add live fred@dev.domain.com:repo/<app>.git
git push live master
# or
git push live <current branch>:master

9: Nginx config

Here is a simple nginx config for a php website, if it is in the website root we can link it using:

sudo ln -s /var/www/<app>/current/nginx.conf /etc/nginx/sites-enabled/<app>
sudo service nginx restart

https://gist.githubusercontent.com/kiasaki/f72fc18e76352a7e49bc/raw/5f92b5b6ae1c3d23b7ef6ef4863c276ef49790b9/nginx-php-website

10: Nginx self-signed SSL

sudo mkdir /etc/nginx/ssl
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/server.key -out /etc/nginx/ssl/server.crt

11: Postgres Backups

https://github.com/epicserve/s3-backups

sudo apt-get install python-pip
sudo pip install s3-backups

sudo curl -o /usr/local/bin/postgres_to_s3.py https://raw.githubusercontent.com/epicserve/s3-backups/master/s3_backups/postgres_to_s3.py

sudo vim /etc/cron.d/postgres_to_s3

# Add this:
0 */1 * * * postgres /usr/local/bin/postgres_to_s3.py --AWS_ACCESS_KEY_ID='xxxxxxxxxxxxxxxxxxxx' --AWS_SECRET_ACCESS_KEY='xxxxxxxxxxxxxxxxxxxx' --S3_BUCKET_NAME='my-backup-bucket' --S3_KEY_NAME='postgres/my-awesome-server' --backup --archive

12: Logentries

wget https://raw.github.com/logentries/le/master/install/linux/logentries_install.sh && sudo bash logentries_install.sh

Then make sure log files are readable and:

le register
le monitor
le follow /var/log/nginx/error.log
sudo service logentries restart

Mysql

$ sudo mysql -p
CREATE USER 'user'@'localhost' IDENTIFIED BY '';
CREATE DATABASE transax;
GRANT ALL ON transax.* TO 'transax'@'localhost';
user www-data;
worker_processes 8;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
# Dependencies
apt-get update -q
apt-get --force-yes -y -q install git curl
apt-get --force-yes -y -q install apache2-utils
apt-get --force-yes -y -q install nginx
apt-get --force-yes -y -q install php5-cli php5-fpm php5-mcrypt php5-gd php5-pgsql php5-curl
apt-get --force-yes -y -q install acl
apt-get update -q
# Use aws - sudo apt-get install postgresql-9.3 postgresql-contrib-9.3
# Composer
curl -sS https://getcomposer.org/installer | php
mv composer.phar /usr/bin/composer
# User setup
adduser --disabled-password --gecos "" ubuntu
adduser ubuntu sudo
adduser ubuntu www-data
su - ubuntu -c 'mkdir /home/ubuntu/.ssh'
su - ubuntu -c 'touch /home/ubuntu/.ssh/authorized_keys'
su - ubuntu -c 'git clone https://github.com/kiasaki/dotfiles.git /home/ubuntu/dotfiles'
su - ubuntu -c 'chmod +x /home/ubuntu/dotfiles/setup.sh'
su - ubuntu -c '/home/ubuntu/dotfiles/setup.sh'
# www directory
appname=$APP_NAME
mkdir -p "/var/www/$appname/current/"
chmod -R 755 "/var/www/$appname/"
chown -R www-data:www-data "/var/www/$appname/"
setfacl -Rm d:u:www-data:rwX,u:www-data:rwX /var/www
setfacl -Rm d:u:ubuntu:rwX,u:ubuntu:rwX /var/www
ln -s "/var/www/$appname/current/nginx.conf" "/etc/nginx/sites-enabled/$appname"
rm -f /etc/nginx/nginx.conf
curl -o /etc/nginx/nginx.conf https://gist.githubusercontent.com/kiasaki/0402aa041c5f53f4b171/raw/4650322aaa76a9fc05f03e5f526c17dfbed6d24c/nginx.conf
service nginx restart
# Copy ssh pub key for ubuntu user
cat /root/.ssh/authorized_keys >> /home/ubuntu/.ssh/authorized_keys
# Git push setup
su - ubuntu -c "mkdir /home/ubuntu/repo"
su - ubuntu -c "mkdir /home/ubuntu/repo/${appname}.git"
su - ubuntu -c "cd /home/ubuntu/repo/${appname}.git && git init --bare"
su - ubuntu -c "curl -o /home/ubuntu/repo/${appname}.git/hooks/post-receive https://gist.githubusercontent.com/kiasaki/00a3044d12956a828e76/raw/988a8bb1b0f42d0f41459adf8c97f28701bbd78f/post-receive"
su - ubuntu -c "chmod +x /home/ubuntu/repo/${appname}.git/hooks/post-receive"
# Allow sudo with no password
rm -f /etc/sudoers
curl -o /etc/sudoers https://gist.githubusercontent.com/kiasaki/0402aa041c5f53f4b171/raw/dfe606ff10cea14966061e76bbbe9a86e06fc163/sudoers
# Postgresql
# sudo apt-get install postgresql-9.3
Defaults env_reset
Defaults mail_badpass
Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) NOPASSWD:ALL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment