Setting up a basic web service on FreeBSD 15
Setting up a FreeBSD webserver on Vultr from scratch.
rc.conf:
pf.conf:
sshd_config:
Caddy Setup:
Message from caddy-2.11.3:
--
To enable caddy:
- Edit /usr/local/etc/caddy/Caddyfile
See https://caddyserver.com/docs/
- Run 'service caddy enable'
Note while Caddy currently defaults to running as root:wheel, it is strongly
recommended to run the server as an unprivileged user, such as www:www --
- Use security/portacl-rc to enable privileged port binding:
# pkg install security/portacl-rc
# sysrc portacl_users+=www
# sysrc portacl_user_www_tcp="http https"
# sysrc portacl_user_www_udp="https"
# service portacl enable
# service portacl start
- Configure caddy to run as www:www
# sysrc caddy_user=www caddy_group=www
- Note if Caddy has been started as root previously, files in
/var/log/caddy, /var/db/caddy, and /var/run/caddy may require their ownership
changing manually.
/usr/local/etc/rc.d/caddy has the following defaults:
- Server log: /var/log/caddy/caddy.log
(runtime messages, NOT an access.log)
- Automatic SSL certificate storage: /var/db/caddy/data/caddy/
- Administration endpoint: //unix/var/run/caddy/caddy.sock
- Runs as root:wheel (this will change to www:www in the future)
Install Elixir:
root@www:~ # pkg install elixir
Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
All repositories are up to date.
The following 3 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
elixir: 1.17.3 [FreeBSD-ports]
erlang: 26.2.5.16_2,4 [FreeBSD-ports]
erlang-man: 26.2 [FreeBSD-ports]
Number of packages to be installed: 3
The process will require 134 MiB more space.
51 MiB to be downloaded.
Proceed with this action? [y/N]: y
[1/3] Fetching erlang-man-26.2: 100% 1250 KiB 1.3 MB/s 00:01
[2/3] Fetching erlang-26.2.5.16_2,4: 100% 40 MiB 42.1 MB/s 00:01
[3/3] Fetching elixir-1.17.3: 100% 9719 KiB 10.0 MB/s 00:01
Checking integrity... done (0 conflicting)
[1/3] Installing erlang-man-26.2...
[1/3] Extracting erlang-man-26.2: 100%
[2/3] Installing erlang-26.2.5.16_2,4...
===> Creating groups
Creating group 'beam' with gid '372'
===> Creating users
Creating user 'beam' with uid '372'
[2/3] Extracting erlang-26.2.5.16_2,4: 100%
[3/3] Installing elixir-1.17.3...
[3/3] Extracting elixir-1.17.3: 100%
=====
Message from erlang-26.2.5.16_2,4:
--
Installation tips:
You can find an emacs mode for Erlang here:
/usr/local/lib/erlang/lib/tools-%%TOOLS_VSN%%/emacs
=====
Message from elixir-1.17.3:
--
Elixir requires a compatible Erlang/OTP runtime. Ensure that you have
one of the following installed:
- lang/erlang
- lang/erlang-runtime24 or newer
Install git-lite:
root@www:~ # pkg install git-lite
Updating FreeBSD-ports repository catalogue...
FreeBSD-ports repository is up to date.
Updating FreeBSD-ports-kmods repository catalogue...
FreeBSD-ports-kmods repository is up to date.
All repositories are up to date.
The following 9 package(s) will be affected (of 0 checked):
New packages to be INSTALLED:
brotli: 1.2.0,1 [FreeBSD-ports]
curl: 8.20.0 [FreeBSD-ports]
expat: 2.8.1 [FreeBSD-ports]
git-lite: 2.53.0 [FreeBSD-ports]
libnghttp2: 1.68.1 [FreeBSD-ports]
libpsl: 0.21.5_2 [FreeBSD-ports]
libssh2: 1.11.1,3 [FreeBSD-ports]
pcre2: 10.47_1 [FreeBSD-ports]
zstd: 1.5.7_1 [FreeBSD-ports]
Number of packages to be installed: 9
The process will require 76 MiB more space.
13 MiB to be downloaded.
Proceed with this action? [y/N]: y
[1/9] Fetching libnghttp2-1.68.1: 100% 139 KiB 142.1 kB/s 00:01
[2/9] Fetching zstd-1.5.7_1: 100% 509 KiB 520.9 kB/s 00:01
[3/9] Fetching pcre2-10.47_1: 100% 1468 KiB 1.5 MB/s 00:01
[4/9] Fetching libssh2-1.11.1,3: 100% 244 KiB 249.9 kB/s 00:01
[5/9] Fetching libpsl-0.21.5_2: 100% 66 KiB 67.5 kB/s 00:01
[6/9] Fetching curl-8.20.0: 100% 1834 KiB 1.9 MB/s 00:01
[7/9] Fetching brotli-1.2.0,1: 100% 388 KiB 397.6 kB/s 00:01
[8/9] Fetching expat-2.8.1: 100% 129 KiB 132.3 kB/s 00:01
[9/9] Fetching git-lite-2.53.0: 100% 8733 KiB 8.9 MB/s 00:01
Checking integrity... done (0 conflicting)
[1/9] Installing brotli-1.2.0,1...
[1/9] Extracting brotli-1.2.0,1: 100%
[2/9] Installing expat-2.8.1...
[2/9] Extracting expat-2.8.1: 100%
[3/9] Installing libnghttp2-1.68.1...
[3/9] Extracting libnghttp2-1.68.1: 100%
[4/9] Installing libpsl-0.21.5_2...
[4/9] Extracting libpsl-0.21.5_2: 100%
[5/9] Installing libssh2-1.11.1,3...
[5/9] Extracting libssh2-1.11.1,3: 100%
[6/9] Installing pcre2-10.47_1...
[6/9] Extracting pcre2-10.47_1: 100%
[7/9] Installing zstd-1.5.7_1...
[7/9] Extracting zstd-1.5.7_1: 100%
[8/9] Installing curl-8.20.0...
[8/9] Extracting curl-8.20.0: 100%
[9/9] Installing git-lite-2.53.0...
===> Creating groups
Creating group 'git_daemon' with gid '964'
===> Creating users
Creating user 'git_daemon' with uid '964'
[9/9] Extracting git-lite-2.53.0: 100%
=====
Message from git-lite-2.53.0:
--
If you installed the GITWEB option please follow these instructions:
In the directory /usr/local/share/examples/git/gitweb you can find all files to
make gitweb work as a public repository on the web.
All you have to do to make gitweb work is:
1) Please be sure you're able to execute CGI scripts in
/usr/local/share/examples/git/gitweb.
2) Set the GITWEB_CONFIG variable in your webserver's config to
/usr/local/etc/git/gitweb.conf. This variable is passed to gitweb.cgi.
3) Restart server.
If you installed the CONTRIB option please note that the scripts are
installed in /usr/local/share/git-core/contrib. Some of them require
other ports to be installed (perl, python, etc), which you may need to
install manually.
Add blog user for our actual service:
root@www:~ # pw useradd blog -c "Blog Webserver" -s /usr/local/bin/git-shell -m
Add an ssh key for the blog user:
root@www:~ # vim .ssh/authorized_keys
root@www:~ # chown blog:blog .ssh/authorized_keys
root@www:~ # chmod 600 .ssh/authorized_keys
Init Bare Repo:
git init --bare /home/blog/repo.git
Note - if you’re doing this as root, you’ll need to make sure to chown and chmod the repository and the authorized_keys files to their appropriate permissions before this will work.
Set up a git target:
joss@grove ~/s/wandering_grove.net (main)> git remote add publish publish.wandering-grove.net:~/repo.git
joss@grove ~/s/wandering_grove.net (main)> git push publish main
Note - if you add publish.wandering-grove.net to your .ssh/config, then you must specify the remote host as above. Trying to target ssh://publish.wandering-grove.net:~/repo.git will not work.
Deployment script from here:
https://gist.github.com/nonbeing/f3441c96d8577a734fa240039b7113db#file-post-receive
Service file from here:
https://elixirforum.com/t/a-simple-rc-d-script-to-run-your-release-as-a-daemon-on-freebsd/66140
Allow the blog user to restart the service in visudo:
blog ALL=(root) NOPASSWD: /usr/sbin/service blog restart
Add to vim /usr/local/etc/newsyslog.conf.d/blog.conf:
/var/log/blog.log 640 7 * @T00 Z
root@www:~ # cat /usr/local/etc/syslog.d/blog.conf
!blog
*.* /var/log/blog.log
Install tailwindcss using npm (what a diversion…)
Install caddy & configure:
root@www:/home/blog/worktree # cat /usr/local/etc/caddy/Caddyfile
# The Caddyfile is an easy way to configure your Caddy web server.
#
# To use your own domain name (with automatic HTTPS), first make
# sure your domain's A/AAAA DNS records are properly pointed to
# this machine's public IP, then replace the line below with your
# domain name.
# Unless the file starts with a global options block, the first
# uncommented line is always the address of your site.
#
wandering-grove.net, www.wandering-grove.net {
# Set this path to your site's directory:
# root * /usr/local/www/caddy
# Enable the static file server:
# file_server
# Set up a reverse proxy:
reverse_proxy localhost:4000
# Serve a PHP site through php-fpm:
# php_fastcgi localhost:9000
# Enable logging:
log {
output file /var/log/caddy/access.log
# Caddy's structured log format:
# format json
format console
# Or, for Common Log Format:
# format single_field common_log
}
}
# Caddy will automatically obtain ACME certs for domains
# example.com {
# root * /path/to/example.com
# file_server
# }
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile