Last active
April 19, 2024 19:31
-
-
Save kidGodzilla/aa0b80644b684db8bfd38b411016c888 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
###################################################################### | |
# This Bootstrap Script installs Dokku latest on Ubuntu (use LTS or latest) | |
# | |
# This script also installs UFW (firewall), some basic Dokku plugins, and | |
# raises ulimits. Comment out any step you wish to skip. | |
# | |
# IMPORTANT: This script also disables password authentication via SSH for | |
# subsequent logins (a recommended hardening step). Don't forget to add your SSK | |
# key to your server before logging out! | |
###################################################################### | |
# See Comments in the related GitHub Gist below for installation instructions | |
###################################################################### | |
# DOKKU_TAG=v0.32.4 | |
# Ensure we are running as root | |
check_root() { | |
if [ "$USER" != "root" ]; then | |
echo "Permission Denied" | |
echo "Can only be run by root" | |
exit | |
fi | |
} | |
# Create a keys file if one does not already exist | |
create-keys-file() { | |
mkdir -p ~/.ssh | |
touch ~/.ssh/authorized_keys | |
} | |
# Update apps | |
apt-get-update() { | |
sudo apt-get update | |
} | |
# Set up automatic updates | |
automatic-updates() { | |
# Ubuntu | |
sudo apt install unattended-upgrades apt-listchanges bsd-mailx -y | |
# sudo dpkg-reconfigure -plow unattended-upgrades -y | |
sudo DEBIAN_FRONTEND=noninteractive dpkg-reconfigure --priority=low unattended-upgrades | |
echo 'Unattended-Upgrade::Automatic-Reboot "true";' >> /etc/apt/apt.conf.d/50unattended-upgrades | |
sudo unattended-upgrades --dry-run | |
} | |
raise-ulimits() { | |
if ! grep -q "fs.file-max = 65535" "/etc/sysctl.conf"; then | |
echo "fs.file-max = 65535" >> /etc/sysctl.conf | |
echo "fs.nr_open = 65535" >> /etc/sysctl.conf | |
echo "session required pam_limits.so" >> /etc/pam.d/common-session | |
echo "* soft nproc 65535" >> su | |
echo "* hard nproc 65535" >> /etc/security/limits.conf | |
echo "* soft nofile 65535" >> /etc/security/limits.conf | |
echo "* hard nofile 65535" >> /etc/security/limits.conf | |
echo "root soft nproc 65535" >> /etc/security/limits.conf | |
echo "root hard nproc 65535" >> /etc/security/limits.conf | |
echo "root soft nofile 65535" >> /etc/security/limits.conf | |
echo "root hard nofile 65535" >> /etc/security/limits.conf | |
echo "* soft nproc 65535" >> /etc/security/limits.conf | |
echo "* hard nproc 65535" >> /etc/security/limits.conf | |
echo "* soft nofile 65535" >> /etc/security/limits.conf | |
echo "* hard nofile 65535" >> /etc/security/limits.conf | |
echo "root soft nproc 65535" >> /etc/security/limits.conf | |
echo "root hard nproc 65535" >> /etc/security/limits.conf | |
echo "root soft nofile 65535" >> /etc/security/limits.conf | |
echo "root hard nofile 65535" >> /etc/security/limits.conf | |
u | |
ulimit -n 65535 | |
fi | |
} | |
# Disable password-based SSH authentication | |
disable-password-authentication() { | |
# Disable password authentication | |
sudo grep -q "ChallengeResponseAuthentication" /etc/ssh/sshd_config && sed -i "/^[^#]*ChallengeResponseAuthentication[[:space:]]yes.*/c\ChallengeResponseAuthentication no" /etc/ssh/sshd_config || echo "ChallengeResponseAuthentication no" >> /etc/ssh/sshd_config | |
sudo grep -q "^[^#]*PasswordAuthentication" /etc/ssh/sshd_config && sed -i "/^[^#]*PasswordAuthentication[[:space:]]yes/c\PasswordAuthentication no" /etc/ssh/sshd_config || echo "PasswordAuthentication no" >> /etc/ssh/sshd_config | |
/etc/init.d/ssh reload | |
} | |
# Get Dokku if not already installed | |
install-dokku() { | |
if ! command -v dokku &> /dev/null | |
then | |
wget https://dokku.com/bootstrap.sh; | |
sudo bash bootstrap.sh | |
fi | |
} | |
# Check that dokku is installed on the server | |
ensure-dokku() { | |
if ! command -v dokku &> /dev/null | |
then | |
echo "dokku is not installed" | |
exit | |
fi | |
} | |
# Install UFW | |
install-firewall() { | |
apt-get install ufw | |
ufw enable && sudo ufw allow www && sudo ufw allow https | |
(yes | sudo ufw allow ssh) | |
sudo ufw status | |
} | |
# Install Fail2Ban | |
install-fail2ban() { | |
sudo apt-get install fail2ban -y | |
if command -v fail2ban &> /dev/null | |
then | |
sudo systemctl restart fail2ban | |
# sudo fail2ban-client status | |
fi | |
} | |
# Make directories for db import/export | |
make-dirs() { | |
cd ~ | |
if [ ! -d "$HOME/dumps" ]; then | |
mkdir dumps | |
cd dumps | |
mkdir postgres | |
mkdir mysql | |
mkdir redis | |
mkdir mongo | |
cd ~ | |
fi | |
} | |
# Check if dokku redis plugin is installed and otherwise install it | |
install-redis() { | |
if sudo dokku plugin:installed redis; then | |
echo "=> Redis plugin already installed skipping" | |
else | |
echo "=> Installing redis plugin" | |
sudo dokku plugin:install https://github.com/dokku/dokku-redis.git redis | |
fi | |
} | |
# Check if dokku postgres plugin is installed and otherwise install it | |
install-postgres() { | |
if sudo dokku plugin:installed postgres; then | |
echo "=> Postgres plugin already installed skipping" | |
else | |
echo "=> Installing postgres plugin" | |
sudo dokku plugin:install https://github.com/dokku/dokku-postgres.git postgres | |
fi | |
} | |
# Check if dokku MySQL plugin is installed and otherwise install it | |
install-mysql() { | |
if sudo dokku plugin:installed mysql; then | |
echo "=> Postgres plugin already installed skipping" | |
else | |
echo "=> Installing mysql plugin" | |
sudo dokku plugin:install https://github.com/dokku/dokku-mysql.git mysql | |
fi | |
} | |
# Check if dokku mongo plugin is installed and otherwise install it | |
install-mongo() { | |
if sudo dokku plugin:installed mongo; then | |
echo "=> Postgres plugin already installed skipping" | |
else | |
echo "=> Installing mongo plugin" | |
sudo dokku plugin:install https://github.com/dokku/dokku-mongo.git mongo | |
fi | |
} | |
# Check if dokku memcached plugin is installed and otherwise install it | |
install-memcached() { | |
if sudo dokku plugin:installed memcached; then | |
echo "=> Memcached plugin already installed skipping" | |
else | |
echo "=> Installing memcached plugin" | |
sudo dokku plugin:install https://github.com/dokku/dokku-memcached.git memcached | |
fi | |
} | |
# Check if dokku clickhouse plugin is installed and otherwise install it | |
install-clickhouse() { | |
if sudo dokku plugin:installed clickhouse; then | |
echo "=> Clickhouse plugin already installed skipping" | |
else | |
echo "=> Installing clickhouse plugin" | |
sudo dokku plugin:install https://github.com/dokku/dokku-clickhouse.git clickhouse | |
fi | |
} | |
# Install Letsencrypt plugin | |
install-letsencrypt() { | |
if [ ! -d "/var/lib/dokku/plugins/available/letsencrypt" ]; then | |
sudo dokku plugin:install https://github.com/dokku/dokku-letsencrypt.git | |
dokku letsencrypt:cron-job --add | |
fi | |
} | |
# Install custom dokku limited users plugin | |
install-limited-users() { | |
if [ ! -d "/var/lib/dokku/plugins/available/limited-users" ]; then | |
sudo dokku plugin:install https://github.com/kidGodzilla/dokku-limited-users.git | |
fi | |
} | |
main() { | |
check_root | |
# Get user ip and export to environment variable | |
DOKKU_SSH_HOST=$(curl ifconfig.co) | |
SERVER_IP=$(curl ipinfo.io/ip) | |
# Basics | |
apt-get-update | |
install-firewall | |
# Add access key | |
create-keys-file | |
# Hardening | |
disable-password-authentication | |
# Install Dokku | |
install-dokku | |
make-dirs | |
# Ensure dokku was installed | |
ensure-dokku | |
# dokku databases & plugins | |
install-redis | |
install-postgres | |
install-mysql | |
install-mongo | |
install-letsencrypt | |
# install-limited-users | |
install-clickhouse | |
install-memcached | |
# Additional Configuration | |
# automatic-updates | |
# raise-ulimits | |
# install-fail2ban | |
} | |
main |
Using Dokku
Creating an App (on your Dokku server)
dokku apps:create appname
Add domains to your App (on your Dokku server)
dokku domains:add appname domainname.com domainname2.com sub.domainname.com
Deploying your App
# Add the remote before your first push
git remote add dokku dokku@1.1.1.1:appname
# Use this command every time you push new changes, to deploy
git push dokku main:master
Optional (but recommended)
Install Dokku CLI locally (macOS)
This lets you interact with your Dokku server(s) from the command line of your local repository, so you can view logs, update domains, restart your app, etc. without SSH into your server.
brew install dokku/repo/dokku
Then, for example, inside your project (where you've already added a git remote) you can:
dokku domains:report # list domains
dokku domains:add domainname.com # add a domain
dokku logs # view logs
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
What is Dokku?
Dokku gives you all the tools you need to manage Docker like any other PaaS you've used (Heroku, Vercel, etc). But instead of paying a monthly fee, you own it, and the servers your code run on.
Since it's powered by Docker, it already has plugins to create and manage any database you could imagine, and you can run pretty much anything.
I like to recommend it because it takes less than 5 minutes to learn how it works, and within a few days you'll be an expert. No black box / mystery, it's all open source and very simple.
Installing
sudo su
before running the script:Don't have a Public / Private Keypair?
Type the following command to generate a new SSH key pair:
You can choose the default options, and you do not need to create a passphrase.
This will generate two files, by default called
id_ed25519
andid_ed25519.pub
in your~/.ssh/
directory.Next, copy this key to your server.
Before running
server_bootstrap.sh
, test SSH without a password to ensure you still have access to the server via Public/Private Keypair: