Skip to content

Instantly share code, notes, and snippets.

@bnf
Last active November 24, 2023 16:12
Show Gist options
  • Save bnf/245290d722dd61448eae12090e340038 to your computer and use it in GitHub Desktop.
Save bnf/245290d722dd61448eae12090e340038 to your computer and use it in GitHub Desktop.
Fedora systemd-nspawn container for web development
#!/bin/sh
version=${2:-39}
name=${1:-fw${version}}
webroot=${3:-${PWD}}
installroot=${4:-/var/lib/machines/${name}}
dnf="dnf --installroot=${installroot} --setopt=cachedir=/var/cache/dnf --releasever=${version} --repo=fedora --repo=updates --setopt=install_weak_deps=False --setopt=keepcache=True"
packages=(
passwd
fedora-release
vim-minimal
util-linux
systemd
httpd
mod_ssl
mariadb
mariadb-server
php-fpm
php-cli
php-common
php-gd
php-intl
php-mbstring
php-mysqlnd
php-opcache
php-pdo
php-pecl-apcu
php-pecl-zip
php-process
php-soap
php-sodium
php-xml
)
if [ "$version" -le "31" ]; then
echo "Fedora <= v31 is not supported"
exit;
fi
if [ "$version" -ge "33" ]; then
packages+=( "systemd-networkd" )
fi
if [ "$version" -ge "35" ]; then
packages+=( "systemd-resolved" )
fi
sudo machinectl stop $name &>/dev/null && sleep 2
sudo $dnf -y install ${packages[*]}
sudo mkdir -p /etc/systemd/nspawn
echo -ne "[Exec]\nNotifyReady=on\n" | sudo tee /etc/systemd/nspawn/${name}.nspawn > /dev/null
echo -ne "[Files]\nBind=${webroot}:/var/www/html:owneridmap\n" | sudo tee -a /etc/systemd/nspawn/${name}.nspawn > /dev/null
tmpdir=$(mktemp -d "/tmp/${name}-keys.XXX")
mkcert -key-file "$tmpdir/key.pem" -cert-file "$tmpdir/cert.pem" ${name}
sudo chown root:root "$tmpdir/key.pem" "$tmpdir/cert.pem"
sudo mv "$tmpdir/key.pem" "$installroot/etc/pki/tls/private/mkcert-key.pem"
sudo mv "$tmpdir/cert.pem" "$installroot/etc/pki/tls/certs/mkcert-cert.pem"
sudo chown 48:48 "$installroot/var/www/html"
sudo tee "$installroot/etc/httpd/conf.d/ssl.conf" >/dev/null <<\EOF
Listen 443
<VirtualHost _default_:443>
SSLEngine on
SSLCertificateKeyFile /etc/pki/tls/private/mkcert-key.pem
SSLCertificateFile /etc/pki/tls/certs/mkcert-cert.pem
</VirtualHost>
EOF
sudo tee "$installroot/etc/httpd/conf.d/webroot.conf" >/dev/null <<\EOF
<Directory "/var/www/html">
Options FollowSymLinks
AllowOverride All
Require all granted
</Directory>
EOF
sudo machinectl start $name
sudo systemctl -M $name enable systemd-networkd httpd
sudo systemctl -M $name start systemd-networkd
sudo systemctl -M $name start httpd
sudo systemctl -M $name start mariadb
sudo mkdir -p $installroot/root
#Enter current password for root (enter for none):
#Switch to unix_socket authentication y
#Change the root password? n
#Remove anonymous users? y
#Disallow root login remotely? y
#Remove test database and access to it? y
#Reload privilege tables now? y
sudo tee "$installroot/root/setup.sh" >/dev/null <<\EOF
#!/bin/sh
ROOT_SQLPASS=$(tr -dc _A-Za-z0-9 < /dev/urandom | head -c16) # Generate a random password
DB_NAME="web"
DB_USER="web"
DB_PASS=$(tr -dc _A-Za-z0-9 < /dev/urandom | head -c16)
DB_HOST="localhost"
cat >/etc/my.cnf.d/charset.cnf <<EOB
[mysqld]
character-set-server = utf8mb4
[client]
default-character-set = utf8mb4
EOB
systemctl restart mariadb
bash -c "echo -e '\ny\nn\ny\ny\ny\ny\n' | mysql_secure_installation"
mysql -Bse "UPDATE mysql.global_priv SET priv=json_set(priv, '$.plugin', 'mysql_native_password', '$.authentication_string', PASSWORD('${ROOT_SQLPASS}')) WHERE User='root'; FLUSH PRIVILEGES;"
echo -e "[client]\nuser=root\npassword=${ROOT_SQLPASS}" > /root/.my.cnf
# TODO
#GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER,CREATE TEMPORARY TABLES
mysql <<EOB
DROP DATABASE IF EXISTS $DB_NAME;
CREATE DATABASE $DB_NAME;
GRANT ALL PRIVILEGES
ON $DB_NAME.*
TO $DB_USER@$DB_HOST
IDENTIFIED BY '$DB_PASS';
FLUSH PRIVILEGES;
EOB
MY_CNF=/usr/share/httpd/.my.cnf
cat >$MY_CNF << EOB
[client]
user=$DB_USER
password=$DB_PASS
host=$DB_HOST
[mysql]
database=$DB_NAME
EOB
chmod 600 $MY_CNF
chown apache:apache $MY_CNF
#sed -i -e 's/^#*max_allowed_packet.*/max_allowed_packet=1G/' /etc/mysql/mariadb.conf.d/50-server.cnf
systemctl restart mariadb
sed -i \
-e 's/^;*date.timezone *=.*/date.timezone = Europe\/Berlin/' \
-e 's/^;*max_input_vars *=.*/max_input_vars = 3000/' \
-e 's/^;*max_execution_time *=.*/max_execution_time = 240/' \
-e 's/^;*memory_limit *=.*/memory_limit = 384M/' \
-e 's/^;*post_max_size *=.*/post_max_size = 128M/' \
-e 's/^;*upload_max_filesize *=.*/upload_max_filesize = 128M/' \
-e 's/^;*opcache.enable_cli *=.*/opcache.enable_cli = 1/' \
/etc/php.ini
systemctl restart php-fpm
sed -i -e '/^apache:/s/sbin\/nologin/bin\/bash/' /etc/passwd
EOF
sudo chmod +x "$installroot/root/setup.sh"
sudo machinectl shell $name /root/setup.sh
# needs mymachines in /etc/nsswitch.conf "hosts:" line
xdg-open "https://${name}"
rm -fr "$tmpdir"
#sudo $dnf clean all
sudo du -hs "$installroot"

Fedora systemd-nspawn container for web development

Requires: systemd/systemd#30080

Usage

cd path/to/your/local/sources
# creates a container with the current directory mapped to /var/www/html and configures apache/php/mariadb.
create-webfedora.sh testsite
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment