In production web, LAMP means Linux + Apache + Mysql + Php installed and integrated, but today, more and more, Apache is being replaced by Nginx or Lighttpd and MySQL by Mariadb. The LAMP documents are:
lighttpd is a simple, standards-compliant, secure, and flexible web server, Nginx is the most used due to beeing manageable by ISP panel's software, but lighttpd performs better. Nginx cannot process fast-cgi programs. For more lighttpd information, consult the Production Web server:Lighttpd wiki page.
Production environment will handle only needed packages. So no doc or managers allowed:
apk add lighttpd gamin
mkdir -p /var/www/localhost/htdocs/stats /var/log/lighttpd /var/lib/lighttpd
sed -i -r 's#\#.*server.port.*=.*#server.port = 80#g' /etc/lighttpd/lighttpd.conf
sed -i -r 's#\#.*server.event-handler = "linux-sysepoll".*#server.event-handler = "linux-sysepoll"#g' /etc/lighttpd/lighttpd.conf
chown -R lighttpd:lighttpd /var/www/localhost/
chown -R lighttpd:lighttpd /var/lib/lighttpd
chown -R lighttpd:lighttpd /var/log/lighttpd
rc-update add lighttpd default
rc-service lighttpd restart
echo "it works" > /var/www/localhost/htdocs/index.html
sed -i -r 's#\#.*mod_status.*,.*# "mod_status",#g' /etc/lighttpd/lighttpd.conf
sed -i -r 's#.*status.status-url.*=.*#status.status-url = "/stats/server-status"#g' /etc/lighttpd/lighttpd.conf
sed -i -r 's#.*status.config-url.*=.*#status.config-url = "/stats/server-config"#g' /etc/lighttpd/lighttpd.conf
rc-service lighttpd restart
For testing, open a browser and go to http://<webserveripaddres>
.
You will see “it works”. The “webserveripaddres” is the ip address
of your setup/server machine.
OPTIONAL: alpine packagers are a mess, removed FAM on recent, so
older releases of alpine can use compiled FAM packages with
sed -i -r 's#.*server.stat-cache-engine.*=.*# server.stat-cache-engine = "fam"#g' /etc/lighttpd/lighttpd.conf
FAM/gamin was deprecated since lighttpd 1.4.36, and in older releases
produces problems so if you are running older version of lighttpd
just avoid usage of FAM/gamin on it!
In Alpine there are two main languages for programming dynamic web pages: PHP and LUA. Alpine is minimalist so not all PHP packages are need in most cases. Both repositories must be enabled (main and community). Here we explain the most common use in production.
Since alpine 3.16 only php 8 are available, php 7 was only from alpine 3.8 to 3.15, there are external repos on venenux git alpine builds!
apk add php81-common php81-doc php81-phar php81-posix php81-pspell php81-session \
php81-cgi php81-fpm php81-curl php81-simplexml php81-sockets php81-bcmath php81-calendar \
php81-ctype php81-dom php81-embed php81-enchant php81-exif php81-fileinfo php81-ftp \
php81-pear php81-gd php81-iconv php81-gettext php81-gmp php81-imap php81-intl \
php81-mbstring php81-openssl php81-opcache php81-pcntl php81-bz2 php81-zip \
php81-tidy php81-tokenizer php81-xml php81-xmlreader php81-xmlwriter php81-xsl
Those are the basic most need packages, the following packages allow to connect to databases.
A special case is php81-odbc
. Unless the others, that are able php to
connect to only specific database ODBC allows to connect to multiple databases!
apk add php81-dba php81-mysqli php81-mysqlnd php81-odbc php81-pgsql php81-sqlite3
There are also special database connection packages called PDO, install if you need:
apk add php81-pdo php81-pdo_dblib php81-pdo_mysql php81-pdo_odbc php81-pdo_pgsql php81-pdo_sqlite
sed -i -r 's|.*cgi.fix_pathinfo=.*|cgi.fix_pathinfo=1|g' /etc/php*/php.ini
sed -i -r 's#.*safe_mode =.*#safe_mode = Off#g' /etc/php*/php.ini
sed -i -r 's#.*expose_php =.*#expose_php = Off#g' /etc/php*/php.ini
sed -i -r 's#memory_limit =.*#memory_limit = 536M#g' /etc/php*/php.ini
sed -i -r 's#upload_max_filesize =.*#upload_max_filesize = 128M#g' /etc/php*/php.ini
sed -i -r 's#post_max_size =.*#post_max_size = 256M#g' /etc/php*/php.ini
sed -i -r 's#^file_uploads =.*#file_uploads = On#g' /etc/php*/php.ini
sed -i -r 's#^max_file_uploads =.*#max_file_uploads = 12#g' /etc/php*/php.ini
sed -i -r 's#^allow_url_fopen = .*#allow_url_fopen = On#g' /etc/php*/php.ini
sed -i -r 's#^.default_charset =.*#default_charset = "UTF-8"#g' /etc/php*/php.ini
sed -i -r 's#^.max_execution_time =.*#max_execution_time = 150#g' /etc/php*/php.ini
sed -i -r 's#^max_input_time =.*#max_input_time = 90#g' /etc/php*/php.ini
mkdir -p /var/run/php-fpm7/
chown lighttpd:root /var/run/php-fpm7
sed -i -r 's|^.*listen =.*|listen = /var/run/php-fpm81/php81-fpm.sock|g' /etc/php*/php-fpm.d/www.conf
sed -i -r 's|^pid =.*|pid = /run/php-fpm81/php81-fpm.pid|g' /etc/php*/php-fpm.conf
sed -i -r 's|^.*listen.mode =.*|listen.mode = 0640|g' /etc/php*/php-fpm.d/www.conf
rc-update add php-fpm81 default
service php-fpm81 restart
The PHP-FPM defines a master process with a process pool for each service request. By default, there's only one process pool, www.
Default values are good for starting, but will need tuning later. The best is a static one, but testing is needed to get the right configuration.
The web server comes with a minimal config file, so we must handle all the required settings:
mkdir -p /var/www/localhost/cgi-bin
sed -i -r 's#\#.*mod_alias.*,.*# "mod_alias",#g' /etc/lighttpd/lighttpd.conf
sed -i -r 's#.*include "mod_cgi.conf".*# include "mod_cgi.conf"#g' /etc/lighttpd/lighttpd.conf
sed -i -r 's#.*include "mod_fastcgi.conf".*#\# include "mod_fastcgi.conf"#g' /etc/lighttpd/lighttpd.conf
sed -i -r 's#.*include "mod_fastcgi_fpm.conf".*# include "mod_fastcgi_fpm.conf"#g' /etc/lighttpd/lighttpd.conf
sed -e '/index-file.names/ s/^#*/#/' -i /etc/lighttpd/lighttpd.conf
cat > /etc/lighttpd/mod_fastcgi_fpm.conf << EOF
server.modules += ( "mod_fastcgi" )
index-file.names += ( "index.php" )
fastcgi.server = (
".php" => (
"localhost" => (
"socket" => "/var/run/php-fpm81/php81-fpm.sock",
"broken-scriptfilename" => "enable"
))
)
EOF
sed -i -r 's|^.*listen =.*|listen = /var/run/php-fpm81/php81-fpm.sock|g' /etc/php*/php-fpm.d/www.conf
sed -i -r 's|^.*listen.owner = .*|listen.owner = lighttpd|g' /etc/php*/php-fpm.d/www.conf
sed -i -r 's|^.*listen.group = .*|listen.group = lighttpd|g' /etc/php*/php-fpm.d/www.conf
sed -i -r 's|^.*listen.mode = .*|listen.mode = 0660|g' /etc/php*/php-fpm.d/www.conf
rc-service php-fpm81 restart
rc-service lighttpd restart
echo "<?php echo phpinfo(); ?>" > /var/www/localhost/htdocs/info.php
For testing, open a browser and go to http://<webserveripaddres>/info.php
.
You will see the info as used in production. There's no sense givig too much
information to crackers. The “webserveripaddres” is the ip address of your setup/server
machine.
After that, all the files with php will be procesed faster than used a
host based. Under the /var/www/localhost/cgi-bin
directory will be
shown as http://localhost/cgi-bin/ path.
Alpine Linux has dummy counterpart packages for those not changed from mysql to mariadb.
Take into consideration the user mysql
was created during package
instalation. In the initialization section two users will be created in
database init: root
and mysql
, and at that point only if they are in
their respective system accounts, will they be able to connect to the
database service.
In alpine the only option is using Mariadb or Postgresql, ODBC only provides TDS and Postgresql, rest of options are only in edge or using other linuxes
This part will use the previosu configurations to setup the DBMS web management, The most secure for web Mysql managemend its adminer, cos phpmyadmin its too polite Adminer permits to manage any kind of database, including odbc, postgresql and mysql/mariadb in only one interface!
mkdir -p /usr/share/webapps/adminer
wget https://github.com/vrana/adminer/releases/download/v4.8.1/adminer-4.8.1.php -O /usr/share/webapps/adminer/adminer-4.8.1.php
ln -s adminer-4.8.1.php /usr/share/webapps/adminer/index.php
sed -i -r 's#\#.*mod_alias.*,.*# "mod_alias",#g' /etc/lighttpd/lighttpd.conf
cat > /etc/lighttpd/mod_adminer.conf << EOF
alias.url += ( "/adminer/" => "/usr/share/webapps/adminer" )
$HTTP["url"] =~ "^/adminer/" {
dir-listing.activate = "disable"
index-file.names := ( "index.php", "index.html", "adminer-4.8.1.php" )
}
EOF
itawxrc="";itawxrc=$(grep 'include "mod_adminer.conf' /etc/lighttpd/lighttpd.conf);[[ "$itawxrc" != "" ]] && echo listo || sed -i -r 's#.*include "mime-types.conf".*#include "mime-types.conf"\ninclude "mod_adminer.conf"#g' /etc/lighttpd/lighttpd.conf
sed -i -r 's#\#.*mod_alias.*,.*# "mod_alias",#g' /etc/lighttpd/lighttpd.conf
checkssl="";checkssl=$(grep 'include "mod_adminer.conf' /etc/lighttpd/lighttpd.conf);[[ "$checkssl" != "" ]] && echo listo || sed -i -r 's#.*include "mod_cgi.conf".*#include "mod_cgi.conf"\ninclude "mod_adminer.conf"#g' /etc/lighttpd/lighttpd.conf
rc-update add lighttpd default
rc-service lighttpd restart
The administrator must use the exact URL
http://<ipaddress>/adminer/index.php
There are two reasons: there's
no directory listing and there's no direct PHP index reference on the
web server, all because of paranoid settings.
apk add mysql mysql-client mariadb-doc mariadb-server-utils mariadb-mytop
mysql_install_db --user=mysql --datadir=/var/lib/mysql
rc-service mariadb start
mysqladmin -u root password toor
sed -i "s|.*max_allowed_packet\s*=.*|max_allowed_packet = 100M|g" /etc/mysql/my.cnf
sed -i "s|.*max_allowed_packet\s*=.*|max_allowed_packet = 100M|g" /etc/my.cnf.d/mariadb-server.cnf
sed -i "s|.*bind-address\s*=.*|bind-address=0.0.0.0|g" /etc/mysql/my.cnf
sed -i "s|.*bind-address\s*=.*|bind-address=0.0.0.0|g" /etc/my.cnf.d/mariadb-server.cnf
sed -i "s|.*skip-networking.*|#skip-networking|g" /etc/mysql/my.cnf
sed -i "s|.*skip-networking.*|#skip-networking|g" /etc/my.cnf.d/mariadb-server.cnf
rc-service mariadb restart
rc-update add mariadb
For information and more deep setup check ../documents/server-alpine-mysql-professional.md
Warning: the configuration here is for quick access and fist development, security is minimal only! for secure configuration set to specific bind-address or if you dont want remote access uncomment skip-networking
apk add postgresql postgresql-client postgresql-contrib postgresql-libs postgresql-orafce
rc-service postgresql setup
sed -r -i "s|.*listen_addresses.*=.*|listen_addresses=\*|g" /var/lib/postgresql/*/data/postgresql.conf*
rc-service postgresql start
rc-update add postgresql
psql -U postgres
create user postfix with password '******';
create database postfix owner postfix;
\c postfix
create language plpgsql;
\q
apk add unixodbc psqlodbc freetds mdbtools-odbc
cat > /tmp/tmppg.tmp << EOF
[PostgreSQL]
Description = PostgreSQL ODBC (ANSI version)
Driver = /usr/lib/psqlodbca.so
Debug = 0
CommLog = 1
[PostgreSQL-Unicode]
Description = PostgreSQL ODBC (Unicode version)
Driver = /usr/lib/psqlodbcw.so
Debug = 0
CommLog = 1
EOF
odbcinst -u -d -f /tmp/tmppg.tmp
cat > /tmp/tmptds.tmp << EOF
[FreeTDS]
Description = TDS module (Sybase/MS SQL)
Driver = /usr/lib/libtdsodbc.so.0
CPTimeout =
CPReuse =
odbcinst -u -d -f /tmp/tmptds.tmp
cat > /tmp/tmpmdb.tmp << EOF
[MDBTools]
Description = MDB modules for ODBC
Driver = /usr/lib/odbc/libmdbodbc.so
CPTimeout =
CPReuse =
odbcinst -u -d -f /tmp/tmpmdb.tmp
Warning the packages for mysql and sqlite are
sqliteodbc
andmariadb-connector-odbc
but only available for edge.
Warning if your alpine version is too older, you cannot use the mysql edge package for odbc unfortunatelly
CC BY-NC-SA: the project allows reusers to distribute, remix, adapt, and build upon the material in any medium or format for noncommercial purposes only, and only so long as attribution is given to the creators involved. If you remix, adapt, or build upon the material, you must license the modified material under identical terms, includes the following elements:
For more information check the alpine/copyright.md