Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
diyarit authored May 14, 2021
0 parents commit a3610da
Show file tree
Hide file tree
Showing 32 changed files with 996 additions and 0 deletions.
150 changes: 150 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
## simple Centos Laravel stack for Zero-Downtime deployment

### Installs a fresh server with
* CentOS
* Nginx and virtual hosts
* Php fpm & cli, composer
* Node, npm, yarn
* Redis
* Basic security
* Add (multiple) laravel projects (any laravel version) with Zero-Downtime deployment

The scripts are all bash, and kept very simple so you can tweak them to your needs if you want to.

Very easy project deployment by calling the project's ```puller``` script

### how to install

* bring up a bare centos 8 server somewhere
* ssh as root and run:

```bash
yum -y install tar
curl -s -L https://github.com/diyarit/laravel-stack-deployer-centos/archive/refs/tags/1.0.tar.gz | tar -xz
cd laravel-stack-deployer-centos-1.0
./setup_full
```

That's it. Now you can add laravel apps:

### Add a new laravel app with Zero Downtime Deployment
Log in as the default (created) user and run
```
addzhost <<domain>> <<git repository>> <<initial tag>>
```

#### Note:
You need access privileges from this server on the repository.
- For github or gitlab, Go to settings->ssh keys and add the contents of ```~/.ssh/id_rsa.pub``` to a new ssh key.

#### Example:

```$ addzhost myapp.example.com [email protected]:myprojects/myapp.git v1.0.3```
Now you can browse to myapp.example.com and enjoy your v1.0.3 release (make sure DNS has been set up)


- adds ```/var/www/myapp.example.com``` for the laravel app (make sure to configure DNS to the IP of this server)
- creates a nginx config in ```/etc/nginx/sites-available``` and enables it
- creates ```/var/www/myapp.example.com/releases``` dir for each inidividual release
- creates ```/var/www/myapp.example.com/storage``` dir which is linked into each release
- creates (stub) ```/var/www/myapp.example.com/.env``` file which is linked into each release. Tweak this to your needs.


- generates a ```puller``` script (in /var/www/myapp.example.com) to pull a version (tag) from the repository and release it
- generates a ```rollback``` script to roll back to a previous release (any of the releases available in the releases dir)
- uses ```puller``` to release the initial tag into production. if it fails you can rollback everything and try again.

#### puller
Usage: ```$ /var/www/[domain]/puller [tag]```

Puller is generated by addzhost on the top project directory: ```/var/www/[domain]/puller```

- Creates a new release in the releases directory and uses ```git archive``` to download the release
- create symbolic links of ```/var/www/[domain]/storage``` and ```/var/www/[domain]/.env``` into the release
- runs ```composer install```
- You can create a custom post-deployment script in the root of your repository called ```after_deploy``` with your own artisan/composer/npm commands.
a typical after_deploy could look like this
```
echo "DEPLOY"
php artisan migrate --force
yarn install
yarn run production
```
- Makes sure everything has the right chown and chmod applied
- swaps the ```/var/www/[domain]/current``` link towards the new release to make it available with zero downtime

If any of the steps failed ```puller``` aborts before making the release current.

You can call ```puller``` from your local development machine for further integration:

```
server=[user]@[host]
dir=[deploy directory]
tag=`git describe --abbrev=0 --tags` # latest tag
echo "$dir/puller $tag;" | ssh $server
```

#### rollback (generated by addzhost)
Usage: rollback [tag]

Rollback is generated by addzhost on the top project directory: ```/var/www/[domain]/rollback```

- swaps the /var/www/[domain]/current link to the old release to make it available with zero downtime

### Overview of individual installation parts run by ```setup_full```

parts are numbered to show the order in which they should be run.

#### 01 user create
create the default user and allow sudo. Block using passwords and only allow access using your public key for security.

* asks for username
* asks for ssh public key to access this account remotely. Paste the contents of your ~/.ssh/id_rsa.pub

#### 02 set hostname
changes the hostname

#### 03 repos and yums
Add remi and epel repo, updates the system and ```yum``` the basics

#### 04 root password
secures the root user

#### 05 security
firewalls, sshd security and fail2ban - disable password logins and secure it further with ```fail2ban```

#### 06 global settings
color prompts, timezone settings, ntp server, fortune and cowsay (just for fun)

#### 07 php
Set up php 74 including fpm and composer

#### 08 node and npm
Installs node, npm and yarn

#### 09 mysql / mariadb
installs mariadb and sets it up for production

* MariaDB asks some questions during install, like the root password to be used

#### 10 nginx
set up nginx for php-fpm and prepare for multiple virtual hosts with the sites-enabled/sites-available pattern

#### 11 laravel
Actually no laravel project is installed, but everything is prepared for adding a zero-downtime-deployment project using the ```addzhost``` command

#### 12 redis
Optionally install redis

#### Finally
logout as root. At this moment the server is ready for project deployments but none is deployed yet.


### extra utilities in ~/bin
* artisan - shortcut to ```php artisan```
* clear-laravel - clears all possible caches and restores path permissions
* logtail - tails the latest laravel log for a live logview (from any laravel top directory)
* dbRemote2local - copy a remote mysql database to a local database



2 changes: 2 additions & 0 deletions VERSION
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
version=v1.0
date="Wed May 12 2021"
12 changes: 12 additions & 0 deletions parts/00_settings
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

## common stuff
RED='\033[0;101m'
GREEN='\033[0;102m'
NC='\033[0m'

logline () {
echo -e "${GREEN} >>>> $1 ${NC}"
}


72 changes: 72 additions & 0 deletions parts/01_user_create
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash

. ${BASH_SOURCE%/*}/00_settings

logline "01.00 user create START"
while [ -z "$username" ]; do
echo -n "Enter username to create and setup as sudoer =>" && read username
done

while [ -z "$pubkey" ]; do
echo "Paste your public key for ssh access"
read pubkey
done

export username

logline "01.01 add user"
## add the user and lock the password
adduser $username -m -n && passwd $username -l

logline "01.02 setup ssh, bin and some settings"
## set user's ssh
su $username <<-'EOF'
mkdir ~/.ssh/
touch ~/.ssh/authorized_keys && chmod 0600 ~/.ssh/authorized_keys
# add deploy key for the machine
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
chmod 0700 ~/.ssh
# lets make a ~/bin and add it to the path
mkdir ~/bin
echo "export PATH=\$PATH:~/bin" >> ~/.bashrc
# lets make a ~/crontab
mkdir ~/crontab
## get rid of unreadable vim colorcoding
echo -e "syntax off\nset t_ti= t_te= \n" >> ~/.vimrc
EOF
echo -e "\n$pubkey\n" >>/home/$username/.ssh/authorized_keys

logline "01.06 add $username to sudoers"
## add user to sudoers
chmod u+w /etc/sudoers
echo "$username ALL=(ALL) NOPASSWD: ALL" >>/etc/sudoers
chmod u-w /etc/sudoers

logline "01.07 copy user scripts"
cp -R ${BASH_SOURCE%/*}/userbin/* /home/$username/bin

logline "01.08 install the indispensable 'z' tool"
# do we have wget yet?
yum -d1 -y install wget
# install https://github.com/rupa/z
wget https://raw.githubusercontent.com/rupa/z/master/z.sh
mv ./z.sh /home/$username/bin
printf "\n\n#initialize Z (https://github.com/rupa/z) \n. ~/bin/z.sh \n\n" >> .bashrc

logline "01.09 ~/bin: change permissions and make executabe"
chown -R $username:users /home/$username/bin
chmod -R a+x /home/$username/bin

logline "01.10 create user crontab"
cp -R ${BASH_SOURCE%/*}/usercron/* /home/$username/crontab
chown -R $username:users /home/$username/crontab
chmod a+x /home/$username/crontab/every*
# start the cron for user
su $username -l -c "cd crontab;crontab crondef"

logline "01.99 user create END"

13 changes: 13 additions & 0 deletions parts/02_set_hostname
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

. ${BASH_SOURCE%/*}/00_settings

logline "02.00 set hostname"
while [ -z "$hostname" ]; do
echo -n "Enter a hostname >" && read hostname
done

## lets name the host
hostnamectl set-hostname $hostname
logline "02.99 set hostname END"

26 changes: 26 additions & 0 deletions parts/03_repos_yums
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash

. ${BASH_SOURCE%/*}/00_settings

logline "03.00 install EPEL and REMI repos and yum standard packages"

logline "03.01 add repos"
yum -d1 -y install epel-release
yum -d1 -y install wget
dnf install -y https://rpms.remirepo.net/enterprise/remi-release-8.rpm
yum -q repolist

logline "03.02 update system - this can take a while.."
yum -y update

logline "03.03 yum some sysop and dev tools"
yum -d1 -y install htop iotop ncdu pv unzip gcc autoconf automake gcc-c++ make git
## optional BIG development install
## yum groupinstall "Development Tools"

logline "03.04 add gh command to git for push to github (origin)"
git config --global alias.gh '!f() { git add -A && git commit -m "${@:-incremental}" && git push; }; f'


logline "03.99 repos and yums END"

19 changes: 19 additions & 0 deletions parts/04_root_password
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

. ${BASH_SOURCE%/*}/00_settings

logline "04.00 start root security"
logline "04.01 secure password or locked password"
echo -n "Do you want a long secure root password (l) or no password at all (n) [L/n]=>" && read rootpas
if [ "$rootpas" = "n" ]; then
passwd root -l
else
## create long (emergency) password for root
newpas=`tr -dc A-Z-a-z0-9 < /dev/urandom | head -c${1:-32}`
echo $newpas | passwd root --stdin
echo ">>>>>>>>> ROOT password set to $newpas - you might want to write this down"
echo -n "Enter to continue >" && read
fi
logline "04.99 root secured"


71 changes: 71 additions & 0 deletions parts/05_security
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/bin/bash

. ${BASH_SOURCE%/*}/00_settings

logline "05.00 security"

logline "05.01 ssh security"

sshtemp=`mktemp`
cat /etc/ssh/sshd_config | sed -e "s/PasswordAuthentication yes/PasswordAuthentication no/" >$sshtemp

cat <<-'EOF' >>$sshtemp
PermitRootLogin no
Protocol 2
UsePrivilegeSeparation yes
SyslogFacility AUTH
LogLevel INFO
StrictModes yes
PubkeyAuthentication yes
IgnoreRhosts yes
HostbasedAuthentication no
PermitEmptyPasswords no
X11Forwarding no
GatewayPorts no
PrintMotd no
TCPKeepAlive yes
PasswordAuthentication no
EOF
mv -f $sshtemp /etc/ssh/sshd_config
systemctl restart sshd.service


logline "05.02 firewall"
systemctl enable firewalld
systemctl start firewalld
# add port 80 and 443
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=443/tcp --permanent
firewall-cmd --reload
# show overview
firewall-cmd --list-all

logline "05.03 fail2ban"
yum -y install fail2ban
cat <<-'EOF' >/etc/fail2ban/jail.local
[sshd]
enabled = true
maxretry = 3
bantime = 86400
EOF
systemctl start fail2ban
systemctl enable fail2ban

logline "05.04 SeLinux"
echo -n "SELinux adds a bit of extra security but a PITA to administer. Use SeLinux [y/N]=>" && read selinux
selinuxconf='/etc/selinux/config'
setemp=`mktemp`
if [ "$selinux" = "y" ]; then
cat $selinuxconf |
sed -e "s/SELINUX=/\nSELINUX=enforcing\n#SELINUX=/" >$setemp
else
cat $selinuxconf |
sed -e "s/SELINUX=/\nSELINUX=disabled\n#SELINUX=/" >$setemp
export rebootOnExit=Y

fi
mv -f $setemp $selinuxconf
echo "You must reboot(!) your machine to use the new SeLinux setting"

logline "05.99 security END"

Loading

0 comments on commit a3610da

Please sign in to comment.