diff --git a/server/caddy.service b/server/caddy.service new file mode 100644 index 00000000..6091f01d --- /dev/null +++ b/server/caddy.service @@ -0,0 +1,33 @@ +# This service originally copied from: +# https://raw.githubusercontent.com/caddyserver/dist/master/init/caddy.service + +# caddy.service +# +# For using Caddy with a config file. +# +# Make sure the ExecStart and ExecReload commands are correct +# for your installation. +# +# See https://caddyserver.com/docs/install for instructions. + +[Unit] +Description=Caddy +Documentation=https://caddyserver.com/docs/ +After=network.target network-online.target +Requires=network-online.target + +[Service] +Type=notify +User=caddy +Group=caddy +ExecStart=/usr/bin/caddy run --config /home/caddy/Caddyfile +ExecReload=/usr/bin/caddy reload --config /home/caddy/Caddyfile +TimeoutStopSec=5s +LimitNOFILE=1048576 +LimitNPROC=512 +PrivateTmp=true +ProtectSystem=full +AmbientCapabilities=CAP_NET_BIND_SERVICE + +[Install] +WantedBy=multi-user.target diff --git a/server/cinera.service b/server/cinera.service new file mode 100644 index 00000000..c8eabf6b --- /dev/null +++ b/server/cinera.service @@ -0,0 +1,15 @@ +[Unit] +Description=Miblo's Cinera program +After=network-online.target nss-lookup.target + +[Service] +Type=forking +User=annotations +Group=annotations +ExecStart=/home/hmn/hmn/cinera/start.sh +ExecStop=/home/hmn/hmn/cinera/stop.sh +PIDFile=/home/hmn/hmn/cinera/data/cinera.pid +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/server/deploy.sh b/server/deploy.sh index 1ab2d1e2..82136c43 100755 --- a/server/deploy.sh +++ b/server/deploy.sh @@ -1,8 +1,7 @@ #!/bin/bash -# This script should be called with the name -# of the branch to deploy. ($1 will be the -# branch name.) +# This script should be called with the name of the branch to deploy. ($1 will +# be the branch name.) set -euo pipefail @@ -11,13 +10,13 @@ set -euo pipefail pushd /home/hmn/hmn git fetch --all git reset --hard $1 - go build -o hmn src/main.go + go build -o /home/hmn/bin/hmn src/main.go popd SCRIPT -monit stop hmn +systemctl stop hmn sudo -u hmn bash -s <<'SCRIPT' set -euo pipefail -/home/hmn/hmn/hmn migrate +/home/hmn/bin/hmn migrate SCRIPT -monit start hmn +systemctl start hmn diff --git a/server/hmn.service b/server/hmn.service new file mode 100644 index 00000000..19de531c --- /dev/null +++ b/server/hmn.service @@ -0,0 +1,13 @@ +[Unit] +Description=The Handmade Network website +After=network-online.target nss-lookup.target + +[Service] +User=hmn +Group=hmn +ExecStart=/home/hmn/bin/hmn +Restart=always +TimeoutStopSec=15 + +[Install] +WantedBy=multi-user.target diff --git a/server/monitrc b/server/monitrc index 0517daab..9debc945 100644 --- a/server/monitrc +++ b/server/monitrc @@ -1,8 +1,12 @@ SET DAEMON 5 SET LOGFILE /var/log/monit.log SET STATEFILE /var/lib/monit/state -SET HTTPD UNIXSOCKET /var/run/monit.sock - allow user:pass +#SET HTTPD UNIXSOCKET /var/run/monit.sock +# allow user:pass +SET HTTPD PORT 2812 AND + USE ADDRESS localhost + ALLOW localhost + ALLOW admin:monit SET MAILSERVER box.handmadedev.org PORT 587 diff --git a/server/serversetup.sh b/server/serversetup.sh index 16fc0822..462aa4e1 100755 --- a/server/serversetup.sh +++ b/server/serversetup.sh @@ -2,155 +2,252 @@ set -euxo pipefail -BLACK_BOLD=$'\e[1;30m' +BLUE_BOLD=$'\e[1;34m' RESET=$'\e[0m' +checkpoint=$(cat ./hmn_setup_checkpoint || echo 0) + +savecheckpoint() { + echo $1 > ./hmn_setup_checkpoint +} + # Add swap space # https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-20-04 -fallocate -l 1G /swapfile -chmod 600 /swapfile -mkswap /swapfile -swapon /swapfile -swapon --show -echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab -sysctl vm.swappiness=10 -sysctl vm.vfs_cache_pressure=50 -echo 'vm.swappiness=10' >> /etc/sysctl.conf -echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf +if [ $checkpoint -lt 10 ]; then + savecheckpoint 10 + + fallocate -l 1G /swapfile + chmod 600 /swapfile + mkswap /swapfile + swapon /swapfile + swapon --show + echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab + sysctl vm.swappiness=10 + sysctl vm.vfs_cache_pressure=50 + echo 'vm.swappiness=10' >> /etc/sysctl.conf + echo 'vm.vfs_cache_pressure=50' >> /etc/sysctl.conf +fi # Configure Linux users -groupadd --system caddy -useradd --system \ - --gid caddy \ - --create-home --home-dir /home/caddy \ - caddy -groupadd --system hmn -useradd --system \ - --gid hmn \ - --create-home --home-dir /home/hmn \ - hmn -groupadd --system annotations -useradd --system \ - --gid annotations \ - --create-home --home-dir /home/annotations \ - annotations +if [ $checkpoint -lt 20 ]; then + savecheckpoint 20 + + groupadd --system caddy + useradd --system \ + --gid caddy \ + --shell /bin/bash \ + --create-home --home-dir /home/caddy \ + caddy + groupadd --system hmn + useradd --system \ + --gid hmn \ + --shell /bin/bash \ + --create-home --home-dir /home/hmn \ + hmn + groupadd --system annotations + useradd --system \ + --gid annotations \ + --shell /bin/bash \ + --create-home --home-dir /home/annotations \ + annotations +fi # Install important stuff -apt update -apt install -y \ - build-essential monit \ - libcurl4-openssl-dev byacc flex +if [ $checkpoint -lt 30 ]; then + savecheckpoint 30 + + apt update + apt install -y \ + build-essential \ + libcurl4-openssl-dev byacc flex +fi # Install Go -wget https://golang.org/dl/go1.17.linux-amd64.tar.gz -tar -C /usr/local -xzf go1.17.linux-amd64.tar.gz -echo 'PATH=$PATH:/usr/local/go/bin:/root/go/bin' >> ~/.profile -source ~/.profile +if [ $checkpoint -lt 40 ]; then + savecheckpoint 40 + + wget https://golang.org/dl/go1.17.linux-amd64.tar.gz + tar -C /usr/local -xzf go1.17.linux-amd64.tar.gz + echo 'PATH=$PATH:/usr/local/go/bin:/root/go/bin' >> ~/.bash_profile + source ~/.bash_profile +fi # Install Caddy # https://www.digitalocean.com/community/tutorials/how-to-host-a-website-with-caddy-on-ubuntu-18-04 -# (with modifications) -go install github.com/caddyserver/xcaddy/cmd/xcaddy@v0.1.9 -xcaddy build \ - --with github.com/caddy-dns/cloudflare \ - --with github.com/aksdb/caddy-cgi/v2 -mv caddy /usr/bin -chown root:root /usr/bin/caddy -chmod 755 /usr/bin/caddy +if [ $checkpoint -lt 50 ]; then + savecheckpoint 50 + + go install github.com/caddyserver/xcaddy/cmd/xcaddy@v0.1.9 + xcaddy build \ + --with github.com/caddy-dns/cloudflare \ + --with github.com/aksdb/caddy-cgi/v2 + mv caddy /usr/bin + chown root:root /usr/bin/caddy + chmod 755 /usr/bin/caddy +fi # Install Postgres # (instructions at https://www.postgresql.org/download/linux/ubuntu/) -sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' -wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - -sudo apt-get update -sudo apt-get -y install postgresql +if [ $checkpoint -lt 60 ]; then + savecheckpoint 60 + + sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' + wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - + sudo apt-get update + sudo apt-get -y install postgresql +fi # Configure Postgres # TODO: This was supposed to create a user without a password - why didn't it? # ...or was it? -sudo -u postgres createuser --createdb --login --pwprompt hmn +if [ $checkpoint -lt 70 ]; then + savecheckpoint 70 + sudo -u postgres createuser --createdb --login --pwprompt hmn +fi # Set up the folder structure, clone the repo -sudo -u hmn bash -s <<'SCRIPT' -set -euxo pipefail +if [ $checkpoint -lt 80 ]; then + savecheckpoint 80 -cd ~ -mkdir log -mkdir bin + sudo -u hmn bash -s <<'SCRIPT' + set -euxo pipefail -echo 'PATH=$PATH:/usr/local/go/bin' >> ~/.profile -source ~/.profile + cd ~ + mkdir log + mkdir bin -ssh-keygen -t ed25519 -C "beta-server" -N "" -f ~/.ssh/gitlab -git config --global core.sshCommand "ssh -i ~/.ssh/gitlab" -echo "" -echo "" -echo "Copy the following key and add it as a Deploy Key in the project in GitLab (https://git.handmade.network/hmn/hmn/-/settings/ci_cd#js-deploy-keys-settings):" -echo "" -cat ~/.ssh/gitlab.pub -echo "" -echo "Press enter to continue when you're done." -read + echo 'PATH=$PATH:/usr/local/go/bin:/home/hmn/bin' >> ~/.bash_profile + source ~/.bash_profile -git clone git@gitssh.handmade.network:hmn/hmn.git -pushd hmn - echo "Building the site for the first time. This may take a while..." - go build -o hmn src/main.go -popd + ssh-keygen -t ed25519 -C "beta-server" -N "" -f ~/.ssh/gitlab + git config --global core.sshCommand "ssh -i ~/.ssh/gitlab" + echo "" + echo "" + echo "Copy the following key and add it as a Deploy Key in the project in GitLab (https://git.handmade.network/hmn/hmn/-/settings/ci_cd#js-deploy-keys-settings):" + echo "" + cat ~/.ssh/gitlab.pub + echo "" + echo "Press enter to continue when you're done." + read + + while true ; do + ssh -T git@gitssh.handmade.network && break || true + echo "Failed to connect to GitLab. Fix the issue and then try again. (Press enter when you're done.)" + read + done SCRIPT + echo 'PATH=$PATH:/home/hmn/bin' >> ~/.bash_profile + source ~/.bash_profile +fi + +if [ $checkpoint -lt 90 ]; then + savecheckpoint 90 + + sudo -u hmn bash -s <<'SCRIPT' + set -euxo pipefail + + cd ~ + git clone git@gitssh.handmade.network:hmn/hmn.git +SCRIPT +fi + # Copy config files to the right places -cp /home/hmn/hmn/server/Caddyfile /home/caddy/Caddyfile -cp /home/hmn/hmn/server/logrotate /etc/logrotate.d/hmn -cp /home/hmn/hmn/server/monitrc ~/.monitrc -cp /home/hmn/hmn/server/deploy.conf.example /home/hmn/hmn/server/deploy.conf -cp /home/hmn/hmn/src/config/config.go.example /home/hmn/hmn/src/config/config.go -cp /home/hmn/hmn/cinera/cinera.conf.sample /home/hmn/hmn/cinera/cinera.conf -chmod 600 ~/.monitrc +if [ $checkpoint -lt 100 ]; then + savecheckpoint 100 + + cp /home/hmn/hmn/server/Caddyfile /home/caddy/Caddyfile + + cp /home/hmn/hmn/server/caddy.service /etc/systemd/system/caddy.service + cp /home/hmn/hmn/server/hmn.service /etc/systemd/system/hmn.service + cp /home/hmn/hmn/server/cinera.service /etc/systemd/system/cinera.service + chmod 644 /etc/systemd/system/caddy.service + chmod 644 /etc/systemd/system/hmn.service + chmod 644 /etc/systemd/system/cinera.service + + cp /home/hmn/hmn/server/logrotate /etc/logrotate.d/hmn + + cp /home/hmn/hmn/src/config/config.go.example /home/hmn/hmn/src/config/config.go + cp /home/hmn/hmn/server/deploy.conf.example /home/hmn/hmn/server/deploy.conf + cp /home/hmn/hmn/cinera/cinera.conf.sample /home/hmn/hmn/cinera/cinera.conf + + systemctl daemon-reload +fi + +# Build the site for the first time (despite bad config) +if [ $checkpoint -lt 110 ]; then + savecheckpoint 110 + + sudo -u hmn bash -s <<'SCRIPT' + set -euxo pipefail + + cd /home/hmn/hmn + echo "Building the site for the first time. This may take a while..." + go build -o /home/hmn/bin/hmn src/main.go +SCRIPT +fi cat < Start up Caddy: - monit start caddy + systemctl start caddy Then run the deploy script: diff --git a/server/start.sh b/server/start.sh deleted file mode 100755 index 728183a7..00000000 --- a/server/start.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -mkdir -p /home/hmn/log -nohup /home/hmn/hmn/hmn > /home/hmn/log/hmn.log 2>&1 & -echo $! > /home/hmn/hmn.pid diff --git a/server/stop.sh b/server/stop.sh deleted file mode 100755 index fec6d3a8..00000000 --- a/server/stop.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -kill $(cat /home/hmn/hmn.pid)