<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rickyrockrat</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Rickyrockrat"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Rickyrockrat"/>
	<updated>2026-04-25T15:41:11Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=26380</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=26380"/>
		<updated>2024-02-11T23:51:48Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Permissive iptables */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Style}}&lt;br /&gt;
&lt;br /&gt;
=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This page describes building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and an internal LAN with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise, it comprises 13 GB of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
* Obtain a microSD card (or HDD) you can wipe the data from. We will assume it is /dev/sdc.&lt;br /&gt;
* Make a 256M FAT16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* The rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* Untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all of the files to the fat16 partition which can be as large as 2G. &lt;br /&gt;
* Make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* Add this to usercfg.txt at the root of the FAT16 partition:&lt;br /&gt;
  enable_uart=1&lt;br /&gt;
  gpu_mem=16&lt;br /&gt;
  dtparam=audio=off&lt;br /&gt;
* This is the contents of cmdline.txt:&lt;br /&gt;
  modules=loop,squashfs,sd-mod,usb-storage console=tty1 console=ttyAMA0,115200&lt;br /&gt;
&lt;br /&gt;
=== First Boot ===&lt;br /&gt;
* Put the SD into the pi zero&lt;br /&gt;
* Connect the serial port&lt;br /&gt;
* Run minicom with the parameters set to 115200,n,8,1, no flow control.&lt;br /&gt;
* Power up the Pi.&lt;br /&gt;
&lt;br /&gt;
=== Copy Root ===&lt;br /&gt;
* mkdir /stage&lt;br /&gt;
* mount /dev/sda2 /stage&lt;br /&gt;
* for d in $(ls -1 /|grep -v &#039;media\|stage\|dev\|proc\|sys&#039;); do cp -a /$d /stage; done&lt;br /&gt;
* modules are loop mounted to /.modloop, and lib/modules is symlinked to that, so&lt;br /&gt;
* rm /stage/lib/modules&lt;br /&gt;
* cp -a /.modloop /stage/lib/modules&lt;br /&gt;
* Fix cmdline.txt&lt;br /&gt;
  mount -o remount,rw /media/mmcblk0p1&lt;br /&gt;
  echo &#039;root=/dev/mmcblk0p2&#039; &amp;gt;&amp;gt; /media/mmcblk0p1/cmdline.txt&lt;br /&gt;
* reboot&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* verify you are now operating from the ext2 filesystem where you copied the rootfs.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
* edit all the configurations supplied here.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
This has two subnets. One for normal dhcp, the other for pseudo static - dhcp provided by MAC. One example here.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=br0&lt;br /&gt;
except-interface=eth0&lt;br /&gt;
dhcp-range=subnet0,192.168.0.10,192.168.0.100,255.255.255.0,24h&lt;br /&gt;
dhcp-range=subnet1,192.168.0.4,192.168.0.6,255.255.255.0,24h&lt;br /&gt;
bind-interfaces&lt;br /&gt;
#log-queries&lt;br /&gt;
#log-dhcp&lt;br /&gt;
dhcp-host=70:85:66:c4:48:55,192.168.0.4,nas&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== /etc/hosts =====&lt;br /&gt;
dnsmasq provides DNS answers from the hosts file. Nice. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
127.0.0.1	localhost localhost.localdomain&lt;br /&gt;
::1		localhost localhost.localdomain&lt;br /&gt;
192.168.0.3     wireless&lt;br /&gt;
192.168.0.4     nas&lt;br /&gt;
192.168.0.5     mpd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=wlan0&lt;br /&gt;
bridge=br0&lt;br /&gt;
hw_mode=g&lt;br /&gt;
channel=7&lt;br /&gt;
wmm_enabled=0&lt;br /&gt;
macaddr_acl=0&lt;br /&gt;
auth_algs=1&lt;br /&gt;
ignore_broadcast_ssid=0&lt;br /&gt;
wpa=2&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&lt;br /&gt;
wpa_pairwise=TKIP&lt;br /&gt;
rsn_pairwise=CCMP&lt;br /&gt;
ssid=Whatever&lt;br /&gt;
wpa_passphrase=YouMakeItUp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname ANYNAME&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&lt;br /&gt;
&lt;br /&gt;
iface eth1 inet manual&lt;br /&gt;
iface wlan0 inet manual&lt;br /&gt;
&lt;br /&gt;
auto br0&lt;br /&gt;
iface br0 inet static&lt;br /&gt;
        pre-up ifconfig eth1 up&lt;br /&gt;
        bridge-ports eth1 wlan0&lt;br /&gt;
        bridge-stp off&lt;br /&gt;
        address 192.168.0.3&lt;br /&gt;
        broadcaset 192.168.1.255&lt;br /&gt;
        netmask 255.255.255.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! There is NO protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create, index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Related =====&lt;br /&gt;
[https://github.com/rickyrockrat/nanopi-alpine NanoPi NEO build script]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26379</id>
		<title>Creating an Alpine package</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26379"/>
		<updated>2024-02-11T23:45:10Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This is a brief list of the steps to add a new package. Details are below, but a NB can miss a few steps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create an account on github.alpine&lt;br /&gt;
&amp;lt;li&amp;gt;Setup the build environment for aports.&lt;br /&gt;
&amp;lt;li&amp;gt;Fork the aports repository. &lt;br /&gt;
&amp;lt;li&amp;gt;Clone your new fork.&lt;br /&gt;
&amp;lt;li&amp;gt;Set git pull.rebase=true, set your username and email.&lt;br /&gt;
&amp;lt;li&amp;gt;Create and switch to a new branch (don&#039;t use master).&lt;br /&gt;
&amp;lt;li&amp;gt;Add a new directory under testing that is your new package name.&lt;br /&gt;
&amp;lt;li&amp;gt;Add your APKBUILD file.&lt;br /&gt;
&amp;lt;li&amp;gt;Run abuild checksum&lt;br /&gt;
&amp;lt;li&amp;gt;Make sure you run the apkbuild-lint and aport -r and there are no warnings.&lt;br /&gt;
&amp;lt;li&amp;gt;Commit your APKBUILD with the commit message: &#039;testing/packagename: new aport&#039;&lt;br /&gt;
&amp;lt;li&amp;gt;Push your changes to your fork on github.alpine.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a merge request.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the rest of this wiki for details on the steps above.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
To build a package for Alpine Linux you need an Alpine Linux installation. Check the [[Installation]] page to see all available installation options.&lt;br /&gt;
&lt;br /&gt;
== Setup your system and account  ==&lt;br /&gt;
{{:Setup_your_system_and_account_for_building_packages}}&lt;br /&gt;
&lt;br /&gt;
== Getting some help ==&lt;br /&gt;
&lt;br /&gt;
It might be wise to start by checking what the [[Abuild and Helpers|abuild]] program can/cannot do.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -h}}&lt;br /&gt;
&lt;br /&gt;
For real help, you can also go on #alpine-devel on [[IRC]].&lt;br /&gt;
&lt;br /&gt;
A reference for APKBUILD files is available as [[APKBUILD Reference]] wiki page or a man page in the &#039;abuild-doc&#039; package:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|man APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Creating an APKBUILD file  ==&lt;br /&gt;
&lt;br /&gt;
=== Use a template APKBUILD ===&lt;br /&gt;
&lt;br /&gt;
To create the actual APKBUILD file {{Pkg|newapkbuild}} can serve you a template to start with. It will create a directory with the given package name, place an example/template APKBUILD file to the given directory, and fill some variables if those are provided. Please check the [[Package_policies| package policies]] page about naming details.&lt;br /&gt;
&lt;br /&gt;
If you doubt to which repository your package belongs to you can safely use &#039;&#039;&#039;testing&#039;&#039;&#039;. Building package in your aports/testing directory is not mandatory but this way the package is already at the right place.&lt;br /&gt;
&lt;br /&gt;
{{:Abuild and Helpers}}&lt;br /&gt;
&lt;br /&gt;
{{Note|On older Alpine systems, abuild -c -n &#039;&#039;packagename&#039;&#039; was the way to create APKBUILD files. The &#039;packagename&#039; was a parameter to the -n option so order of -c and -n matters. }}&lt;br /&gt;
&lt;br /&gt;
[[Abuild_and_Helpers#apkbuild-cpan|apkbuild-cpan]] simplifies the creation of perl packages from CPAN and [[Abuild_and_Helpers#apkbuild-pypi|apkbuild-pypi]] ease the generation of APKBUILD files for python packages from PyPi.  &lt;br /&gt;
&lt;br /&gt;
If you are creating a daemon package which needs initd scripts you can add the -c making it: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|newapkbuild -c &#039;&#039;packagename&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This will copy the sample initd and confd files to the build directory.&amp;lt;BR&amp;gt;&lt;br /&gt;
A third file sample.install file will be copied as well (we will discuss this later on).&lt;br /&gt;
&lt;br /&gt;
=== Modify your APKBUILD ===&lt;br /&gt;
Edit APKBUILD and fill in the needed info (especially pkgname, pkgver, pkgdesc, url, license, depends and source). &lt;br /&gt;
&lt;br /&gt;
If you are going to use any of the variables for directories like $pkgdir, always make sure they are double quoted like: &lt;br /&gt;
&lt;br /&gt;
 &amp;quot;$pkgdir&amp;quot;/somedir&lt;br /&gt;
&lt;br /&gt;
This will prevent issues with spaces/special characters in the future. &lt;br /&gt;
&lt;br /&gt;
{{Note|If you like syntax highlighting we suggest you to install vim. We have setup vim to recognize the APKBUILD file as a bash scripts so its easier to read them.}}&lt;br /&gt;
&lt;br /&gt;
=== APKBUILD variables/functions  ===&lt;br /&gt;
&lt;br /&gt;
==== source  ====&lt;br /&gt;
&lt;br /&gt;
The source variable is not only used to list the remote source files to fetch, it is also used to list the local files that abuild will need in order to build the apk. Examples of such local files include: init.d files, conf.d files, install files (see [[Creating an Alpine package#install|install variable]]), patches, and all other necessary files.&lt;br /&gt;
&lt;br /&gt;
Here are few things to note:&lt;br /&gt;
&lt;br /&gt;
* When you are finished adding local and/or remote files to &#039;&#039;source&#039;&#039;, you can execute the following command to add their checksums to the APKBUILD file:&lt;br /&gt;
: {{cmd|abuild checksum}}&lt;br /&gt;
: {{Note|When later updating the content of &#039;&#039;source&#039;&#039;, or updating a file that is listed in &#039;&#039;source&#039;&#039;, you must also update their checksums again with the same command.}}&lt;br /&gt;
&lt;br /&gt;
* When the remote file is hosted at SourceForge, it&#039;s best to specify the special mirrors link used by SourceForge:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
: (or similar depending on the package).&lt;br /&gt;
&lt;br /&gt;
* When the remote filename is not specified in the URI (ie, does not end in &#039;/software-1.0.tar.gz&#039;), such as:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
: You must prepend &#039;${pkgname}-${pkgver}.tar.gz::&#039; to the protocol, like so:&lt;br /&gt;
: &amp;lt;pre&amp;gt;source=&amp;quot;${pkgname}-${pkgver}.tar.gz::http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
: This causes the file to be saved as &#039;&#039;software-1.0.tar.gz&#039;&#039; where abuild can use it, instead of &#039;&#039;?get=software&amp;amp;ver=1.0&#039;&#039;, where abuild cannot use it.&lt;br /&gt;
&lt;br /&gt;
* Some projects didn&#039;t provide a release tarball. Beware that some git services (gitweg, cgit, …?) doesn’t provide &#039;&#039;stable&#039;&#039; tarballs, so when you point source to an tarball like &amp;lt;tt&amp;gt;https://repo.or.cz/w/gitstats.git/snapshot/ad7efbb9399e60cee6cb217c6b47e604174a8093.tar.gz&amp;lt;/tt&amp;gt;, then you will run into issues because the checksum changes when downloading on the build system. This is not a problem on GitHub, GitLab and other decent services provides, they provide &#039;&#039;stable&#039;&#039; tarballs.&lt;br /&gt;
&lt;br /&gt;
* abuild currently supports the following protocols for remote file retrieval:&lt;br /&gt;
** http&lt;br /&gt;
** https&lt;br /&gt;
** ftp&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--: {{Note|If the you want to download from https, you need GNU wget installed on your system.}}--&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
* abuild currently supports the following archive types/archive file extensions:&lt;br /&gt;
** .tar&lt;br /&gt;
** .tar.gz / .tgz&lt;br /&gt;
** .tar.bz2&lt;br /&gt;
** .tar.lz (only in Alpine &amp;gt;=3.7)&lt;br /&gt;
** .tar.lzma&lt;br /&gt;
** .tar.xz&lt;br /&gt;
** .zip&lt;br /&gt;
&lt;br /&gt;
==== depends &amp;amp;amp; makedepends  ====&lt;br /&gt;
&lt;br /&gt;
Depends are the actual running dependencies that a package would need when it is running. Makedepends are only needed when you are building a package. If you set a package in depends, you do not need to add it to makedepends as well. The best way to find out what the depends and makedepends of a package are is to [https://en.wikipedia.org/wiki/Rtfm RTFM]. &lt;br /&gt;
&lt;br /&gt;
No kidding, lots of important information can be found in the package INSTALL and README files (or the likes). Another good way is the run &amp;lt;code&amp;gt;./configure --help&amp;lt;/code&amp;gt; from the source directory to see which options are needed for configure to finish without errors. If you do not yet have a source directory you can create one with the command: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild unpack}}&lt;br /&gt;
&lt;br /&gt;
Running &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt; will also show you how you can disable a specific option for this package. For instance, a good example is &amp;quot;--disable-nls&amp;quot; which will disable native language support and thus does not depend on gettext (libiconv, glib, ...). &lt;br /&gt;
&lt;br /&gt;
Alpine likes to keep things small, so we try to disable as much as possible without losing too many features. The exact disable/enable options are decided by the package builder but please try to follow Alpine&#039;s design concept as much as possible.&lt;br /&gt;
&lt;br /&gt;
An easy way of quickly finding out the build info for a package is to check Arch Linux (Alpine package management and build scripts are similar) or Gentoo Linux ebuilds (previous versions of Alpine were based on Gentoo).&lt;br /&gt;
&lt;br /&gt;
* [https://gitweb.gentoo.org/repo/gentoo.git/tree/ Gentoo Ebuilds] &lt;br /&gt;
* [https://archlinux.org/packages/?q=search Arch Linux packages] [https://aur.archlinux.org/ Arch Linux User Repository]&lt;br /&gt;
&lt;br /&gt;
==== license  ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;license&#039;&#039;&#039; tag must reflect the license of the source code. Please check the source tarball for COPYING, LICENSE, or other files with names that indicates that it contains licensing information. Beside the license file most developer include headers in the source code files with licensing details.&lt;br /&gt;
&lt;br /&gt;
If the license is on the [https://spdx.org/licenses/ SPDX License List] or [https://spdx.org/licenses/exceptions-index.html SPDX License Exceptions], use the identifier specified by SPDX.&lt;br /&gt;
&lt;br /&gt;
Note that some licenses have additional requirements that should be adhered to. The &amp;lt;code&amp;gt;MIT&amp;lt;/code&amp;gt; license for example has the requirement:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that we need to include the license as shipped with the project.&lt;br /&gt;
&lt;br /&gt;
If a package has a special/custom license or is not listed as [https://opensource.org/licenses/alphabetical OSI approved], use the identifier &amp;quot;custom&amp;quot;. In that case we need to provide the license file with the package as well.&lt;br /&gt;
&lt;br /&gt;
Because we want to save space and don&#039;t like to have licenses all over our system we have decided to include the license in the doc subpackage. Please follow the following guidelines to add a proper license. Locate the license file inside the source package. Add the doc subpackage to the $subpackages variable as follows: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a similar line to the following to your package() function, depending on the license description file: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 COPYING &amp;quot;$pkgdir&amp;quot;/usr/share/licenses/$pkgname/COPYING}}&lt;br /&gt;
&lt;br /&gt;
If you follow these steps then abuild will automatically add the license to the package-doc apk for you.&lt;br /&gt;
&lt;br /&gt;
{{Warning|It is not acceptable to package software with &amp;quot;unknown&amp;quot; license! If you can&#039;t find the license of the source code, please contact the author and ask them to specify the license. }}&lt;br /&gt;
&lt;br /&gt;
==== arch ====&lt;br /&gt;
&lt;br /&gt;
The package architecture(s) to build for.  This can be one of: &#039;&#039;x86, x86_64, all,&#039;&#039; or &#039;&#039;noarch&#039;&#039;, where &#039;&#039;all&#039;&#039; means all architectures, and &#039;&#039;noarch&#039;&#039; means it&#039;s architecture-independent (e.g., a pure-python package).&lt;br /&gt;
{{Tip|To determine if your APKBUILD can use &#039;&#039;noarch&#039;&#039;, build the package for your architecture and then run &amp;quot;scanelf -R pkg&amp;quot; from the directory that the APKBUILD resides in, in order to scan for ELF files in the &#039;&#039;./pkg&#039;&#039; directory.  If you do NOT get output from this, then &#039;&#039;noarch&#039;&#039; can be used.}}&lt;br /&gt;
&lt;br /&gt;
==== url  ====&lt;br /&gt;
&lt;br /&gt;
Website address for the program. This is useful later on when either finding documentation or other information about the package.&lt;br /&gt;
&lt;br /&gt;
==== pkgdesc  ====&lt;br /&gt;
&lt;br /&gt;
A brief, one line, description of what the package does. Useful for the package management system. It should start with a capital letter and does &#039;&#039;&#039;not&#039;&#039;&#039; end with a period.&lt;br /&gt;
&lt;br /&gt;
Here is an example from apk_info for the OpenSSH client package:&lt;br /&gt;
&lt;br /&gt;
 pkgdesc=&amp;quot;Port of OpenBSD&#039;s free SSH release - client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== pkgver  ====&lt;br /&gt;
&lt;br /&gt;
Provide the release number of the package you are building.&lt;br /&gt;
&lt;br /&gt;
==== pkgrel  ====&lt;br /&gt;
&lt;br /&gt;
The $pkgrel versioning is made so that if you change something in your APKBUILD file without changing the actual $pkgver, you can increment pkgrel so apk tools will detect it as an update. For instance, if you forget to add a dependency, you can add it afterward and you can +1 pkgver so apk finds this update and adds the missing dependency. When there&#039;s an upstream version change, we reset the pkgrel to 0.&lt;br /&gt;
&lt;br /&gt;
==== pkgname  ====&lt;br /&gt;
&lt;br /&gt;
The base name of the package you are creating.  For Freeswitch 1.0.6, you would use &amp;quot;freeswitch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== install  ====&lt;br /&gt;
&lt;br /&gt;
There are 6 different kinds of install scripts. Each script is called with the $pkgname.&#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; where &#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; is one of the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before package is installed. Typical use is when package needs a group and a user to be created. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
addgroup -S clamav 2&amp;gt;/dev/null&lt;br /&gt;
adduser -S -D -H -s /bin/false -G clamav -g clamav clamav 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the &#039;&#039;exit 0&#039;&#039; at the end. If the script exits with failure (if the user already exist), the package will not be installed and &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; will exit with failure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after the package is installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as pre-install but is executed before upgrading/downgrading/reinstalling an already installed package. Note that exiting with failure will not cause apk to exit with failure, but will mark the package as broken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as post-install but is executed after upgrading/downgrading/reinstalling an already installed package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before uninstalling a package. If script exits with failure apk will not uninstall the package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after a package have been uninstalled. For example, can be used to restore busybox links:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
busybox --install -s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the package has a pre-install and post-install script the APKBUILD should have the &#039;&#039;install&#039;&#039; variable defined:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
install=&amp;quot;$pkgname.pre-install $pkgname.post-install&amp;quot;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== subpackages  ====&lt;br /&gt;
&lt;br /&gt;
$subpackages are made to split up the normal &amp;quot;make install&amp;quot; into separate packages. The most common subpackages we use are doc and dev. Because we like to keep our target system small we move documentation and development files (only needed when building packages) into separate packages. To use the specific program a user only need to install the base apk without package-doc or package-dev, but if he wants to read the manual he will need to install package-doc. &lt;br /&gt;
&lt;br /&gt;
The easiest way to find out if you need to use -dev and -doc is to first build the package without these options set and wait until the build finishes. When its finished you should have a pkg directory which is the fake root directory. Inside this directory you will see the structure as how it would be installed in / on the target system. &lt;br /&gt;
&lt;br /&gt;
To see if you need the -dev package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/ -name &#039;*.[acho]&#039; -o -name &#039;*.la&#039;}}&lt;br /&gt;
&lt;br /&gt;
If this returns any files you need to include the -dev package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; To see if you need the -doc package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/share -name doc -o -name man -o -name info -o -name html -o -name sgml -o -name licenses}}&lt;br /&gt;
&lt;br /&gt;
If this returns any directories you need to include the -doc package. &lt;br /&gt;
&lt;br /&gt;
===== Custom subpackages  =====&lt;br /&gt;
&lt;br /&gt;
Some software additionally has non-essential files that do not qualify as either documentation or development content. These files should be placed in their own, specialized subpackage(s). Some packages include large test suites which are only needed in specific circumstances or binaries which have depends which we prefer not to install. To handle those we create our own package/function. In the APKBUILD below the build() function we create another function: &lt;br /&gt;
&lt;br /&gt;
 test() {&lt;br /&gt;
        mkdir -p &amp;quot;$subpkgdir&amp;quot;/usr&lt;br /&gt;
        mv &amp;quot;$pkgdir&amp;quot;/usr/package-test &amp;quot;$subpkgdir&amp;quot;/usr/&lt;br /&gt;
        # or amove usr/package-test&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We also need to add the package info to $subpackages variable: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc $pkgname-dev $pkgname-test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
After we finish building the package you should see another apk called packagename-test.apk which includes the files which we moved to the $subpkgdir dir. &lt;br /&gt;
&lt;br /&gt;
The above mentioned variables can also be used in our custom function. If we want for instance to build the test() function with perl support we would add: &lt;br /&gt;
&lt;br /&gt;
 depends=&amp;quot;perl&amp;quot;&lt;br /&gt;
 makedepends=&amp;quot;perl-dev&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we would install the base package it would not install perl, but if we install the package-test package it would.&lt;br /&gt;
&lt;br /&gt;
==== Patches  ====&lt;br /&gt;
&lt;br /&gt;
Please make sure you always submit human readable patches. Ways to create them are: &lt;br /&gt;
&lt;br /&gt;
directory compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -Nurp original_directory new_directory &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
file compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -up original.file new.file &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
If a patch contains a completely new file but not *.rej or *.orig file, you need to add -N option to diff, but you may need to add exclusions with &amp;lt;code&amp;gt;--exclude PATTERN&amp;lt;/code&amp;gt; so that you do not inadvertently add files.  You may need to manually delete unwanted files inside the patch file.&lt;br /&gt;
&lt;br /&gt;
Because multiple patches can patch the same file, they can change the offsets required by subsequent patches. To make sure we always patch in a specific way, we should number the patches as follows: &lt;br /&gt;
&lt;br /&gt;
 10-patch1.patch 20-patch2.patch 30-patch3.patch&lt;br /&gt;
&lt;br /&gt;
This way we are always sure that patch 1 is applied first, and if we want to add additional patches between them we can use appropriate indexes (e.g. 11, 12, 21, 22).&lt;br /&gt;
&lt;br /&gt;
Add the names of the patch files to the &#039;&#039;source&#039;&#039; variable. If you haven&#039;t declared a custom &#039;&#039;prepare&#039;&#039; function, no further action is necessary. Otherwise, be sure to call &#039;&#039;default_prepare&#039;&#039; in your &#039;&#039;prepare&#039;&#039; function. For example:&lt;br /&gt;
&lt;br /&gt;
 prepare() {&lt;br /&gt;
 	default_prepare&lt;br /&gt;
 &lt;br /&gt;
 	# do your stuff&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Note: Some older packages contain a &#039;&#039;for&#039;&#039; loop in the &#039;&#039;prepare&#039;&#039; function to apply patches. This is not needed anymore, as patches are handled by &#039;&#039;default_prepare&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In Alpine &amp;gt;=3.4 you can define patch_args to supply the patch level.  This only works if all the patches have the same patch level.  If there are a lot of patches from different sources, there is a good chance that you may need to edit them, as discussed below.&lt;br /&gt;
&lt;br /&gt;
To automatically patch the package (available only in Alpine &amp;gt;=3.4) if it uses a patch level (-pX) other than the default (-p1), you need to carefully modify the patch.  First, you&#039;ll need a text editor that does not automatically convert  between Windows and Unix new lines (or, disable this feature) so that it preserves the old code.  The next thing you&#039;ll need to do is modify the paths on &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines in the .patch file.  You can begin the path with a/ and b/ like shown below.  Next, you need to adjust the paths so that the relative base path is from inside $builddir.  Anything to the left of $builddir, including $builddir itself, needs to be removed from the path.  So, if $builddir is /home/USER/aports/community/chromium/src/chromium-65, you need to erase it on the &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines.  Inside the chromium-65 folder you can see a src folder that has 3rdparty as a descendant.  If a patch originally has a deeper patch level, you may need to fill in the missing portion of the path.  For example, use the &amp;lt;code&amp;gt;find . -name &amp;quot;Assertions.cpp&amp;quot;&amp;lt;/code&amp;gt; command to find the full path to the file relative to the base.&lt;br /&gt;
&lt;br /&gt;
{{Cat|example.patch|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Author: John Doe &amp;lt;johndoe@mail.com&amp;gt;&lt;br /&gt;
URL: http://.....&lt;br /&gt;
Summary: Fixes musl compatibility&lt;br /&gt;
----&lt;br /&gt;
--- a/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp.orig&lt;br /&gt;
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp&lt;br /&gt;
@@ -142,7 +142,7 @@&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 FrameToNameScope::FrameToNameScope(void* addr) : m_name(0), m_cxaDemangled(0) {&lt;br /&gt;
-#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; !defined(__UCLIBC__))&lt;br /&gt;
+#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; defined(__GLIBC__))&lt;br /&gt;
   Dl_info info;&lt;br /&gt;
   if (!dladdr(addr, &amp;amp;info) || !info.dli_sname)&lt;br /&gt;
return;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Portions of the patch may be outdated, removed completely as in the source code file completely removed, or moved or renamed files.  You need to delete that section of the patch or find where that section of code changed and re-diff it.&lt;br /&gt;
&lt;br /&gt;
It is good etiquette to give credit at the top and the location of where you originally found them with notes.&lt;br /&gt;
&lt;br /&gt;
Excluding patches with global variable resembling patch_opts is not available on Alpine.  To exclude patches you need to create your own custom prepare().&lt;br /&gt;
&lt;br /&gt;
If you have a monolithic patch where there are a bunch of patches in one big patch, you could use filterdiff which is available in the patchutils package.&lt;br /&gt;
&lt;br /&gt;
Just do something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
makedepends=&amp;quot;patchutils&amp;quot;&lt;br /&gt;
&lt;br /&gt;
prepare() {&lt;br /&gt;
  ...&lt;br /&gt;
  cd &amp;quot;$builddir&amp;quot;&lt;br /&gt;
  filterdiff -x &#039;*drivers/video/logo*&#039; &amp;quot;$srcdir&amp;quot;/original.patch &amp;gt; &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
  patch -p1 -i &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to put the wildcard pattern in single quotes for it to work.&lt;br /&gt;
&lt;br /&gt;
==== Configure options  ====&lt;br /&gt;
&lt;br /&gt;
Alpine has some default configure options we set by default. We use /usr for prefix to make sure everything is installed with /usr in front of it. If you notice that anything is installed in the wrong directory please run {{Cmd|./configure --help}} and see if you can set the correct location. &lt;br /&gt;
&lt;br /&gt;
We are not covering the depend switches here we have discussed this already in the depend section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Make options  ====&lt;br /&gt;
&lt;br /&gt;
If you notice weird problems when compiling or installing the package with make/make install you could try to disable [https://www.gnu.org/software/make/manual/make.html#Parallel parallel] building/installing. A normal make line would be: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make}}&lt;br /&gt;
&lt;br /&gt;
To disable parallel we use: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make -j1}}&lt;br /&gt;
&lt;br /&gt;
We can use the same for make install. &lt;br /&gt;
&lt;br /&gt;
Because we do not want to install the package in our build environment but we want to install it in a fake root directory we need to tell &#039;make install&#039; to use another destination directory instead of &#039;/&#039;. We do this by setting a variable when we execute make install as followed: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make DESTDIR{{=}}&amp;quot;$pkgdir&amp;quot; install}}&lt;br /&gt;
&lt;br /&gt;
Please note that some Makefiles do not support this variable and will always install software in &#039;/&#039;. To make sure you do not mess up your build system NEVER run your build system as root but always use a custom user and doas when needed. If by accident the Makefile does not support DESTDIR variable it will fail to install in our build system system directories.&lt;br /&gt;
&lt;br /&gt;
==== builddir ====&lt;br /&gt;
If you used &amp;lt;tt&amp;gt;newapkbuild&amp;lt;/tt&amp;gt; to create your APKBUILD file, you must specify the path to your unpacked sources. Inside the sections during the prepare/build/install process &#039;&#039;builddir&#039;&#039; is used. Most of the time a combination of &#039;&#039;$srcdir&#039;&#039; and &#039;&#039;$pkgname-$pkgver&#039;&#039; will work. When not, check the /src directory or the source tarball for the right string. Especially when you are working with automatically generated tarballs (like from github and gitorious), this needs to be adjusted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
builddir=&amp;quot;$srcdir&amp;quot;/$pkgname-$pkgver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Additional files  ====&lt;br /&gt;
&lt;br /&gt;
If you want/need to install additional files not mentioned above you can use the following cmd (this is an example of a conf file): &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 doc/$pkgname.conf &amp;quot;$pkgdir&amp;quot;/etc/$pkgname.conf}}&lt;br /&gt;
&lt;br /&gt;
== Build the package  ==&lt;br /&gt;
&lt;br /&gt;
If you did not already create the checksums as mentioned above you can do so now: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $pkgname&lt;br /&gt;
abuild checksum}}&lt;br /&gt;
&lt;br /&gt;
It&#039;s about time we build our package. Because a build system should never have all the package installed to prevent linking to packages we don&#039;t want it to link we use a abuild recursively with the &#039;&#039;&#039;-r&#039;&#039;&#039; switch. It will install all dependencies from your repository and builds it, afterwards it will uninstall all those depending packages again.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -r}}&lt;br /&gt;
&lt;br /&gt;
See also [[Abuild_and_Helpers|Abuild and Helpers]].&lt;br /&gt;
&lt;br /&gt;
== Testing the package locally ==&lt;br /&gt;
&lt;br /&gt;
When it completes, your package will be found in a subfolder of &amp;lt;code&amp;gt;~/packages&amp;lt;/code&amp;gt;.  You may want to test it on your machine but only if the package is not a critical system package like musl or apk-tools package.  To avoid borking your system (as in making it impossible to use &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; or to restore back the system and the compiler toolchain) for a critical system package, you should test on a chroot first before using it live.&lt;br /&gt;
&lt;br /&gt;
The best way to test a package locally is to modify your &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; so that it includes the indexes to your locally built packages - the directories that contain &amp;lt;code&amp;gt;ARCH/APKINDEX.tar.gz&amp;lt;/code&amp;gt;. For example the &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; below includes locally built packages in testing, community and main. To use this example change &amp;lt;code&amp;gt;USER&amp;lt;/code&amp;gt; to your login name.&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/apk/repositories|/home/USER/packages/testing/&lt;br /&gt;
/home/USER/packages/main/&lt;br /&gt;
/home/USER/packages/community/&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you prefer to test a package without changing any other configuration you can use the &amp;lt;code&amp;gt;-X, --repository&amp;lt;/code&amp;gt; option to &amp;lt;code&amp;gt;apk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|doas apk add --repository /home/USER/packages/testing $pkgname}}&lt;br /&gt;
&lt;br /&gt;
== Code review ==&lt;br /&gt;
&lt;br /&gt;
To successfully have your package pass through code reviewers (as of Feb 18, 2018 are nmeum and jirutka on GitHub) and possible increased acceptance, the following conventions need to be followed:&lt;br /&gt;
&lt;br /&gt;
# Custom global variables should be prefixed with underscore (_).&lt;br /&gt;
# Compact code as in merged commands, removed unused variables, removal of functions that do the same thing that are automatically handled by abuild.&lt;br /&gt;
# Versioning is done properly.  For details see [[APKBUILD_Reference#pkgver]].&lt;br /&gt;
# Licensing is done properly. Remove unnecessary copying of licensing that is already OSI approved.&lt;br /&gt;
# Naming conventions rules for unofficial variables as in _gitrev is preferred over commit.&lt;br /&gt;
# Indent with tabs not spaces.&lt;br /&gt;
# Removal of explicit return 1.  (They are still found the old APKBUILD files if you are learning but are now strongly discouraged.)&lt;br /&gt;
# Disabling check() requires either (1) a comment (#) stating next to options=&amp;quot;!check&amp;quot; that there is no test suite/unit tests or (2) functioning working check() function.&lt;br /&gt;
# Explicit call to subpackages=&amp;quot;$pkgname-doc&amp;quot; must be used instead of explicit gzip man page compression.&lt;br /&gt;
# Ideally, lines should be no more than 80 columns wide&lt;br /&gt;
&lt;br /&gt;
Additionally, make sure to run the linter on your package:&lt;br /&gt;
{{Cmd|doas apk add atools&lt;br /&gt;
apkbuild-lint APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
For more information see [[Development using git:Quality assurance]] and [[Package_policies]].&lt;br /&gt;
Also check out [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/COMMITSTYLE.md?ref_type=heads aports/COMMITSTYLE.md] and [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/CODINGSTYLE.md?ref_type=heads aports/CODINGSTYLE.md]&lt;br /&gt;
&lt;br /&gt;
== Commit your work  ==&lt;br /&gt;
&lt;br /&gt;
After you successfully build your package and properly followed the conventions and requirements in the code review section, you can submit your APKBUILD to Alpine&#039;s git repository. &lt;br /&gt;
&lt;br /&gt;
Update your git repo, before adding new files: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git pull}}&lt;br /&gt;
&lt;br /&gt;
This should pull all the changes made by others into your local git repo.&lt;br /&gt;
&lt;br /&gt;
When you think you are ready you can add your files to git: &lt;br /&gt;
&lt;br /&gt;
NOTE: when using our Gitlab instance, you can create MR&#039;s for each package. Please squash all commits related to the same package into a single one per MR.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git add testing/$pkgdir (include any other files needed for the build; $pkgname.install...)&lt;br /&gt;
git commit}}&lt;br /&gt;
&lt;br /&gt;
Use the following commit message template for new aports (without the comments):&lt;br /&gt;
&lt;br /&gt;
{{Cat|template|testing/$pkgname: new aport   # this will be the subject line&lt;br /&gt;
                              # a blank line&lt;br /&gt;
$url                          # project homepage&lt;br /&gt;
$pkgdesc                      # one line description}}&lt;br /&gt;
&lt;br /&gt;
Or you could add the following and &amp;lt;code&amp;gt;chmod +x ports/.git/hooks/prepare-commit-msg&amp;lt;/code&amp;gt; to automatically generate commit message which the default aports/.githooks/ does not:&lt;br /&gt;
&lt;br /&gt;
{{Cat|aports/.git/hooks/prepare-commit-msg|&amp;lt;nowiki&amp;gt;#!/bin/sh&lt;br /&gt;
case &amp;quot;$2,$3&amp;quot; in&lt;br /&gt;
  ,|template,)&lt;br /&gt;
    if git diff-index --diff-filter=A --name-only --cached HEAD \&lt;br /&gt;
        | grep -q &#039;/APKBUILD$&#039;; then&lt;br /&gt;
      meta() { git diff --staged | grep &amp;quot;^+$1&amp;quot; | sed &#039;s/.*=&amp;quot;\?//;s/&amp;quot;$//&#039;;}&lt;br /&gt;
      printf &#039;testing/%s: new aport\n\n%s\n%s\n&#039; &amp;quot;$(meta pkgname)&amp;quot; \&lt;br /&gt;
        &amp;quot;$(meta url)&amp;quot; &amp;quot;$(meta pkgdesc)&amp;quot; &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      printf &#039;%s\n\n%s&#039; `git diff-index --name-only --cached HEAD \&lt;br /&gt;
        | sed -n &#039;s/\/APKBUILD$//p;q&#039;` &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    fi;;&lt;br /&gt;
esac&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Now your changes are only available locally in your repository.&lt;br /&gt;
&lt;br /&gt;
Because you do not have push rights to the Alpine aports repository you need to create a merge request to [https://gitlab.alpinelinux.org/alpine/aports Alpine&#039;s GitLab instance].&lt;br /&gt;
&lt;br /&gt;
Alternatively you can also create a diff (patch) of the changes you made and send this patch to the &lt;br /&gt;
[https://lists.alpinelinux.org/~alpine/aports  alpine-aports mailinglist].&lt;br /&gt;
&lt;br /&gt;
To create a diff patch:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^}}&lt;br /&gt;
&lt;br /&gt;
or if you have sprunge, you can create a link to your patch for convenience&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^ --stdout &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; sprunge}}&lt;br /&gt;
&lt;br /&gt;
== Automated flagging of outdated ports ==&lt;br /&gt;
Consider adding your port to [https://release-monitoring.org/ Anitya], so it will be flagged as outdated&lt;br /&gt;
as soon as a new stable version is released by upstream.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[APKBUILD Reference]]&lt;br /&gt;
* [[APKBUILD examples]]&lt;br /&gt;
* [[Development using git]]&lt;br /&gt;
* [[Development using git:Quality assurance]]&lt;br /&gt;
&lt;br /&gt;
[[category: Package Manager]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26378</id>
		<title>Creating an Alpine package</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26378"/>
		<updated>2024-02-11T23:44:38Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This is a brief list of the steps to add a new package. Details are below, but a NB can miss a few steps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create an account on github.alpine&lt;br /&gt;
&amp;lt;li&amp;gt;Setup the build environment for aports.&lt;br /&gt;
&amp;lt;li&amp;gt;Fork the aports repository. &lt;br /&gt;
&amp;lt;li&amp;gt;Clone your new fork.&lt;br /&gt;
&amp;lt;li&amp;gt;Set git pull.rebase=true, set your username and email.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a new branch (don&#039;t use master).&lt;br /&gt;
&amp;lt;li&amp;gt;Add a new directory under testing that is your new package name.&lt;br /&gt;
&amp;lt;li&amp;gt;Add your APKBUILD file.&lt;br /&gt;
&amp;lt;li&amp;gt;Run abuild checksum&lt;br /&gt;
&amp;lt;li&amp;gt;Make sure you run the apkbuild-lint and aport -r and there are no warnings.&lt;br /&gt;
&amp;lt;li&amp;gt;Commit your APKBUILD with the commit message: &#039;testing/packagename: new aport&#039;&lt;br /&gt;
&amp;lt;li&amp;gt;Push your changes to your fork on github.alpine.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a merge request.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the rest of this wiki for details on the steps above.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
To build a package for Alpine Linux you need an Alpine Linux installation. Check the [[Installation]] page to see all available installation options.&lt;br /&gt;
&lt;br /&gt;
== Setup your system and account  ==&lt;br /&gt;
{{:Setup_your_system_and_account_for_building_packages}}&lt;br /&gt;
&lt;br /&gt;
== Getting some help ==&lt;br /&gt;
&lt;br /&gt;
It might be wise to start by checking what the [[Abuild and Helpers|abuild]] program can/cannot do.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -h}}&lt;br /&gt;
&lt;br /&gt;
For real help, you can also go on #alpine-devel on [[IRC]].&lt;br /&gt;
&lt;br /&gt;
A reference for APKBUILD files is available as [[APKBUILD Reference]] wiki page or a man page in the &#039;abuild-doc&#039; package:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|man APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Creating an APKBUILD file  ==&lt;br /&gt;
&lt;br /&gt;
=== Use a template APKBUILD ===&lt;br /&gt;
&lt;br /&gt;
To create the actual APKBUILD file {{Pkg|newapkbuild}} can serve you a template to start with. It will create a directory with the given package name, place an example/template APKBUILD file to the given directory, and fill some variables if those are provided. Please check the [[Package_policies| package policies]] page about naming details.&lt;br /&gt;
&lt;br /&gt;
If you doubt to which repository your package belongs to you can safely use &#039;&#039;&#039;testing&#039;&#039;&#039;. Building package in your aports/testing directory is not mandatory but this way the package is already at the right place.&lt;br /&gt;
&lt;br /&gt;
{{:Abuild and Helpers}}&lt;br /&gt;
&lt;br /&gt;
{{Note|On older Alpine systems, abuild -c -n &#039;&#039;packagename&#039;&#039; was the way to create APKBUILD files. The &#039;packagename&#039; was a parameter to the -n option so order of -c and -n matters. }}&lt;br /&gt;
&lt;br /&gt;
[[Abuild_and_Helpers#apkbuild-cpan|apkbuild-cpan]] simplifies the creation of perl packages from CPAN and [[Abuild_and_Helpers#apkbuild-pypi|apkbuild-pypi]] ease the generation of APKBUILD files for python packages from PyPi.  &lt;br /&gt;
&lt;br /&gt;
If you are creating a daemon package which needs initd scripts you can add the -c making it: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|newapkbuild -c &#039;&#039;packagename&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This will copy the sample initd and confd files to the build directory.&amp;lt;BR&amp;gt;&lt;br /&gt;
A third file sample.install file will be copied as well (we will discuss this later on).&lt;br /&gt;
&lt;br /&gt;
=== Modify your APKBUILD ===&lt;br /&gt;
Edit APKBUILD and fill in the needed info (especially pkgname, pkgver, pkgdesc, url, license, depends and source). &lt;br /&gt;
&lt;br /&gt;
If you are going to use any of the variables for directories like $pkgdir, always make sure they are double quoted like: &lt;br /&gt;
&lt;br /&gt;
 &amp;quot;$pkgdir&amp;quot;/somedir&lt;br /&gt;
&lt;br /&gt;
This will prevent issues with spaces/special characters in the future. &lt;br /&gt;
&lt;br /&gt;
{{Note|If you like syntax highlighting we suggest you to install vim. We have setup vim to recognize the APKBUILD file as a bash scripts so its easier to read them.}}&lt;br /&gt;
&lt;br /&gt;
=== APKBUILD variables/functions  ===&lt;br /&gt;
&lt;br /&gt;
==== source  ====&lt;br /&gt;
&lt;br /&gt;
The source variable is not only used to list the remote source files to fetch, it is also used to list the local files that abuild will need in order to build the apk. Examples of such local files include: init.d files, conf.d files, install files (see [[Creating an Alpine package#install|install variable]]), patches, and all other necessary files.&lt;br /&gt;
&lt;br /&gt;
Here are few things to note:&lt;br /&gt;
&lt;br /&gt;
* When you are finished adding local and/or remote files to &#039;&#039;source&#039;&#039;, you can execute the following command to add their checksums to the APKBUILD file:&lt;br /&gt;
: {{cmd|abuild checksum}}&lt;br /&gt;
: {{Note|When later updating the content of &#039;&#039;source&#039;&#039;, or updating a file that is listed in &#039;&#039;source&#039;&#039;, you must also update their checksums again with the same command.}}&lt;br /&gt;
&lt;br /&gt;
* When the remote file is hosted at SourceForge, it&#039;s best to specify the special mirrors link used by SourceForge:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
: (or similar depending on the package).&lt;br /&gt;
&lt;br /&gt;
* When the remote filename is not specified in the URI (ie, does not end in &#039;/software-1.0.tar.gz&#039;), such as:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
: You must prepend &#039;${pkgname}-${pkgver}.tar.gz::&#039; to the protocol, like so:&lt;br /&gt;
: &amp;lt;pre&amp;gt;source=&amp;quot;${pkgname}-${pkgver}.tar.gz::http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
: This causes the file to be saved as &#039;&#039;software-1.0.tar.gz&#039;&#039; where abuild can use it, instead of &#039;&#039;?get=software&amp;amp;ver=1.0&#039;&#039;, where abuild cannot use it.&lt;br /&gt;
&lt;br /&gt;
* Some projects didn&#039;t provide a release tarball. Beware that some git services (gitweg, cgit, …?) doesn’t provide &#039;&#039;stable&#039;&#039; tarballs, so when you point source to an tarball like &amp;lt;tt&amp;gt;https://repo.or.cz/w/gitstats.git/snapshot/ad7efbb9399e60cee6cb217c6b47e604174a8093.tar.gz&amp;lt;/tt&amp;gt;, then you will run into issues because the checksum changes when downloading on the build system. This is not a problem on GitHub, GitLab and other decent services provides, they provide &#039;&#039;stable&#039;&#039; tarballs.&lt;br /&gt;
&lt;br /&gt;
* abuild currently supports the following protocols for remote file retrieval:&lt;br /&gt;
** http&lt;br /&gt;
** https&lt;br /&gt;
** ftp&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--: {{Note|If the you want to download from https, you need GNU wget installed on your system.}}--&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
* abuild currently supports the following archive types/archive file extensions:&lt;br /&gt;
** .tar&lt;br /&gt;
** .tar.gz / .tgz&lt;br /&gt;
** .tar.bz2&lt;br /&gt;
** .tar.lz (only in Alpine &amp;gt;=3.7)&lt;br /&gt;
** .tar.lzma&lt;br /&gt;
** .tar.xz&lt;br /&gt;
** .zip&lt;br /&gt;
&lt;br /&gt;
==== depends &amp;amp;amp; makedepends  ====&lt;br /&gt;
&lt;br /&gt;
Depends are the actual running dependencies that a package would need when it is running. Makedepends are only needed when you are building a package. If you set a package in depends, you do not need to add it to makedepends as well. The best way to find out what the depends and makedepends of a package are is to [https://en.wikipedia.org/wiki/Rtfm RTFM]. &lt;br /&gt;
&lt;br /&gt;
No kidding, lots of important information can be found in the package INSTALL and README files (or the likes). Another good way is the run &amp;lt;code&amp;gt;./configure --help&amp;lt;/code&amp;gt; from the source directory to see which options are needed for configure to finish without errors. If you do not yet have a source directory you can create one with the command: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild unpack}}&lt;br /&gt;
&lt;br /&gt;
Running &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt; will also show you how you can disable a specific option for this package. For instance, a good example is &amp;quot;--disable-nls&amp;quot; which will disable native language support and thus does not depend on gettext (libiconv, glib, ...). &lt;br /&gt;
&lt;br /&gt;
Alpine likes to keep things small, so we try to disable as much as possible without losing too many features. The exact disable/enable options are decided by the package builder but please try to follow Alpine&#039;s design concept as much as possible.&lt;br /&gt;
&lt;br /&gt;
An easy way of quickly finding out the build info for a package is to check Arch Linux (Alpine package management and build scripts are similar) or Gentoo Linux ebuilds (previous versions of Alpine were based on Gentoo).&lt;br /&gt;
&lt;br /&gt;
* [https://gitweb.gentoo.org/repo/gentoo.git/tree/ Gentoo Ebuilds] &lt;br /&gt;
* [https://archlinux.org/packages/?q=search Arch Linux packages] [https://aur.archlinux.org/ Arch Linux User Repository]&lt;br /&gt;
&lt;br /&gt;
==== license  ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;license&#039;&#039;&#039; tag must reflect the license of the source code. Please check the source tarball for COPYING, LICENSE, or other files with names that indicates that it contains licensing information. Beside the license file most developer include headers in the source code files with licensing details.&lt;br /&gt;
&lt;br /&gt;
If the license is on the [https://spdx.org/licenses/ SPDX License List] or [https://spdx.org/licenses/exceptions-index.html SPDX License Exceptions], use the identifier specified by SPDX.&lt;br /&gt;
&lt;br /&gt;
Note that some licenses have additional requirements that should be adhered to. The &amp;lt;code&amp;gt;MIT&amp;lt;/code&amp;gt; license for example has the requirement:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that we need to include the license as shipped with the project.&lt;br /&gt;
&lt;br /&gt;
If a package has a special/custom license or is not listed as [https://opensource.org/licenses/alphabetical OSI approved], use the identifier &amp;quot;custom&amp;quot;. In that case we need to provide the license file with the package as well.&lt;br /&gt;
&lt;br /&gt;
Because we want to save space and don&#039;t like to have licenses all over our system we have decided to include the license in the doc subpackage. Please follow the following guidelines to add a proper license. Locate the license file inside the source package. Add the doc subpackage to the $subpackages variable as follows: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a similar line to the following to your package() function, depending on the license description file: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 COPYING &amp;quot;$pkgdir&amp;quot;/usr/share/licenses/$pkgname/COPYING}}&lt;br /&gt;
&lt;br /&gt;
If you follow these steps then abuild will automatically add the license to the package-doc apk for you.&lt;br /&gt;
&lt;br /&gt;
{{Warning|It is not acceptable to package software with &amp;quot;unknown&amp;quot; license! If you can&#039;t find the license of the source code, please contact the author and ask them to specify the license. }}&lt;br /&gt;
&lt;br /&gt;
==== arch ====&lt;br /&gt;
&lt;br /&gt;
The package architecture(s) to build for.  This can be one of: &#039;&#039;x86, x86_64, all,&#039;&#039; or &#039;&#039;noarch&#039;&#039;, where &#039;&#039;all&#039;&#039; means all architectures, and &#039;&#039;noarch&#039;&#039; means it&#039;s architecture-independent (e.g., a pure-python package).&lt;br /&gt;
{{Tip|To determine if your APKBUILD can use &#039;&#039;noarch&#039;&#039;, build the package for your architecture and then run &amp;quot;scanelf -R pkg&amp;quot; from the directory that the APKBUILD resides in, in order to scan for ELF files in the &#039;&#039;./pkg&#039;&#039; directory.  If you do NOT get output from this, then &#039;&#039;noarch&#039;&#039; can be used.}}&lt;br /&gt;
&lt;br /&gt;
==== url  ====&lt;br /&gt;
&lt;br /&gt;
Website address for the program. This is useful later on when either finding documentation or other information about the package.&lt;br /&gt;
&lt;br /&gt;
==== pkgdesc  ====&lt;br /&gt;
&lt;br /&gt;
A brief, one line, description of what the package does. Useful for the package management system. It should start with a capital letter and does &#039;&#039;&#039;not&#039;&#039;&#039; end with a period.&lt;br /&gt;
&lt;br /&gt;
Here is an example from apk_info for the OpenSSH client package:&lt;br /&gt;
&lt;br /&gt;
 pkgdesc=&amp;quot;Port of OpenBSD&#039;s free SSH release - client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== pkgver  ====&lt;br /&gt;
&lt;br /&gt;
Provide the release number of the package you are building.&lt;br /&gt;
&lt;br /&gt;
==== pkgrel  ====&lt;br /&gt;
&lt;br /&gt;
The $pkgrel versioning is made so that if you change something in your APKBUILD file without changing the actual $pkgver, you can increment pkgrel so apk tools will detect it as an update. For instance, if you forget to add a dependency, you can add it afterward and you can +1 pkgver so apk finds this update and adds the missing dependency. When there&#039;s an upstream version change, we reset the pkgrel to 0.&lt;br /&gt;
&lt;br /&gt;
==== pkgname  ====&lt;br /&gt;
&lt;br /&gt;
The base name of the package you are creating.  For Freeswitch 1.0.6, you would use &amp;quot;freeswitch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== install  ====&lt;br /&gt;
&lt;br /&gt;
There are 6 different kinds of install scripts. Each script is called with the $pkgname.&#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; where &#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; is one of the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before package is installed. Typical use is when package needs a group and a user to be created. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
addgroup -S clamav 2&amp;gt;/dev/null&lt;br /&gt;
adduser -S -D -H -s /bin/false -G clamav -g clamav clamav 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the &#039;&#039;exit 0&#039;&#039; at the end. If the script exits with failure (if the user already exist), the package will not be installed and &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; will exit with failure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after the package is installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as pre-install but is executed before upgrading/downgrading/reinstalling an already installed package. Note that exiting with failure will not cause apk to exit with failure, but will mark the package as broken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as post-install but is executed after upgrading/downgrading/reinstalling an already installed package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before uninstalling a package. If script exits with failure apk will not uninstall the package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after a package have been uninstalled. For example, can be used to restore busybox links:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
busybox --install -s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the package has a pre-install and post-install script the APKBUILD should have the &#039;&#039;install&#039;&#039; variable defined:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
install=&amp;quot;$pkgname.pre-install $pkgname.post-install&amp;quot;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== subpackages  ====&lt;br /&gt;
&lt;br /&gt;
$subpackages are made to split up the normal &amp;quot;make install&amp;quot; into separate packages. The most common subpackages we use are doc and dev. Because we like to keep our target system small we move documentation and development files (only needed when building packages) into separate packages. To use the specific program a user only need to install the base apk without package-doc or package-dev, but if he wants to read the manual he will need to install package-doc. &lt;br /&gt;
&lt;br /&gt;
The easiest way to find out if you need to use -dev and -doc is to first build the package without these options set and wait until the build finishes. When its finished you should have a pkg directory which is the fake root directory. Inside this directory you will see the structure as how it would be installed in / on the target system. &lt;br /&gt;
&lt;br /&gt;
To see if you need the -dev package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/ -name &#039;*.[acho]&#039; -o -name &#039;*.la&#039;}}&lt;br /&gt;
&lt;br /&gt;
If this returns any files you need to include the -dev package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; To see if you need the -doc package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/share -name doc -o -name man -o -name info -o -name html -o -name sgml -o -name licenses}}&lt;br /&gt;
&lt;br /&gt;
If this returns any directories you need to include the -doc package. &lt;br /&gt;
&lt;br /&gt;
===== Custom subpackages  =====&lt;br /&gt;
&lt;br /&gt;
Some software additionally has non-essential files that do not qualify as either documentation or development content. These files should be placed in their own, specialized subpackage(s). Some packages include large test suites which are only needed in specific circumstances or binaries which have depends which we prefer not to install. To handle those we create our own package/function. In the APKBUILD below the build() function we create another function: &lt;br /&gt;
&lt;br /&gt;
 test() {&lt;br /&gt;
        mkdir -p &amp;quot;$subpkgdir&amp;quot;/usr&lt;br /&gt;
        mv &amp;quot;$pkgdir&amp;quot;/usr/package-test &amp;quot;$subpkgdir&amp;quot;/usr/&lt;br /&gt;
        # or amove usr/package-test&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We also need to add the package info to $subpackages variable: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc $pkgname-dev $pkgname-test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
After we finish building the package you should see another apk called packagename-test.apk which includes the files which we moved to the $subpkgdir dir. &lt;br /&gt;
&lt;br /&gt;
The above mentioned variables can also be used in our custom function. If we want for instance to build the test() function with perl support we would add: &lt;br /&gt;
&lt;br /&gt;
 depends=&amp;quot;perl&amp;quot;&lt;br /&gt;
 makedepends=&amp;quot;perl-dev&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we would install the base package it would not install perl, but if we install the package-test package it would.&lt;br /&gt;
&lt;br /&gt;
==== Patches  ====&lt;br /&gt;
&lt;br /&gt;
Please make sure you always submit human readable patches. Ways to create them are: &lt;br /&gt;
&lt;br /&gt;
directory compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -Nurp original_directory new_directory &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
file compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -up original.file new.file &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
If a patch contains a completely new file but not *.rej or *.orig file, you need to add -N option to diff, but you may need to add exclusions with &amp;lt;code&amp;gt;--exclude PATTERN&amp;lt;/code&amp;gt; so that you do not inadvertently add files.  You may need to manually delete unwanted files inside the patch file.&lt;br /&gt;
&lt;br /&gt;
Because multiple patches can patch the same file, they can change the offsets required by subsequent patches. To make sure we always patch in a specific way, we should number the patches as follows: &lt;br /&gt;
&lt;br /&gt;
 10-patch1.patch 20-patch2.patch 30-patch3.patch&lt;br /&gt;
&lt;br /&gt;
This way we are always sure that patch 1 is applied first, and if we want to add additional patches between them we can use appropriate indexes (e.g. 11, 12, 21, 22).&lt;br /&gt;
&lt;br /&gt;
Add the names of the patch files to the &#039;&#039;source&#039;&#039; variable. If you haven&#039;t declared a custom &#039;&#039;prepare&#039;&#039; function, no further action is necessary. Otherwise, be sure to call &#039;&#039;default_prepare&#039;&#039; in your &#039;&#039;prepare&#039;&#039; function. For example:&lt;br /&gt;
&lt;br /&gt;
 prepare() {&lt;br /&gt;
 	default_prepare&lt;br /&gt;
 &lt;br /&gt;
 	# do your stuff&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Note: Some older packages contain a &#039;&#039;for&#039;&#039; loop in the &#039;&#039;prepare&#039;&#039; function to apply patches. This is not needed anymore, as patches are handled by &#039;&#039;default_prepare&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In Alpine &amp;gt;=3.4 you can define patch_args to supply the patch level.  This only works if all the patches have the same patch level.  If there are a lot of patches from different sources, there is a good chance that you may need to edit them, as discussed below.&lt;br /&gt;
&lt;br /&gt;
To automatically patch the package (available only in Alpine &amp;gt;=3.4) if it uses a patch level (-pX) other than the default (-p1), you need to carefully modify the patch.  First, you&#039;ll need a text editor that does not automatically convert  between Windows and Unix new lines (or, disable this feature) so that it preserves the old code.  The next thing you&#039;ll need to do is modify the paths on &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines in the .patch file.  You can begin the path with a/ and b/ like shown below.  Next, you need to adjust the paths so that the relative base path is from inside $builddir.  Anything to the left of $builddir, including $builddir itself, needs to be removed from the path.  So, if $builddir is /home/USER/aports/community/chromium/src/chromium-65, you need to erase it on the &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines.  Inside the chromium-65 folder you can see a src folder that has 3rdparty as a descendant.  If a patch originally has a deeper patch level, you may need to fill in the missing portion of the path.  For example, use the &amp;lt;code&amp;gt;find . -name &amp;quot;Assertions.cpp&amp;quot;&amp;lt;/code&amp;gt; command to find the full path to the file relative to the base.&lt;br /&gt;
&lt;br /&gt;
{{Cat|example.patch|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Author: John Doe &amp;lt;johndoe@mail.com&amp;gt;&lt;br /&gt;
URL: http://.....&lt;br /&gt;
Summary: Fixes musl compatibility&lt;br /&gt;
----&lt;br /&gt;
--- a/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp.orig&lt;br /&gt;
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp&lt;br /&gt;
@@ -142,7 +142,7 @@&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 FrameToNameScope::FrameToNameScope(void* addr) : m_name(0), m_cxaDemangled(0) {&lt;br /&gt;
-#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; !defined(__UCLIBC__))&lt;br /&gt;
+#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; defined(__GLIBC__))&lt;br /&gt;
   Dl_info info;&lt;br /&gt;
   if (!dladdr(addr, &amp;amp;info) || !info.dli_sname)&lt;br /&gt;
return;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Portions of the patch may be outdated, removed completely as in the source code file completely removed, or moved or renamed files.  You need to delete that section of the patch or find where that section of code changed and re-diff it.&lt;br /&gt;
&lt;br /&gt;
It is good etiquette to give credit at the top and the location of where you originally found them with notes.&lt;br /&gt;
&lt;br /&gt;
Excluding patches with global variable resembling patch_opts is not available on Alpine.  To exclude patches you need to create your own custom prepare().&lt;br /&gt;
&lt;br /&gt;
If you have a monolithic patch where there are a bunch of patches in one big patch, you could use filterdiff which is available in the patchutils package.&lt;br /&gt;
&lt;br /&gt;
Just do something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
makedepends=&amp;quot;patchutils&amp;quot;&lt;br /&gt;
&lt;br /&gt;
prepare() {&lt;br /&gt;
  ...&lt;br /&gt;
  cd &amp;quot;$builddir&amp;quot;&lt;br /&gt;
  filterdiff -x &#039;*drivers/video/logo*&#039; &amp;quot;$srcdir&amp;quot;/original.patch &amp;gt; &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
  patch -p1 -i &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to put the wildcard pattern in single quotes for it to work.&lt;br /&gt;
&lt;br /&gt;
==== Configure options  ====&lt;br /&gt;
&lt;br /&gt;
Alpine has some default configure options we set by default. We use /usr for prefix to make sure everything is installed with /usr in front of it. If you notice that anything is installed in the wrong directory please run {{Cmd|./configure --help}} and see if you can set the correct location. &lt;br /&gt;
&lt;br /&gt;
We are not covering the depend switches here we have discussed this already in the depend section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Make options  ====&lt;br /&gt;
&lt;br /&gt;
If you notice weird problems when compiling or installing the package with make/make install you could try to disable [https://www.gnu.org/software/make/manual/make.html#Parallel parallel] building/installing. A normal make line would be: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make}}&lt;br /&gt;
&lt;br /&gt;
To disable parallel we use: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make -j1}}&lt;br /&gt;
&lt;br /&gt;
We can use the same for make install. &lt;br /&gt;
&lt;br /&gt;
Because we do not want to install the package in our build environment but we want to install it in a fake root directory we need to tell &#039;make install&#039; to use another destination directory instead of &#039;/&#039;. We do this by setting a variable when we execute make install as followed: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make DESTDIR{{=}}&amp;quot;$pkgdir&amp;quot; install}}&lt;br /&gt;
&lt;br /&gt;
Please note that some Makefiles do not support this variable and will always install software in &#039;/&#039;. To make sure you do not mess up your build system NEVER run your build system as root but always use a custom user and doas when needed. If by accident the Makefile does not support DESTDIR variable it will fail to install in our build system system directories.&lt;br /&gt;
&lt;br /&gt;
==== builddir ====&lt;br /&gt;
If you used &amp;lt;tt&amp;gt;newapkbuild&amp;lt;/tt&amp;gt; to create your APKBUILD file, you must specify the path to your unpacked sources. Inside the sections during the prepare/build/install process &#039;&#039;builddir&#039;&#039; is used. Most of the time a combination of &#039;&#039;$srcdir&#039;&#039; and &#039;&#039;$pkgname-$pkgver&#039;&#039; will work. When not, check the /src directory or the source tarball for the right string. Especially when you are working with automatically generated tarballs (like from github and gitorious), this needs to be adjusted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
builddir=&amp;quot;$srcdir&amp;quot;/$pkgname-$pkgver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Additional files  ====&lt;br /&gt;
&lt;br /&gt;
If you want/need to install additional files not mentioned above you can use the following cmd (this is an example of a conf file): &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 doc/$pkgname.conf &amp;quot;$pkgdir&amp;quot;/etc/$pkgname.conf}}&lt;br /&gt;
&lt;br /&gt;
== Build the package  ==&lt;br /&gt;
&lt;br /&gt;
If you did not already create the checksums as mentioned above you can do so now: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $pkgname&lt;br /&gt;
abuild checksum}}&lt;br /&gt;
&lt;br /&gt;
It&#039;s about time we build our package. Because a build system should never have all the package installed to prevent linking to packages we don&#039;t want it to link we use a abuild recursively with the &#039;&#039;&#039;-r&#039;&#039;&#039; switch. It will install all dependencies from your repository and builds it, afterwards it will uninstall all those depending packages again.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -r}}&lt;br /&gt;
&lt;br /&gt;
See also [[Abuild_and_Helpers|Abuild and Helpers]].&lt;br /&gt;
&lt;br /&gt;
== Testing the package locally ==&lt;br /&gt;
&lt;br /&gt;
When it completes, your package will be found in a subfolder of &amp;lt;code&amp;gt;~/packages&amp;lt;/code&amp;gt;.  You may want to test it on your machine but only if the package is not a critical system package like musl or apk-tools package.  To avoid borking your system (as in making it impossible to use &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; or to restore back the system and the compiler toolchain) for a critical system package, you should test on a chroot first before using it live.&lt;br /&gt;
&lt;br /&gt;
The best way to test a package locally is to modify your &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; so that it includes the indexes to your locally built packages - the directories that contain &amp;lt;code&amp;gt;ARCH/APKINDEX.tar.gz&amp;lt;/code&amp;gt;. For example the &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; below includes locally built packages in testing, community and main. To use this example change &amp;lt;code&amp;gt;USER&amp;lt;/code&amp;gt; to your login name.&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/apk/repositories|/home/USER/packages/testing/&lt;br /&gt;
/home/USER/packages/main/&lt;br /&gt;
/home/USER/packages/community/&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you prefer to test a package without changing any other configuration you can use the &amp;lt;code&amp;gt;-X, --repository&amp;lt;/code&amp;gt; option to &amp;lt;code&amp;gt;apk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|doas apk add --repository /home/USER/packages/testing $pkgname}}&lt;br /&gt;
&lt;br /&gt;
== Code review ==&lt;br /&gt;
&lt;br /&gt;
To successfully have your package pass through code reviewers (as of Feb 18, 2018 are nmeum and jirutka on GitHub) and possible increased acceptance, the following conventions need to be followed:&lt;br /&gt;
&lt;br /&gt;
# Custom global variables should be prefixed with underscore (_).&lt;br /&gt;
# Compact code as in merged commands, removed unused variables, removal of functions that do the same thing that are automatically handled by abuild.&lt;br /&gt;
# Versioning is done properly.  For details see [[APKBUILD_Reference#pkgver]].&lt;br /&gt;
# Licensing is done properly. Remove unnecessary copying of licensing that is already OSI approved.&lt;br /&gt;
# Naming conventions rules for unofficial variables as in _gitrev is preferred over commit.&lt;br /&gt;
# Indent with tabs not spaces.&lt;br /&gt;
# Removal of explicit return 1.  (They are still found the old APKBUILD files if you are learning but are now strongly discouraged.)&lt;br /&gt;
# Disabling check() requires either (1) a comment (#) stating next to options=&amp;quot;!check&amp;quot; that there is no test suite/unit tests or (2) functioning working check() function.&lt;br /&gt;
# Explicit call to subpackages=&amp;quot;$pkgname-doc&amp;quot; must be used instead of explicit gzip man page compression.&lt;br /&gt;
# Ideally, lines should be no more than 80 columns wide&lt;br /&gt;
&lt;br /&gt;
Additionally, make sure to run the linter on your package:&lt;br /&gt;
{{Cmd|doas apk add atools&lt;br /&gt;
apkbuild-lint APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
For more information see [[Development using git:Quality assurance]] and [[Package_policies]].&lt;br /&gt;
Also check out [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/COMMITSTYLE.md?ref_type=heads aports/COMMITSTYLE.md] and [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/CODINGSTYLE.md?ref_type=heads aports/CODINGSTYLE.md]&lt;br /&gt;
&lt;br /&gt;
== Commit your work  ==&lt;br /&gt;
&lt;br /&gt;
After you successfully build your package and properly followed the conventions and requirements in the code review section, you can submit your APKBUILD to Alpine&#039;s git repository. &lt;br /&gt;
&lt;br /&gt;
Update your git repo, before adding new files: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git pull}}&lt;br /&gt;
&lt;br /&gt;
This should pull all the changes made by others into your local git repo.&lt;br /&gt;
&lt;br /&gt;
When you think you are ready you can add your files to git: &lt;br /&gt;
&lt;br /&gt;
NOTE: when using our Gitlab instance, you can create MR&#039;s for each package. Please squash all commits related to the same package into a single one per MR.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git add testing/$pkgdir (include any other files needed for the build; $pkgname.install...)&lt;br /&gt;
git commit}}&lt;br /&gt;
&lt;br /&gt;
Use the following commit message template for new aports (without the comments):&lt;br /&gt;
&lt;br /&gt;
{{Cat|template|testing/$pkgname: new aport   # this will be the subject line&lt;br /&gt;
                              # a blank line&lt;br /&gt;
$url                          # project homepage&lt;br /&gt;
$pkgdesc                      # one line description}}&lt;br /&gt;
&lt;br /&gt;
Or you could add the following and &amp;lt;code&amp;gt;chmod +x ports/.git/hooks/prepare-commit-msg&amp;lt;/code&amp;gt; to automatically generate commit message which the default aports/.githooks/ does not:&lt;br /&gt;
&lt;br /&gt;
{{Cat|aports/.git/hooks/prepare-commit-msg|&amp;lt;nowiki&amp;gt;#!/bin/sh&lt;br /&gt;
case &amp;quot;$2,$3&amp;quot; in&lt;br /&gt;
  ,|template,)&lt;br /&gt;
    if git diff-index --diff-filter=A --name-only --cached HEAD \&lt;br /&gt;
        | grep -q &#039;/APKBUILD$&#039;; then&lt;br /&gt;
      meta() { git diff --staged | grep &amp;quot;^+$1&amp;quot; | sed &#039;s/.*=&amp;quot;\?//;s/&amp;quot;$//&#039;;}&lt;br /&gt;
      printf &#039;testing/%s: new aport\n\n%s\n%s\n&#039; &amp;quot;$(meta pkgname)&amp;quot; \&lt;br /&gt;
        &amp;quot;$(meta url)&amp;quot; &amp;quot;$(meta pkgdesc)&amp;quot; &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      printf &#039;%s\n\n%s&#039; `git diff-index --name-only --cached HEAD \&lt;br /&gt;
        | sed -n &#039;s/\/APKBUILD$//p;q&#039;` &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    fi;;&lt;br /&gt;
esac&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Now your changes are only available locally in your repository.&lt;br /&gt;
&lt;br /&gt;
Because you do not have push rights to the Alpine aports repository you need to create a merge request to [https://gitlab.alpinelinux.org/alpine/aports Alpine&#039;s GitLab instance].&lt;br /&gt;
&lt;br /&gt;
Alternatively you can also create a diff (patch) of the changes you made and send this patch to the &lt;br /&gt;
[https://lists.alpinelinux.org/~alpine/aports  alpine-aports mailinglist].&lt;br /&gt;
&lt;br /&gt;
To create a diff patch:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^}}&lt;br /&gt;
&lt;br /&gt;
or if you have sprunge, you can create a link to your patch for convenience&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^ --stdout &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; sprunge}}&lt;br /&gt;
&lt;br /&gt;
== Automated flagging of outdated ports ==&lt;br /&gt;
Consider adding your port to [https://release-monitoring.org/ Anitya], so it will be flagged as outdated&lt;br /&gt;
as soon as a new stable version is released by upstream.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[APKBUILD Reference]]&lt;br /&gt;
* [[APKBUILD examples]]&lt;br /&gt;
* [[Development using git]]&lt;br /&gt;
* [[Development using git:Quality assurance]]&lt;br /&gt;
&lt;br /&gt;
[[category: Package Manager]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26377</id>
		<title>Creating an Alpine package</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26377"/>
		<updated>2024-02-11T23:43:32Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This is a brief list of the steps to add a new package. Details are below, but a NB can miss a few steps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create an account on github.alpine&lt;br /&gt;
&amp;lt;li&amp;gt;Fork the aports repository. &lt;br /&gt;
&amp;lt;li&amp;gt;Clone your new fork.&lt;br /&gt;
&amp;lt;li&amp;gt;Set git pull.rebase=true, set your username and email.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a new branch (don&#039;t use master).&lt;br /&gt;
&amp;lt;li&amp;gt;Add a new directory under testing that is your new package name.&lt;br /&gt;
&amp;lt;li&amp;gt;Add your APKBUILD file.&lt;br /&gt;
&amp;lt;li&amp;gt;Run abuild checksum&lt;br /&gt;
&amp;lt;li&amp;gt;Make sure you run the apkbuild-lint and aport -r and there are no warnings.&lt;br /&gt;
&amp;lt;li&amp;gt;Commit your APKBUILD with the commit message: &#039;testing/packagename: new aport&#039;&lt;br /&gt;
&amp;lt;li&amp;gt;Push your changes to your fork on github.alpine.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a merge request.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the rest of this wiki for details on the steps above.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
To build a package for Alpine Linux you need an Alpine Linux installation. Check the [[Installation]] page to see all available installation options.&lt;br /&gt;
&lt;br /&gt;
== Setup your system and account  ==&lt;br /&gt;
{{:Setup_your_system_and_account_for_building_packages}}&lt;br /&gt;
&lt;br /&gt;
== Getting some help ==&lt;br /&gt;
&lt;br /&gt;
It might be wise to start by checking what the [[Abuild and Helpers|abuild]] program can/cannot do.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -h}}&lt;br /&gt;
&lt;br /&gt;
For real help, you can also go on #alpine-devel on [[IRC]].&lt;br /&gt;
&lt;br /&gt;
A reference for APKBUILD files is available as [[APKBUILD Reference]] wiki page or a man page in the &#039;abuild-doc&#039; package:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|man APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Creating an APKBUILD file  ==&lt;br /&gt;
&lt;br /&gt;
=== Use a template APKBUILD ===&lt;br /&gt;
&lt;br /&gt;
To create the actual APKBUILD file {{Pkg|newapkbuild}} can serve you a template to start with. It will create a directory with the given package name, place an example/template APKBUILD file to the given directory, and fill some variables if those are provided. Please check the [[Package_policies| package policies]] page about naming details.&lt;br /&gt;
&lt;br /&gt;
If you doubt to which repository your package belongs to you can safely use &#039;&#039;&#039;testing&#039;&#039;&#039;. Building package in your aports/testing directory is not mandatory but this way the package is already at the right place.&lt;br /&gt;
&lt;br /&gt;
{{:Abuild and Helpers}}&lt;br /&gt;
&lt;br /&gt;
{{Note|On older Alpine systems, abuild -c -n &#039;&#039;packagename&#039;&#039; was the way to create APKBUILD files. The &#039;packagename&#039; was a parameter to the -n option so order of -c and -n matters. }}&lt;br /&gt;
&lt;br /&gt;
[[Abuild_and_Helpers#apkbuild-cpan|apkbuild-cpan]] simplifies the creation of perl packages from CPAN and [[Abuild_and_Helpers#apkbuild-pypi|apkbuild-pypi]] ease the generation of APKBUILD files for python packages from PyPi.  &lt;br /&gt;
&lt;br /&gt;
If you are creating a daemon package which needs initd scripts you can add the -c making it: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|newapkbuild -c &#039;&#039;packagename&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This will copy the sample initd and confd files to the build directory.&amp;lt;BR&amp;gt;&lt;br /&gt;
A third file sample.install file will be copied as well (we will discuss this later on).&lt;br /&gt;
&lt;br /&gt;
=== Modify your APKBUILD ===&lt;br /&gt;
Edit APKBUILD and fill in the needed info (especially pkgname, pkgver, pkgdesc, url, license, depends and source). &lt;br /&gt;
&lt;br /&gt;
If you are going to use any of the variables for directories like $pkgdir, always make sure they are double quoted like: &lt;br /&gt;
&lt;br /&gt;
 &amp;quot;$pkgdir&amp;quot;/somedir&lt;br /&gt;
&lt;br /&gt;
This will prevent issues with spaces/special characters in the future. &lt;br /&gt;
&lt;br /&gt;
{{Note|If you like syntax highlighting we suggest you to install vim. We have setup vim to recognize the APKBUILD file as a bash scripts so its easier to read them.}}&lt;br /&gt;
&lt;br /&gt;
=== APKBUILD variables/functions  ===&lt;br /&gt;
&lt;br /&gt;
==== source  ====&lt;br /&gt;
&lt;br /&gt;
The source variable is not only used to list the remote source files to fetch, it is also used to list the local files that abuild will need in order to build the apk. Examples of such local files include: init.d files, conf.d files, install files (see [[Creating an Alpine package#install|install variable]]), patches, and all other necessary files.&lt;br /&gt;
&lt;br /&gt;
Here are few things to note:&lt;br /&gt;
&lt;br /&gt;
* When you are finished adding local and/or remote files to &#039;&#039;source&#039;&#039;, you can execute the following command to add their checksums to the APKBUILD file:&lt;br /&gt;
: {{cmd|abuild checksum}}&lt;br /&gt;
: {{Note|When later updating the content of &#039;&#039;source&#039;&#039;, or updating a file that is listed in &#039;&#039;source&#039;&#039;, you must also update their checksums again with the same command.}}&lt;br /&gt;
&lt;br /&gt;
* When the remote file is hosted at SourceForge, it&#039;s best to specify the special mirrors link used by SourceForge:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
: (or similar depending on the package).&lt;br /&gt;
&lt;br /&gt;
* When the remote filename is not specified in the URI (ie, does not end in &#039;/software-1.0.tar.gz&#039;), such as:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
: You must prepend &#039;${pkgname}-${pkgver}.tar.gz::&#039; to the protocol, like so:&lt;br /&gt;
: &amp;lt;pre&amp;gt;source=&amp;quot;${pkgname}-${pkgver}.tar.gz::http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
: This causes the file to be saved as &#039;&#039;software-1.0.tar.gz&#039;&#039; where abuild can use it, instead of &#039;&#039;?get=software&amp;amp;ver=1.0&#039;&#039;, where abuild cannot use it.&lt;br /&gt;
&lt;br /&gt;
* Some projects didn&#039;t provide a release tarball. Beware that some git services (gitweg, cgit, …?) doesn’t provide &#039;&#039;stable&#039;&#039; tarballs, so when you point source to an tarball like &amp;lt;tt&amp;gt;https://repo.or.cz/w/gitstats.git/snapshot/ad7efbb9399e60cee6cb217c6b47e604174a8093.tar.gz&amp;lt;/tt&amp;gt;, then you will run into issues because the checksum changes when downloading on the build system. This is not a problem on GitHub, GitLab and other decent services provides, they provide &#039;&#039;stable&#039;&#039; tarballs.&lt;br /&gt;
&lt;br /&gt;
* abuild currently supports the following protocols for remote file retrieval:&lt;br /&gt;
** http&lt;br /&gt;
** https&lt;br /&gt;
** ftp&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--: {{Note|If the you want to download from https, you need GNU wget installed on your system.}}--&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
* abuild currently supports the following archive types/archive file extensions:&lt;br /&gt;
** .tar&lt;br /&gt;
** .tar.gz / .tgz&lt;br /&gt;
** .tar.bz2&lt;br /&gt;
** .tar.lz (only in Alpine &amp;gt;=3.7)&lt;br /&gt;
** .tar.lzma&lt;br /&gt;
** .tar.xz&lt;br /&gt;
** .zip&lt;br /&gt;
&lt;br /&gt;
==== depends &amp;amp;amp; makedepends  ====&lt;br /&gt;
&lt;br /&gt;
Depends are the actual running dependencies that a package would need when it is running. Makedepends are only needed when you are building a package. If you set a package in depends, you do not need to add it to makedepends as well. The best way to find out what the depends and makedepends of a package are is to [https://en.wikipedia.org/wiki/Rtfm RTFM]. &lt;br /&gt;
&lt;br /&gt;
No kidding, lots of important information can be found in the package INSTALL and README files (or the likes). Another good way is the run &amp;lt;code&amp;gt;./configure --help&amp;lt;/code&amp;gt; from the source directory to see which options are needed for configure to finish without errors. If you do not yet have a source directory you can create one with the command: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild unpack}}&lt;br /&gt;
&lt;br /&gt;
Running &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt; will also show you how you can disable a specific option for this package. For instance, a good example is &amp;quot;--disable-nls&amp;quot; which will disable native language support and thus does not depend on gettext (libiconv, glib, ...). &lt;br /&gt;
&lt;br /&gt;
Alpine likes to keep things small, so we try to disable as much as possible without losing too many features. The exact disable/enable options are decided by the package builder but please try to follow Alpine&#039;s design concept as much as possible.&lt;br /&gt;
&lt;br /&gt;
An easy way of quickly finding out the build info for a package is to check Arch Linux (Alpine package management and build scripts are similar) or Gentoo Linux ebuilds (previous versions of Alpine were based on Gentoo).&lt;br /&gt;
&lt;br /&gt;
* [https://gitweb.gentoo.org/repo/gentoo.git/tree/ Gentoo Ebuilds] &lt;br /&gt;
* [https://archlinux.org/packages/?q=search Arch Linux packages] [https://aur.archlinux.org/ Arch Linux User Repository]&lt;br /&gt;
&lt;br /&gt;
==== license  ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;license&#039;&#039;&#039; tag must reflect the license of the source code. Please check the source tarball for COPYING, LICENSE, or other files with names that indicates that it contains licensing information. Beside the license file most developer include headers in the source code files with licensing details.&lt;br /&gt;
&lt;br /&gt;
If the license is on the [https://spdx.org/licenses/ SPDX License List] or [https://spdx.org/licenses/exceptions-index.html SPDX License Exceptions], use the identifier specified by SPDX.&lt;br /&gt;
&lt;br /&gt;
Note that some licenses have additional requirements that should be adhered to. The &amp;lt;code&amp;gt;MIT&amp;lt;/code&amp;gt; license for example has the requirement:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that we need to include the license as shipped with the project.&lt;br /&gt;
&lt;br /&gt;
If a package has a special/custom license or is not listed as [https://opensource.org/licenses/alphabetical OSI approved], use the identifier &amp;quot;custom&amp;quot;. In that case we need to provide the license file with the package as well.&lt;br /&gt;
&lt;br /&gt;
Because we want to save space and don&#039;t like to have licenses all over our system we have decided to include the license in the doc subpackage. Please follow the following guidelines to add a proper license. Locate the license file inside the source package. Add the doc subpackage to the $subpackages variable as follows: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a similar line to the following to your package() function, depending on the license description file: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 COPYING &amp;quot;$pkgdir&amp;quot;/usr/share/licenses/$pkgname/COPYING}}&lt;br /&gt;
&lt;br /&gt;
If you follow these steps then abuild will automatically add the license to the package-doc apk for you.&lt;br /&gt;
&lt;br /&gt;
{{Warning|It is not acceptable to package software with &amp;quot;unknown&amp;quot; license! If you can&#039;t find the license of the source code, please contact the author and ask them to specify the license. }}&lt;br /&gt;
&lt;br /&gt;
==== arch ====&lt;br /&gt;
&lt;br /&gt;
The package architecture(s) to build for.  This can be one of: &#039;&#039;x86, x86_64, all,&#039;&#039; or &#039;&#039;noarch&#039;&#039;, where &#039;&#039;all&#039;&#039; means all architectures, and &#039;&#039;noarch&#039;&#039; means it&#039;s architecture-independent (e.g., a pure-python package).&lt;br /&gt;
{{Tip|To determine if your APKBUILD can use &#039;&#039;noarch&#039;&#039;, build the package for your architecture and then run &amp;quot;scanelf -R pkg&amp;quot; from the directory that the APKBUILD resides in, in order to scan for ELF files in the &#039;&#039;./pkg&#039;&#039; directory.  If you do NOT get output from this, then &#039;&#039;noarch&#039;&#039; can be used.}}&lt;br /&gt;
&lt;br /&gt;
==== url  ====&lt;br /&gt;
&lt;br /&gt;
Website address for the program. This is useful later on when either finding documentation or other information about the package.&lt;br /&gt;
&lt;br /&gt;
==== pkgdesc  ====&lt;br /&gt;
&lt;br /&gt;
A brief, one line, description of what the package does. Useful for the package management system. It should start with a capital letter and does &#039;&#039;&#039;not&#039;&#039;&#039; end with a period.&lt;br /&gt;
&lt;br /&gt;
Here is an example from apk_info for the OpenSSH client package:&lt;br /&gt;
&lt;br /&gt;
 pkgdesc=&amp;quot;Port of OpenBSD&#039;s free SSH release - client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== pkgver  ====&lt;br /&gt;
&lt;br /&gt;
Provide the release number of the package you are building.&lt;br /&gt;
&lt;br /&gt;
==== pkgrel  ====&lt;br /&gt;
&lt;br /&gt;
The $pkgrel versioning is made so that if you change something in your APKBUILD file without changing the actual $pkgver, you can increment pkgrel so apk tools will detect it as an update. For instance, if you forget to add a dependency, you can add it afterward and you can +1 pkgver so apk finds this update and adds the missing dependency. When there&#039;s an upstream version change, we reset the pkgrel to 0.&lt;br /&gt;
&lt;br /&gt;
==== pkgname  ====&lt;br /&gt;
&lt;br /&gt;
The base name of the package you are creating.  For Freeswitch 1.0.6, you would use &amp;quot;freeswitch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== install  ====&lt;br /&gt;
&lt;br /&gt;
There are 6 different kinds of install scripts. Each script is called with the $pkgname.&#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; where &#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; is one of the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before package is installed. Typical use is when package needs a group and a user to be created. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
addgroup -S clamav 2&amp;gt;/dev/null&lt;br /&gt;
adduser -S -D -H -s /bin/false -G clamav -g clamav clamav 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the &#039;&#039;exit 0&#039;&#039; at the end. If the script exits with failure (if the user already exist), the package will not be installed and &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; will exit with failure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after the package is installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as pre-install but is executed before upgrading/downgrading/reinstalling an already installed package. Note that exiting with failure will not cause apk to exit with failure, but will mark the package as broken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as post-install but is executed after upgrading/downgrading/reinstalling an already installed package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before uninstalling a package. If script exits with failure apk will not uninstall the package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after a package have been uninstalled. For example, can be used to restore busybox links:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
busybox --install -s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the package has a pre-install and post-install script the APKBUILD should have the &#039;&#039;install&#039;&#039; variable defined:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
install=&amp;quot;$pkgname.pre-install $pkgname.post-install&amp;quot;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== subpackages  ====&lt;br /&gt;
&lt;br /&gt;
$subpackages are made to split up the normal &amp;quot;make install&amp;quot; into separate packages. The most common subpackages we use are doc and dev. Because we like to keep our target system small we move documentation and development files (only needed when building packages) into separate packages. To use the specific program a user only need to install the base apk without package-doc or package-dev, but if he wants to read the manual he will need to install package-doc. &lt;br /&gt;
&lt;br /&gt;
The easiest way to find out if you need to use -dev and -doc is to first build the package without these options set and wait until the build finishes. When its finished you should have a pkg directory which is the fake root directory. Inside this directory you will see the structure as how it would be installed in / on the target system. &lt;br /&gt;
&lt;br /&gt;
To see if you need the -dev package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/ -name &#039;*.[acho]&#039; -o -name &#039;*.la&#039;}}&lt;br /&gt;
&lt;br /&gt;
If this returns any files you need to include the -dev package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; To see if you need the -doc package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/share -name doc -o -name man -o -name info -o -name html -o -name sgml -o -name licenses}}&lt;br /&gt;
&lt;br /&gt;
If this returns any directories you need to include the -doc package. &lt;br /&gt;
&lt;br /&gt;
===== Custom subpackages  =====&lt;br /&gt;
&lt;br /&gt;
Some software additionally has non-essential files that do not qualify as either documentation or development content. These files should be placed in their own, specialized subpackage(s). Some packages include large test suites which are only needed in specific circumstances or binaries which have depends which we prefer not to install. To handle those we create our own package/function. In the APKBUILD below the build() function we create another function: &lt;br /&gt;
&lt;br /&gt;
 test() {&lt;br /&gt;
        mkdir -p &amp;quot;$subpkgdir&amp;quot;/usr&lt;br /&gt;
        mv &amp;quot;$pkgdir&amp;quot;/usr/package-test &amp;quot;$subpkgdir&amp;quot;/usr/&lt;br /&gt;
        # or amove usr/package-test&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We also need to add the package info to $subpackages variable: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc $pkgname-dev $pkgname-test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
After we finish building the package you should see another apk called packagename-test.apk which includes the files which we moved to the $subpkgdir dir. &lt;br /&gt;
&lt;br /&gt;
The above mentioned variables can also be used in our custom function. If we want for instance to build the test() function with perl support we would add: &lt;br /&gt;
&lt;br /&gt;
 depends=&amp;quot;perl&amp;quot;&lt;br /&gt;
 makedepends=&amp;quot;perl-dev&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we would install the base package it would not install perl, but if we install the package-test package it would.&lt;br /&gt;
&lt;br /&gt;
==== Patches  ====&lt;br /&gt;
&lt;br /&gt;
Please make sure you always submit human readable patches. Ways to create them are: &lt;br /&gt;
&lt;br /&gt;
directory compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -Nurp original_directory new_directory &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
file compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -up original.file new.file &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
If a patch contains a completely new file but not *.rej or *.orig file, you need to add -N option to diff, but you may need to add exclusions with &amp;lt;code&amp;gt;--exclude PATTERN&amp;lt;/code&amp;gt; so that you do not inadvertently add files.  You may need to manually delete unwanted files inside the patch file.&lt;br /&gt;
&lt;br /&gt;
Because multiple patches can patch the same file, they can change the offsets required by subsequent patches. To make sure we always patch in a specific way, we should number the patches as follows: &lt;br /&gt;
&lt;br /&gt;
 10-patch1.patch 20-patch2.patch 30-patch3.patch&lt;br /&gt;
&lt;br /&gt;
This way we are always sure that patch 1 is applied first, and if we want to add additional patches between them we can use appropriate indexes (e.g. 11, 12, 21, 22).&lt;br /&gt;
&lt;br /&gt;
Add the names of the patch files to the &#039;&#039;source&#039;&#039; variable. If you haven&#039;t declared a custom &#039;&#039;prepare&#039;&#039; function, no further action is necessary. Otherwise, be sure to call &#039;&#039;default_prepare&#039;&#039; in your &#039;&#039;prepare&#039;&#039; function. For example:&lt;br /&gt;
&lt;br /&gt;
 prepare() {&lt;br /&gt;
 	default_prepare&lt;br /&gt;
 &lt;br /&gt;
 	# do your stuff&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Note: Some older packages contain a &#039;&#039;for&#039;&#039; loop in the &#039;&#039;prepare&#039;&#039; function to apply patches. This is not needed anymore, as patches are handled by &#039;&#039;default_prepare&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In Alpine &amp;gt;=3.4 you can define patch_args to supply the patch level.  This only works if all the patches have the same patch level.  If there are a lot of patches from different sources, there is a good chance that you may need to edit them, as discussed below.&lt;br /&gt;
&lt;br /&gt;
To automatically patch the package (available only in Alpine &amp;gt;=3.4) if it uses a patch level (-pX) other than the default (-p1), you need to carefully modify the patch.  First, you&#039;ll need a text editor that does not automatically convert  between Windows and Unix new lines (or, disable this feature) so that it preserves the old code.  The next thing you&#039;ll need to do is modify the paths on &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines in the .patch file.  You can begin the path with a/ and b/ like shown below.  Next, you need to adjust the paths so that the relative base path is from inside $builddir.  Anything to the left of $builddir, including $builddir itself, needs to be removed from the path.  So, if $builddir is /home/USER/aports/community/chromium/src/chromium-65, you need to erase it on the &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines.  Inside the chromium-65 folder you can see a src folder that has 3rdparty as a descendant.  If a patch originally has a deeper patch level, you may need to fill in the missing portion of the path.  For example, use the &amp;lt;code&amp;gt;find . -name &amp;quot;Assertions.cpp&amp;quot;&amp;lt;/code&amp;gt; command to find the full path to the file relative to the base.&lt;br /&gt;
&lt;br /&gt;
{{Cat|example.patch|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Author: John Doe &amp;lt;johndoe@mail.com&amp;gt;&lt;br /&gt;
URL: http://.....&lt;br /&gt;
Summary: Fixes musl compatibility&lt;br /&gt;
----&lt;br /&gt;
--- a/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp.orig&lt;br /&gt;
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp&lt;br /&gt;
@@ -142,7 +142,7 @@&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 FrameToNameScope::FrameToNameScope(void* addr) : m_name(0), m_cxaDemangled(0) {&lt;br /&gt;
-#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; !defined(__UCLIBC__))&lt;br /&gt;
+#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; defined(__GLIBC__))&lt;br /&gt;
   Dl_info info;&lt;br /&gt;
   if (!dladdr(addr, &amp;amp;info) || !info.dli_sname)&lt;br /&gt;
return;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Portions of the patch may be outdated, removed completely as in the source code file completely removed, or moved or renamed files.  You need to delete that section of the patch or find where that section of code changed and re-diff it.&lt;br /&gt;
&lt;br /&gt;
It is good etiquette to give credit at the top and the location of where you originally found them with notes.&lt;br /&gt;
&lt;br /&gt;
Excluding patches with global variable resembling patch_opts is not available on Alpine.  To exclude patches you need to create your own custom prepare().&lt;br /&gt;
&lt;br /&gt;
If you have a monolithic patch where there are a bunch of patches in one big patch, you could use filterdiff which is available in the patchutils package.&lt;br /&gt;
&lt;br /&gt;
Just do something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
makedepends=&amp;quot;patchutils&amp;quot;&lt;br /&gt;
&lt;br /&gt;
prepare() {&lt;br /&gt;
  ...&lt;br /&gt;
  cd &amp;quot;$builddir&amp;quot;&lt;br /&gt;
  filterdiff -x &#039;*drivers/video/logo*&#039; &amp;quot;$srcdir&amp;quot;/original.patch &amp;gt; &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
  patch -p1 -i &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to put the wildcard pattern in single quotes for it to work.&lt;br /&gt;
&lt;br /&gt;
==== Configure options  ====&lt;br /&gt;
&lt;br /&gt;
Alpine has some default configure options we set by default. We use /usr for prefix to make sure everything is installed with /usr in front of it. If you notice that anything is installed in the wrong directory please run {{Cmd|./configure --help}} and see if you can set the correct location. &lt;br /&gt;
&lt;br /&gt;
We are not covering the depend switches here we have discussed this already in the depend section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Make options  ====&lt;br /&gt;
&lt;br /&gt;
If you notice weird problems when compiling or installing the package with make/make install you could try to disable [https://www.gnu.org/software/make/manual/make.html#Parallel parallel] building/installing. A normal make line would be: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make}}&lt;br /&gt;
&lt;br /&gt;
To disable parallel we use: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make -j1}}&lt;br /&gt;
&lt;br /&gt;
We can use the same for make install. &lt;br /&gt;
&lt;br /&gt;
Because we do not want to install the package in our build environment but we want to install it in a fake root directory we need to tell &#039;make install&#039; to use another destination directory instead of &#039;/&#039;. We do this by setting a variable when we execute make install as followed: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make DESTDIR{{=}}&amp;quot;$pkgdir&amp;quot; install}}&lt;br /&gt;
&lt;br /&gt;
Please note that some Makefiles do not support this variable and will always install software in &#039;/&#039;. To make sure you do not mess up your build system NEVER run your build system as root but always use a custom user and doas when needed. If by accident the Makefile does not support DESTDIR variable it will fail to install in our build system system directories.&lt;br /&gt;
&lt;br /&gt;
==== builddir ====&lt;br /&gt;
If you used &amp;lt;tt&amp;gt;newapkbuild&amp;lt;/tt&amp;gt; to create your APKBUILD file, you must specify the path to your unpacked sources. Inside the sections during the prepare/build/install process &#039;&#039;builddir&#039;&#039; is used. Most of the time a combination of &#039;&#039;$srcdir&#039;&#039; and &#039;&#039;$pkgname-$pkgver&#039;&#039; will work. When not, check the /src directory or the source tarball for the right string. Especially when you are working with automatically generated tarballs (like from github and gitorious), this needs to be adjusted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
builddir=&amp;quot;$srcdir&amp;quot;/$pkgname-$pkgver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Additional files  ====&lt;br /&gt;
&lt;br /&gt;
If you want/need to install additional files not mentioned above you can use the following cmd (this is an example of a conf file): &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 doc/$pkgname.conf &amp;quot;$pkgdir&amp;quot;/etc/$pkgname.conf}}&lt;br /&gt;
&lt;br /&gt;
== Build the package  ==&lt;br /&gt;
&lt;br /&gt;
If you did not already create the checksums as mentioned above you can do so now: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $pkgname&lt;br /&gt;
abuild checksum}}&lt;br /&gt;
&lt;br /&gt;
It&#039;s about time we build our package. Because a build system should never have all the package installed to prevent linking to packages we don&#039;t want it to link we use a abuild recursively with the &#039;&#039;&#039;-r&#039;&#039;&#039; switch. It will install all dependencies from your repository and builds it, afterwards it will uninstall all those depending packages again.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -r}}&lt;br /&gt;
&lt;br /&gt;
See also [[Abuild_and_Helpers|Abuild and Helpers]].&lt;br /&gt;
&lt;br /&gt;
== Testing the package locally ==&lt;br /&gt;
&lt;br /&gt;
When it completes, your package will be found in a subfolder of &amp;lt;code&amp;gt;~/packages&amp;lt;/code&amp;gt;.  You may want to test it on your machine but only if the package is not a critical system package like musl or apk-tools package.  To avoid borking your system (as in making it impossible to use &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; or to restore back the system and the compiler toolchain) for a critical system package, you should test on a chroot first before using it live.&lt;br /&gt;
&lt;br /&gt;
The best way to test a package locally is to modify your &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; so that it includes the indexes to your locally built packages - the directories that contain &amp;lt;code&amp;gt;ARCH/APKINDEX.tar.gz&amp;lt;/code&amp;gt;. For example the &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; below includes locally built packages in testing, community and main. To use this example change &amp;lt;code&amp;gt;USER&amp;lt;/code&amp;gt; to your login name.&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/apk/repositories|/home/USER/packages/testing/&lt;br /&gt;
/home/USER/packages/main/&lt;br /&gt;
/home/USER/packages/community/&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you prefer to test a package without changing any other configuration you can use the &amp;lt;code&amp;gt;-X, --repository&amp;lt;/code&amp;gt; option to &amp;lt;code&amp;gt;apk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|doas apk add --repository /home/USER/packages/testing $pkgname}}&lt;br /&gt;
&lt;br /&gt;
== Code review ==&lt;br /&gt;
&lt;br /&gt;
To successfully have your package pass through code reviewers (as of Feb 18, 2018 are nmeum and jirutka on GitHub) and possible increased acceptance, the following conventions need to be followed:&lt;br /&gt;
&lt;br /&gt;
# Custom global variables should be prefixed with underscore (_).&lt;br /&gt;
# Compact code as in merged commands, removed unused variables, removal of functions that do the same thing that are automatically handled by abuild.&lt;br /&gt;
# Versioning is done properly.  For details see [[APKBUILD_Reference#pkgver]].&lt;br /&gt;
# Licensing is done properly. Remove unnecessary copying of licensing that is already OSI approved.&lt;br /&gt;
# Naming conventions rules for unofficial variables as in _gitrev is preferred over commit.&lt;br /&gt;
# Indent with tabs not spaces.&lt;br /&gt;
# Removal of explicit return 1.  (They are still found the old APKBUILD files if you are learning but are now strongly discouraged.)&lt;br /&gt;
# Disabling check() requires either (1) a comment (#) stating next to options=&amp;quot;!check&amp;quot; that there is no test suite/unit tests or (2) functioning working check() function.&lt;br /&gt;
# Explicit call to subpackages=&amp;quot;$pkgname-doc&amp;quot; must be used instead of explicit gzip man page compression.&lt;br /&gt;
# Ideally, lines should be no more than 80 columns wide&lt;br /&gt;
&lt;br /&gt;
Additionally, make sure to run the linter on your package:&lt;br /&gt;
{{Cmd|doas apk add atools&lt;br /&gt;
apkbuild-lint APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
For more information see [[Development using git:Quality assurance]] and [[Package_policies]].&lt;br /&gt;
Also check out [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/COMMITSTYLE.md?ref_type=heads aports/COMMITSTYLE.md] and [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/CODINGSTYLE.md?ref_type=heads aports/CODINGSTYLE.md]&lt;br /&gt;
&lt;br /&gt;
== Commit your work  ==&lt;br /&gt;
&lt;br /&gt;
After you successfully build your package and properly followed the conventions and requirements in the code review section, you can submit your APKBUILD to Alpine&#039;s git repository. &lt;br /&gt;
&lt;br /&gt;
Update your git repo, before adding new files: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git pull}}&lt;br /&gt;
&lt;br /&gt;
This should pull all the changes made by others into your local git repo.&lt;br /&gt;
&lt;br /&gt;
When you think you are ready you can add your files to git: &lt;br /&gt;
&lt;br /&gt;
NOTE: when using our Gitlab instance, you can create MR&#039;s for each package. Please squash all commits related to the same package into a single one per MR.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git add testing/$pkgdir (include any other files needed for the build; $pkgname.install...)&lt;br /&gt;
git commit}}&lt;br /&gt;
&lt;br /&gt;
Use the following commit message template for new aports (without the comments):&lt;br /&gt;
&lt;br /&gt;
{{Cat|template|testing/$pkgname: new aport   # this will be the subject line&lt;br /&gt;
                              # a blank line&lt;br /&gt;
$url                          # project homepage&lt;br /&gt;
$pkgdesc                      # one line description}}&lt;br /&gt;
&lt;br /&gt;
Or you could add the following and &amp;lt;code&amp;gt;chmod +x ports/.git/hooks/prepare-commit-msg&amp;lt;/code&amp;gt; to automatically generate commit message which the default aports/.githooks/ does not:&lt;br /&gt;
&lt;br /&gt;
{{Cat|aports/.git/hooks/prepare-commit-msg|&amp;lt;nowiki&amp;gt;#!/bin/sh&lt;br /&gt;
case &amp;quot;$2,$3&amp;quot; in&lt;br /&gt;
  ,|template,)&lt;br /&gt;
    if git diff-index --diff-filter=A --name-only --cached HEAD \&lt;br /&gt;
        | grep -q &#039;/APKBUILD$&#039;; then&lt;br /&gt;
      meta() { git diff --staged | grep &amp;quot;^+$1&amp;quot; | sed &#039;s/.*=&amp;quot;\?//;s/&amp;quot;$//&#039;;}&lt;br /&gt;
      printf &#039;testing/%s: new aport\n\n%s\n%s\n&#039; &amp;quot;$(meta pkgname)&amp;quot; \&lt;br /&gt;
        &amp;quot;$(meta url)&amp;quot; &amp;quot;$(meta pkgdesc)&amp;quot; &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      printf &#039;%s\n\n%s&#039; `git diff-index --name-only --cached HEAD \&lt;br /&gt;
        | sed -n &#039;s/\/APKBUILD$//p;q&#039;` &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    fi;;&lt;br /&gt;
esac&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Now your changes are only available locally in your repository.&lt;br /&gt;
&lt;br /&gt;
Because you do not have push rights to the Alpine aports repository you need to create a merge request to [https://gitlab.alpinelinux.org/alpine/aports Alpine&#039;s GitLab instance].&lt;br /&gt;
&lt;br /&gt;
Alternatively you can also create a diff (patch) of the changes you made and send this patch to the &lt;br /&gt;
[https://lists.alpinelinux.org/~alpine/aports  alpine-aports mailinglist].&lt;br /&gt;
&lt;br /&gt;
To create a diff patch:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^}}&lt;br /&gt;
&lt;br /&gt;
or if you have sprunge, you can create a link to your patch for convenience&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^ --stdout &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; sprunge}}&lt;br /&gt;
&lt;br /&gt;
== Automated flagging of outdated ports ==&lt;br /&gt;
Consider adding your port to [https://release-monitoring.org/ Anitya], so it will be flagged as outdated&lt;br /&gt;
as soon as a new stable version is released by upstream.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[APKBUILD Reference]]&lt;br /&gt;
* [[APKBUILD examples]]&lt;br /&gt;
* [[Development using git]]&lt;br /&gt;
* [[Development using git:Quality assurance]]&lt;br /&gt;
&lt;br /&gt;
[[category: Package Manager]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26376</id>
		<title>Creating an Alpine package</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26376"/>
		<updated>2024-02-11T23:42:09Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This is a brief list of the steps to add a new package. Details are below, but a NB can miss a few steps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create an account on github.alpine&lt;br /&gt;
&amp;lt;li&amp;gt;Fork the aports repository. &lt;br /&gt;
&amp;lt;li&amp;gt;Clone your new fork.&lt;br /&gt;
&amp;lt;li&amp;gt;Set git pull.rebase=true, set your username and email.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a new branch (don&#039;t use master).&lt;br /&gt;
&amp;lt;li&amp;gt;Add a new directory under testing that is your new package name.&lt;br /&gt;
&amp;lt;li&amp;gt;Add your APKBUILD file.&lt;br /&gt;
&amp;lt;li&amp;gt;Run abuild checksum&lt;br /&gt;
&amp;lt;li&amp;gt;Make sure you run the apkbuild-lint and aport -r and there are no warnings.&lt;br /&gt;
&amp;lt;li&amp;gt;Commit your APKBUILD with the commit message: &#039;testing/packagename: new aport&#039;&lt;br /&gt;
&amp;lt;li&amp;gt;Push your changes to github.alpine.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a merge request.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the rest of this wiki for details on the steps above.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
To build a package for Alpine Linux you need an Alpine Linux installation. Check the [[Installation]] page to see all available installation options.&lt;br /&gt;
&lt;br /&gt;
== Setup your system and account  ==&lt;br /&gt;
{{:Setup_your_system_and_account_for_building_packages}}&lt;br /&gt;
&lt;br /&gt;
== Getting some help ==&lt;br /&gt;
&lt;br /&gt;
It might be wise to start by checking what the [[Abuild and Helpers|abuild]] program can/cannot do.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -h}}&lt;br /&gt;
&lt;br /&gt;
For real help, you can also go on #alpine-devel on [[IRC]].&lt;br /&gt;
&lt;br /&gt;
A reference for APKBUILD files is available as [[APKBUILD Reference]] wiki page or a man page in the &#039;abuild-doc&#039; package:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|man APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Creating an APKBUILD file  ==&lt;br /&gt;
&lt;br /&gt;
=== Use a template APKBUILD ===&lt;br /&gt;
&lt;br /&gt;
To create the actual APKBUILD file {{Pkg|newapkbuild}} can serve you a template to start with. It will create a directory with the given package name, place an example/template APKBUILD file to the given directory, and fill some variables if those are provided. Please check the [[Package_policies| package policies]] page about naming details.&lt;br /&gt;
&lt;br /&gt;
If you doubt to which repository your package belongs to you can safely use &#039;&#039;&#039;testing&#039;&#039;&#039;. Building package in your aports/testing directory is not mandatory but this way the package is already at the right place.&lt;br /&gt;
&lt;br /&gt;
{{:Abuild and Helpers}}&lt;br /&gt;
&lt;br /&gt;
{{Note|On older Alpine systems, abuild -c -n &#039;&#039;packagename&#039;&#039; was the way to create APKBUILD files. The &#039;packagename&#039; was a parameter to the -n option so order of -c and -n matters. }}&lt;br /&gt;
&lt;br /&gt;
[[Abuild_and_Helpers#apkbuild-cpan|apkbuild-cpan]] simplifies the creation of perl packages from CPAN and [[Abuild_and_Helpers#apkbuild-pypi|apkbuild-pypi]] ease the generation of APKBUILD files for python packages from PyPi.  &lt;br /&gt;
&lt;br /&gt;
If you are creating a daemon package which needs initd scripts you can add the -c making it: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|newapkbuild -c &#039;&#039;packagename&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This will copy the sample initd and confd files to the build directory.&amp;lt;BR&amp;gt;&lt;br /&gt;
A third file sample.install file will be copied as well (we will discuss this later on).&lt;br /&gt;
&lt;br /&gt;
=== Modify your APKBUILD ===&lt;br /&gt;
Edit APKBUILD and fill in the needed info (especially pkgname, pkgver, pkgdesc, url, license, depends and source). &lt;br /&gt;
&lt;br /&gt;
If you are going to use any of the variables for directories like $pkgdir, always make sure they are double quoted like: &lt;br /&gt;
&lt;br /&gt;
 &amp;quot;$pkgdir&amp;quot;/somedir&lt;br /&gt;
&lt;br /&gt;
This will prevent issues with spaces/special characters in the future. &lt;br /&gt;
&lt;br /&gt;
{{Note|If you like syntax highlighting we suggest you to install vim. We have setup vim to recognize the APKBUILD file as a bash scripts so its easier to read them.}}&lt;br /&gt;
&lt;br /&gt;
=== APKBUILD variables/functions  ===&lt;br /&gt;
&lt;br /&gt;
==== source  ====&lt;br /&gt;
&lt;br /&gt;
The source variable is not only used to list the remote source files to fetch, it is also used to list the local files that abuild will need in order to build the apk. Examples of such local files include: init.d files, conf.d files, install files (see [[Creating an Alpine package#install|install variable]]), patches, and all other necessary files.&lt;br /&gt;
&lt;br /&gt;
Here are few things to note:&lt;br /&gt;
&lt;br /&gt;
* When you are finished adding local and/or remote files to &#039;&#039;source&#039;&#039;, you can execute the following command to add their checksums to the APKBUILD file:&lt;br /&gt;
: {{cmd|abuild checksum}}&lt;br /&gt;
: {{Note|When later updating the content of &#039;&#039;source&#039;&#039;, or updating a file that is listed in &#039;&#039;source&#039;&#039;, you must also update their checksums again with the same command.}}&lt;br /&gt;
&lt;br /&gt;
* When the remote file is hosted at SourceForge, it&#039;s best to specify the special mirrors link used by SourceForge:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
: (or similar depending on the package).&lt;br /&gt;
&lt;br /&gt;
* When the remote filename is not specified in the URI (ie, does not end in &#039;/software-1.0.tar.gz&#039;), such as:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
: You must prepend &#039;${pkgname}-${pkgver}.tar.gz::&#039; to the protocol, like so:&lt;br /&gt;
: &amp;lt;pre&amp;gt;source=&amp;quot;${pkgname}-${pkgver}.tar.gz::http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
: This causes the file to be saved as &#039;&#039;software-1.0.tar.gz&#039;&#039; where abuild can use it, instead of &#039;&#039;?get=software&amp;amp;ver=1.0&#039;&#039;, where abuild cannot use it.&lt;br /&gt;
&lt;br /&gt;
* Some projects didn&#039;t provide a release tarball. Beware that some git services (gitweg, cgit, …?) doesn’t provide &#039;&#039;stable&#039;&#039; tarballs, so when you point source to an tarball like &amp;lt;tt&amp;gt;https://repo.or.cz/w/gitstats.git/snapshot/ad7efbb9399e60cee6cb217c6b47e604174a8093.tar.gz&amp;lt;/tt&amp;gt;, then you will run into issues because the checksum changes when downloading on the build system. This is not a problem on GitHub, GitLab and other decent services provides, they provide &#039;&#039;stable&#039;&#039; tarballs.&lt;br /&gt;
&lt;br /&gt;
* abuild currently supports the following protocols for remote file retrieval:&lt;br /&gt;
** http&lt;br /&gt;
** https&lt;br /&gt;
** ftp&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--: {{Note|If the you want to download from https, you need GNU wget installed on your system.}}--&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
* abuild currently supports the following archive types/archive file extensions:&lt;br /&gt;
** .tar&lt;br /&gt;
** .tar.gz / .tgz&lt;br /&gt;
** .tar.bz2&lt;br /&gt;
** .tar.lz (only in Alpine &amp;gt;=3.7)&lt;br /&gt;
** .tar.lzma&lt;br /&gt;
** .tar.xz&lt;br /&gt;
** .zip&lt;br /&gt;
&lt;br /&gt;
==== depends &amp;amp;amp; makedepends  ====&lt;br /&gt;
&lt;br /&gt;
Depends are the actual running dependencies that a package would need when it is running. Makedepends are only needed when you are building a package. If you set a package in depends, you do not need to add it to makedepends as well. The best way to find out what the depends and makedepends of a package are is to [https://en.wikipedia.org/wiki/Rtfm RTFM]. &lt;br /&gt;
&lt;br /&gt;
No kidding, lots of important information can be found in the package INSTALL and README files (or the likes). Another good way is the run &amp;lt;code&amp;gt;./configure --help&amp;lt;/code&amp;gt; from the source directory to see which options are needed for configure to finish without errors. If you do not yet have a source directory you can create one with the command: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild unpack}}&lt;br /&gt;
&lt;br /&gt;
Running &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt; will also show you how you can disable a specific option for this package. For instance, a good example is &amp;quot;--disable-nls&amp;quot; which will disable native language support and thus does not depend on gettext (libiconv, glib, ...). &lt;br /&gt;
&lt;br /&gt;
Alpine likes to keep things small, so we try to disable as much as possible without losing too many features. The exact disable/enable options are decided by the package builder but please try to follow Alpine&#039;s design concept as much as possible.&lt;br /&gt;
&lt;br /&gt;
An easy way of quickly finding out the build info for a package is to check Arch Linux (Alpine package management and build scripts are similar) or Gentoo Linux ebuilds (previous versions of Alpine were based on Gentoo).&lt;br /&gt;
&lt;br /&gt;
* [https://gitweb.gentoo.org/repo/gentoo.git/tree/ Gentoo Ebuilds] &lt;br /&gt;
* [https://archlinux.org/packages/?q=search Arch Linux packages] [https://aur.archlinux.org/ Arch Linux User Repository]&lt;br /&gt;
&lt;br /&gt;
==== license  ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;license&#039;&#039;&#039; tag must reflect the license of the source code. Please check the source tarball for COPYING, LICENSE, or other files with names that indicates that it contains licensing information. Beside the license file most developer include headers in the source code files with licensing details.&lt;br /&gt;
&lt;br /&gt;
If the license is on the [https://spdx.org/licenses/ SPDX License List] or [https://spdx.org/licenses/exceptions-index.html SPDX License Exceptions], use the identifier specified by SPDX.&lt;br /&gt;
&lt;br /&gt;
Note that some licenses have additional requirements that should be adhered to. The &amp;lt;code&amp;gt;MIT&amp;lt;/code&amp;gt; license for example has the requirement:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that we need to include the license as shipped with the project.&lt;br /&gt;
&lt;br /&gt;
If a package has a special/custom license or is not listed as [https://opensource.org/licenses/alphabetical OSI approved], use the identifier &amp;quot;custom&amp;quot;. In that case we need to provide the license file with the package as well.&lt;br /&gt;
&lt;br /&gt;
Because we want to save space and don&#039;t like to have licenses all over our system we have decided to include the license in the doc subpackage. Please follow the following guidelines to add a proper license. Locate the license file inside the source package. Add the doc subpackage to the $subpackages variable as follows: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a similar line to the following to your package() function, depending on the license description file: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 COPYING &amp;quot;$pkgdir&amp;quot;/usr/share/licenses/$pkgname/COPYING}}&lt;br /&gt;
&lt;br /&gt;
If you follow these steps then abuild will automatically add the license to the package-doc apk for you.&lt;br /&gt;
&lt;br /&gt;
{{Warning|It is not acceptable to package software with &amp;quot;unknown&amp;quot; license! If you can&#039;t find the license of the source code, please contact the author and ask them to specify the license. }}&lt;br /&gt;
&lt;br /&gt;
==== arch ====&lt;br /&gt;
&lt;br /&gt;
The package architecture(s) to build for.  This can be one of: &#039;&#039;x86, x86_64, all,&#039;&#039; or &#039;&#039;noarch&#039;&#039;, where &#039;&#039;all&#039;&#039; means all architectures, and &#039;&#039;noarch&#039;&#039; means it&#039;s architecture-independent (e.g., a pure-python package).&lt;br /&gt;
{{Tip|To determine if your APKBUILD can use &#039;&#039;noarch&#039;&#039;, build the package for your architecture and then run &amp;quot;scanelf -R pkg&amp;quot; from the directory that the APKBUILD resides in, in order to scan for ELF files in the &#039;&#039;./pkg&#039;&#039; directory.  If you do NOT get output from this, then &#039;&#039;noarch&#039;&#039; can be used.}}&lt;br /&gt;
&lt;br /&gt;
==== url  ====&lt;br /&gt;
&lt;br /&gt;
Website address for the program. This is useful later on when either finding documentation or other information about the package.&lt;br /&gt;
&lt;br /&gt;
==== pkgdesc  ====&lt;br /&gt;
&lt;br /&gt;
A brief, one line, description of what the package does. Useful for the package management system. It should start with a capital letter and does &#039;&#039;&#039;not&#039;&#039;&#039; end with a period.&lt;br /&gt;
&lt;br /&gt;
Here is an example from apk_info for the OpenSSH client package:&lt;br /&gt;
&lt;br /&gt;
 pkgdesc=&amp;quot;Port of OpenBSD&#039;s free SSH release - client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== pkgver  ====&lt;br /&gt;
&lt;br /&gt;
Provide the release number of the package you are building.&lt;br /&gt;
&lt;br /&gt;
==== pkgrel  ====&lt;br /&gt;
&lt;br /&gt;
The $pkgrel versioning is made so that if you change something in your APKBUILD file without changing the actual $pkgver, you can increment pkgrel so apk tools will detect it as an update. For instance, if you forget to add a dependency, you can add it afterward and you can +1 pkgver so apk finds this update and adds the missing dependency. When there&#039;s an upstream version change, we reset the pkgrel to 0.&lt;br /&gt;
&lt;br /&gt;
==== pkgname  ====&lt;br /&gt;
&lt;br /&gt;
The base name of the package you are creating.  For Freeswitch 1.0.6, you would use &amp;quot;freeswitch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== install  ====&lt;br /&gt;
&lt;br /&gt;
There are 6 different kinds of install scripts. Each script is called with the $pkgname.&#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; where &#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; is one of the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before package is installed. Typical use is when package needs a group and a user to be created. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
addgroup -S clamav 2&amp;gt;/dev/null&lt;br /&gt;
adduser -S -D -H -s /bin/false -G clamav -g clamav clamav 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the &#039;&#039;exit 0&#039;&#039; at the end. If the script exits with failure (if the user already exist), the package will not be installed and &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; will exit with failure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after the package is installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as pre-install but is executed before upgrading/downgrading/reinstalling an already installed package. Note that exiting with failure will not cause apk to exit with failure, but will mark the package as broken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as post-install but is executed after upgrading/downgrading/reinstalling an already installed package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before uninstalling a package. If script exits with failure apk will not uninstall the package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after a package have been uninstalled. For example, can be used to restore busybox links:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
busybox --install -s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the package has a pre-install and post-install script the APKBUILD should have the &#039;&#039;install&#039;&#039; variable defined:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
install=&amp;quot;$pkgname.pre-install $pkgname.post-install&amp;quot;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== subpackages  ====&lt;br /&gt;
&lt;br /&gt;
$subpackages are made to split up the normal &amp;quot;make install&amp;quot; into separate packages. The most common subpackages we use are doc and dev. Because we like to keep our target system small we move documentation and development files (only needed when building packages) into separate packages. To use the specific program a user only need to install the base apk without package-doc or package-dev, but if he wants to read the manual he will need to install package-doc. &lt;br /&gt;
&lt;br /&gt;
The easiest way to find out if you need to use -dev and -doc is to first build the package without these options set and wait until the build finishes. When its finished you should have a pkg directory which is the fake root directory. Inside this directory you will see the structure as how it would be installed in / on the target system. &lt;br /&gt;
&lt;br /&gt;
To see if you need the -dev package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/ -name &#039;*.[acho]&#039; -o -name &#039;*.la&#039;}}&lt;br /&gt;
&lt;br /&gt;
If this returns any files you need to include the -dev package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; To see if you need the -doc package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/share -name doc -o -name man -o -name info -o -name html -o -name sgml -o -name licenses}}&lt;br /&gt;
&lt;br /&gt;
If this returns any directories you need to include the -doc package. &lt;br /&gt;
&lt;br /&gt;
===== Custom subpackages  =====&lt;br /&gt;
&lt;br /&gt;
Some software additionally has non-essential files that do not qualify as either documentation or development content. These files should be placed in their own, specialized subpackage(s). Some packages include large test suites which are only needed in specific circumstances or binaries which have depends which we prefer not to install. To handle those we create our own package/function. In the APKBUILD below the build() function we create another function: &lt;br /&gt;
&lt;br /&gt;
 test() {&lt;br /&gt;
        mkdir -p &amp;quot;$subpkgdir&amp;quot;/usr&lt;br /&gt;
        mv &amp;quot;$pkgdir&amp;quot;/usr/package-test &amp;quot;$subpkgdir&amp;quot;/usr/&lt;br /&gt;
        # or amove usr/package-test&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We also need to add the package info to $subpackages variable: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc $pkgname-dev $pkgname-test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
After we finish building the package you should see another apk called packagename-test.apk which includes the files which we moved to the $subpkgdir dir. &lt;br /&gt;
&lt;br /&gt;
The above mentioned variables can also be used in our custom function. If we want for instance to build the test() function with perl support we would add: &lt;br /&gt;
&lt;br /&gt;
 depends=&amp;quot;perl&amp;quot;&lt;br /&gt;
 makedepends=&amp;quot;perl-dev&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we would install the base package it would not install perl, but if we install the package-test package it would.&lt;br /&gt;
&lt;br /&gt;
==== Patches  ====&lt;br /&gt;
&lt;br /&gt;
Please make sure you always submit human readable patches. Ways to create them are: &lt;br /&gt;
&lt;br /&gt;
directory compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -Nurp original_directory new_directory &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
file compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -up original.file new.file &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
If a patch contains a completely new file but not *.rej or *.orig file, you need to add -N option to diff, but you may need to add exclusions with &amp;lt;code&amp;gt;--exclude PATTERN&amp;lt;/code&amp;gt; so that you do not inadvertently add files.  You may need to manually delete unwanted files inside the patch file.&lt;br /&gt;
&lt;br /&gt;
Because multiple patches can patch the same file, they can change the offsets required by subsequent patches. To make sure we always patch in a specific way, we should number the patches as follows: &lt;br /&gt;
&lt;br /&gt;
 10-patch1.patch 20-patch2.patch 30-patch3.patch&lt;br /&gt;
&lt;br /&gt;
This way we are always sure that patch 1 is applied first, and if we want to add additional patches between them we can use appropriate indexes (e.g. 11, 12, 21, 22).&lt;br /&gt;
&lt;br /&gt;
Add the names of the patch files to the &#039;&#039;source&#039;&#039; variable. If you haven&#039;t declared a custom &#039;&#039;prepare&#039;&#039; function, no further action is necessary. Otherwise, be sure to call &#039;&#039;default_prepare&#039;&#039; in your &#039;&#039;prepare&#039;&#039; function. For example:&lt;br /&gt;
&lt;br /&gt;
 prepare() {&lt;br /&gt;
 	default_prepare&lt;br /&gt;
 &lt;br /&gt;
 	# do your stuff&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Note: Some older packages contain a &#039;&#039;for&#039;&#039; loop in the &#039;&#039;prepare&#039;&#039; function to apply patches. This is not needed anymore, as patches are handled by &#039;&#039;default_prepare&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In Alpine &amp;gt;=3.4 you can define patch_args to supply the patch level.  This only works if all the patches have the same patch level.  If there are a lot of patches from different sources, there is a good chance that you may need to edit them, as discussed below.&lt;br /&gt;
&lt;br /&gt;
To automatically patch the package (available only in Alpine &amp;gt;=3.4) if it uses a patch level (-pX) other than the default (-p1), you need to carefully modify the patch.  First, you&#039;ll need a text editor that does not automatically convert  between Windows and Unix new lines (or, disable this feature) so that it preserves the old code.  The next thing you&#039;ll need to do is modify the paths on &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines in the .patch file.  You can begin the path with a/ and b/ like shown below.  Next, you need to adjust the paths so that the relative base path is from inside $builddir.  Anything to the left of $builddir, including $builddir itself, needs to be removed from the path.  So, if $builddir is /home/USER/aports/community/chromium/src/chromium-65, you need to erase it on the &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines.  Inside the chromium-65 folder you can see a src folder that has 3rdparty as a descendant.  If a patch originally has a deeper patch level, you may need to fill in the missing portion of the path.  For example, use the &amp;lt;code&amp;gt;find . -name &amp;quot;Assertions.cpp&amp;quot;&amp;lt;/code&amp;gt; command to find the full path to the file relative to the base.&lt;br /&gt;
&lt;br /&gt;
{{Cat|example.patch|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Author: John Doe &amp;lt;johndoe@mail.com&amp;gt;&lt;br /&gt;
URL: http://.....&lt;br /&gt;
Summary: Fixes musl compatibility&lt;br /&gt;
----&lt;br /&gt;
--- a/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp.orig&lt;br /&gt;
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp&lt;br /&gt;
@@ -142,7 +142,7 @@&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 FrameToNameScope::FrameToNameScope(void* addr) : m_name(0), m_cxaDemangled(0) {&lt;br /&gt;
-#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; !defined(__UCLIBC__))&lt;br /&gt;
+#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; defined(__GLIBC__))&lt;br /&gt;
   Dl_info info;&lt;br /&gt;
   if (!dladdr(addr, &amp;amp;info) || !info.dli_sname)&lt;br /&gt;
return;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Portions of the patch may be outdated, removed completely as in the source code file completely removed, or moved or renamed files.  You need to delete that section of the patch or find where that section of code changed and re-diff it.&lt;br /&gt;
&lt;br /&gt;
It is good etiquette to give credit at the top and the location of where you originally found them with notes.&lt;br /&gt;
&lt;br /&gt;
Excluding patches with global variable resembling patch_opts is not available on Alpine.  To exclude patches you need to create your own custom prepare().&lt;br /&gt;
&lt;br /&gt;
If you have a monolithic patch where there are a bunch of patches in one big patch, you could use filterdiff which is available in the patchutils package.&lt;br /&gt;
&lt;br /&gt;
Just do something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
makedepends=&amp;quot;patchutils&amp;quot;&lt;br /&gt;
&lt;br /&gt;
prepare() {&lt;br /&gt;
  ...&lt;br /&gt;
  cd &amp;quot;$builddir&amp;quot;&lt;br /&gt;
  filterdiff -x &#039;*drivers/video/logo*&#039; &amp;quot;$srcdir&amp;quot;/original.patch &amp;gt; &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
  patch -p1 -i &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to put the wildcard pattern in single quotes for it to work.&lt;br /&gt;
&lt;br /&gt;
==== Configure options  ====&lt;br /&gt;
&lt;br /&gt;
Alpine has some default configure options we set by default. We use /usr for prefix to make sure everything is installed with /usr in front of it. If you notice that anything is installed in the wrong directory please run {{Cmd|./configure --help}} and see if you can set the correct location. &lt;br /&gt;
&lt;br /&gt;
We are not covering the depend switches here we have discussed this already in the depend section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Make options  ====&lt;br /&gt;
&lt;br /&gt;
If you notice weird problems when compiling or installing the package with make/make install you could try to disable [https://www.gnu.org/software/make/manual/make.html#Parallel parallel] building/installing. A normal make line would be: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make}}&lt;br /&gt;
&lt;br /&gt;
To disable parallel we use: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make -j1}}&lt;br /&gt;
&lt;br /&gt;
We can use the same for make install. &lt;br /&gt;
&lt;br /&gt;
Because we do not want to install the package in our build environment but we want to install it in a fake root directory we need to tell &#039;make install&#039; to use another destination directory instead of &#039;/&#039;. We do this by setting a variable when we execute make install as followed: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make DESTDIR{{=}}&amp;quot;$pkgdir&amp;quot; install}}&lt;br /&gt;
&lt;br /&gt;
Please note that some Makefiles do not support this variable and will always install software in &#039;/&#039;. To make sure you do not mess up your build system NEVER run your build system as root but always use a custom user and doas when needed. If by accident the Makefile does not support DESTDIR variable it will fail to install in our build system system directories.&lt;br /&gt;
&lt;br /&gt;
==== builddir ====&lt;br /&gt;
If you used &amp;lt;tt&amp;gt;newapkbuild&amp;lt;/tt&amp;gt; to create your APKBUILD file, you must specify the path to your unpacked sources. Inside the sections during the prepare/build/install process &#039;&#039;builddir&#039;&#039; is used. Most of the time a combination of &#039;&#039;$srcdir&#039;&#039; and &#039;&#039;$pkgname-$pkgver&#039;&#039; will work. When not, check the /src directory or the source tarball for the right string. Especially when you are working with automatically generated tarballs (like from github and gitorious), this needs to be adjusted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
builddir=&amp;quot;$srcdir&amp;quot;/$pkgname-$pkgver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Additional files  ====&lt;br /&gt;
&lt;br /&gt;
If you want/need to install additional files not mentioned above you can use the following cmd (this is an example of a conf file): &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 doc/$pkgname.conf &amp;quot;$pkgdir&amp;quot;/etc/$pkgname.conf}}&lt;br /&gt;
&lt;br /&gt;
== Build the package  ==&lt;br /&gt;
&lt;br /&gt;
If you did not already create the checksums as mentioned above you can do so now: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $pkgname&lt;br /&gt;
abuild checksum}}&lt;br /&gt;
&lt;br /&gt;
It&#039;s about time we build our package. Because a build system should never have all the package installed to prevent linking to packages we don&#039;t want it to link we use a abuild recursively with the &#039;&#039;&#039;-r&#039;&#039;&#039; switch. It will install all dependencies from your repository and builds it, afterwards it will uninstall all those depending packages again.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -r}}&lt;br /&gt;
&lt;br /&gt;
See also [[Abuild_and_Helpers|Abuild and Helpers]].&lt;br /&gt;
&lt;br /&gt;
== Testing the package locally ==&lt;br /&gt;
&lt;br /&gt;
When it completes, your package will be found in a subfolder of &amp;lt;code&amp;gt;~/packages&amp;lt;/code&amp;gt;.  You may want to test it on your machine but only if the package is not a critical system package like musl or apk-tools package.  To avoid borking your system (as in making it impossible to use &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; or to restore back the system and the compiler toolchain) for a critical system package, you should test on a chroot first before using it live.&lt;br /&gt;
&lt;br /&gt;
The best way to test a package locally is to modify your &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; so that it includes the indexes to your locally built packages - the directories that contain &amp;lt;code&amp;gt;ARCH/APKINDEX.tar.gz&amp;lt;/code&amp;gt;. For example the &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; below includes locally built packages in testing, community and main. To use this example change &amp;lt;code&amp;gt;USER&amp;lt;/code&amp;gt; to your login name.&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/apk/repositories|/home/USER/packages/testing/&lt;br /&gt;
/home/USER/packages/main/&lt;br /&gt;
/home/USER/packages/community/&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you prefer to test a package without changing any other configuration you can use the &amp;lt;code&amp;gt;-X, --repository&amp;lt;/code&amp;gt; option to &amp;lt;code&amp;gt;apk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|doas apk add --repository /home/USER/packages/testing $pkgname}}&lt;br /&gt;
&lt;br /&gt;
== Code review ==&lt;br /&gt;
&lt;br /&gt;
To successfully have your package pass through code reviewers (as of Feb 18, 2018 are nmeum and jirutka on GitHub) and possible increased acceptance, the following conventions need to be followed:&lt;br /&gt;
&lt;br /&gt;
# Custom global variables should be prefixed with underscore (_).&lt;br /&gt;
# Compact code as in merged commands, removed unused variables, removal of functions that do the same thing that are automatically handled by abuild.&lt;br /&gt;
# Versioning is done properly.  For details see [[APKBUILD_Reference#pkgver]].&lt;br /&gt;
# Licensing is done properly. Remove unnecessary copying of licensing that is already OSI approved.&lt;br /&gt;
# Naming conventions rules for unofficial variables as in _gitrev is preferred over commit.&lt;br /&gt;
# Indent with tabs not spaces.&lt;br /&gt;
# Removal of explicit return 1.  (They are still found the old APKBUILD files if you are learning but are now strongly discouraged.)&lt;br /&gt;
# Disabling check() requires either (1) a comment (#) stating next to options=&amp;quot;!check&amp;quot; that there is no test suite/unit tests or (2) functioning working check() function.&lt;br /&gt;
# Explicit call to subpackages=&amp;quot;$pkgname-doc&amp;quot; must be used instead of explicit gzip man page compression.&lt;br /&gt;
# Ideally, lines should be no more than 80 columns wide&lt;br /&gt;
&lt;br /&gt;
Additionally, make sure to run the linter on your package:&lt;br /&gt;
{{Cmd|doas apk add atools&lt;br /&gt;
apkbuild-lint APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
For more information see [[Development using git:Quality assurance]] and [[Package_policies]].&lt;br /&gt;
Also check out [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/COMMITSTYLE.md?ref_type=heads aports/COMMITSTYLE.md] and [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/CODINGSTYLE.md?ref_type=heads aports/CODINGSTYLE.md]&lt;br /&gt;
&lt;br /&gt;
== Commit your work  ==&lt;br /&gt;
&lt;br /&gt;
After you successfully build your package and properly followed the conventions and requirements in the code review section, you can submit your APKBUILD to Alpine&#039;s git repository. &lt;br /&gt;
&lt;br /&gt;
Update your git repo, before adding new files: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git pull}}&lt;br /&gt;
&lt;br /&gt;
This should pull all the changes made by others into your local git repo.&lt;br /&gt;
&lt;br /&gt;
When you think you are ready you can add your files to git: &lt;br /&gt;
&lt;br /&gt;
NOTE: when using our Gitlab instance, you can create MR&#039;s for each package. Please squash all commits related to the same package into a single one per MR.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git add testing/$pkgdir (include any other files needed for the build; $pkgname.install...)&lt;br /&gt;
git commit}}&lt;br /&gt;
&lt;br /&gt;
Use the following commit message template for new aports (without the comments):&lt;br /&gt;
&lt;br /&gt;
{{Cat|template|testing/$pkgname: new aport   # this will be the subject line&lt;br /&gt;
                              # a blank line&lt;br /&gt;
$url                          # project homepage&lt;br /&gt;
$pkgdesc                      # one line description}}&lt;br /&gt;
&lt;br /&gt;
Or you could add the following and &amp;lt;code&amp;gt;chmod +x ports/.git/hooks/prepare-commit-msg&amp;lt;/code&amp;gt; to automatically generate commit message which the default aports/.githooks/ does not:&lt;br /&gt;
&lt;br /&gt;
{{Cat|aports/.git/hooks/prepare-commit-msg|&amp;lt;nowiki&amp;gt;#!/bin/sh&lt;br /&gt;
case &amp;quot;$2,$3&amp;quot; in&lt;br /&gt;
  ,|template,)&lt;br /&gt;
    if git diff-index --diff-filter=A --name-only --cached HEAD \&lt;br /&gt;
        | grep -q &#039;/APKBUILD$&#039;; then&lt;br /&gt;
      meta() { git diff --staged | grep &amp;quot;^+$1&amp;quot; | sed &#039;s/.*=&amp;quot;\?//;s/&amp;quot;$//&#039;;}&lt;br /&gt;
      printf &#039;testing/%s: new aport\n\n%s\n%s\n&#039; &amp;quot;$(meta pkgname)&amp;quot; \&lt;br /&gt;
        &amp;quot;$(meta url)&amp;quot; &amp;quot;$(meta pkgdesc)&amp;quot; &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      printf &#039;%s\n\n%s&#039; `git diff-index --name-only --cached HEAD \&lt;br /&gt;
        | sed -n &#039;s/\/APKBUILD$//p;q&#039;` &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    fi;;&lt;br /&gt;
esac&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Now your changes are only available locally in your repository.&lt;br /&gt;
&lt;br /&gt;
Because you do not have push rights to the Alpine aports repository you need to create a merge request to [https://gitlab.alpinelinux.org/alpine/aports Alpine&#039;s GitLab instance].&lt;br /&gt;
&lt;br /&gt;
Alternatively you can also create a diff (patch) of the changes you made and send this patch to the &lt;br /&gt;
[https://lists.alpinelinux.org/~alpine/aports  alpine-aports mailinglist].&lt;br /&gt;
&lt;br /&gt;
To create a diff patch:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^}}&lt;br /&gt;
&lt;br /&gt;
or if you have sprunge, you can create a link to your patch for convenience&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^ --stdout &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; sprunge}}&lt;br /&gt;
&lt;br /&gt;
== Automated flagging of outdated ports ==&lt;br /&gt;
Consider adding your port to [https://release-monitoring.org/ Anitya], so it will be flagged as outdated&lt;br /&gt;
as soon as a new stable version is released by upstream.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[APKBUILD Reference]]&lt;br /&gt;
* [[APKBUILD examples]]&lt;br /&gt;
* [[Development using git]]&lt;br /&gt;
* [[Development using git:Quality assurance]]&lt;br /&gt;
&lt;br /&gt;
[[category: Package Manager]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26375</id>
		<title>Creating an Alpine package</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26375"/>
		<updated>2024-02-11T23:38:59Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This is a brief list of the steps to add a new package. Details are below, but a NB can miss a few steps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create an account on github.alpine&lt;br /&gt;
&amp;lt;li&amp;gt;Fork the aports repository. &lt;br /&gt;
&amp;lt;li&amp;gt;Clone your new fork.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a new branch (don&#039;t use master).&lt;br /&gt;
&amp;lt;li&amp;gt;Add a new directory under testing that is your new package name.&lt;br /&gt;
&amp;lt;li&amp;gt;Add your APKBUILD file.&lt;br /&gt;
&amp;lt;li&amp;gt;Run abuild checksum&lt;br /&gt;
&amp;lt;li&amp;gt;Make sure you run the apkbuild-lint and aport -r and there are no warnings.&lt;br /&gt;
&amp;lt;li&amp;gt;Commit your APKBUILD with the commit message: &#039;testing/packagename: new aport&#039;&lt;br /&gt;
&amp;lt;li&amp;gt;Push your changes to github.alpine.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a merge request.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the rest of this wiki for details on the steps above.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
To build a package for Alpine Linux you need an Alpine Linux installation. Check the [[Installation]] page to see all available installation options.&lt;br /&gt;
&lt;br /&gt;
== Setup your system and account  ==&lt;br /&gt;
{{:Setup_your_system_and_account_for_building_packages}}&lt;br /&gt;
&lt;br /&gt;
== Getting some help ==&lt;br /&gt;
&lt;br /&gt;
It might be wise to start by checking what the [[Abuild and Helpers|abuild]] program can/cannot do.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -h}}&lt;br /&gt;
&lt;br /&gt;
For real help, you can also go on #alpine-devel on [[IRC]].&lt;br /&gt;
&lt;br /&gt;
A reference for APKBUILD files is available as [[APKBUILD Reference]] wiki page or a man page in the &#039;abuild-doc&#039; package:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|man APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Creating an APKBUILD file  ==&lt;br /&gt;
&lt;br /&gt;
=== Use a template APKBUILD ===&lt;br /&gt;
&lt;br /&gt;
To create the actual APKBUILD file {{Pkg|newapkbuild}} can serve you a template to start with. It will create a directory with the given package name, place an example/template APKBUILD file to the given directory, and fill some variables if those are provided. Please check the [[Package_policies| package policies]] page about naming details.&lt;br /&gt;
&lt;br /&gt;
If you doubt to which repository your package belongs to you can safely use &#039;&#039;&#039;testing&#039;&#039;&#039;. Building package in your aports/testing directory is not mandatory but this way the package is already at the right place.&lt;br /&gt;
&lt;br /&gt;
{{:Abuild and Helpers}}&lt;br /&gt;
&lt;br /&gt;
{{Note|On older Alpine systems, abuild -c -n &#039;&#039;packagename&#039;&#039; was the way to create APKBUILD files. The &#039;packagename&#039; was a parameter to the -n option so order of -c and -n matters. }}&lt;br /&gt;
&lt;br /&gt;
[[Abuild_and_Helpers#apkbuild-cpan|apkbuild-cpan]] simplifies the creation of perl packages from CPAN and [[Abuild_and_Helpers#apkbuild-pypi|apkbuild-pypi]] ease the generation of APKBUILD files for python packages from PyPi.  &lt;br /&gt;
&lt;br /&gt;
If you are creating a daemon package which needs initd scripts you can add the -c making it: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|newapkbuild -c &#039;&#039;packagename&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This will copy the sample initd and confd files to the build directory.&amp;lt;BR&amp;gt;&lt;br /&gt;
A third file sample.install file will be copied as well (we will discuss this later on).&lt;br /&gt;
&lt;br /&gt;
=== Modify your APKBUILD ===&lt;br /&gt;
Edit APKBUILD and fill in the needed info (especially pkgname, pkgver, pkgdesc, url, license, depends and source). &lt;br /&gt;
&lt;br /&gt;
If you are going to use any of the variables for directories like $pkgdir, always make sure they are double quoted like: &lt;br /&gt;
&lt;br /&gt;
 &amp;quot;$pkgdir&amp;quot;/somedir&lt;br /&gt;
&lt;br /&gt;
This will prevent issues with spaces/special characters in the future. &lt;br /&gt;
&lt;br /&gt;
{{Note|If you like syntax highlighting we suggest you to install vim. We have setup vim to recognize the APKBUILD file as a bash scripts so its easier to read them.}}&lt;br /&gt;
&lt;br /&gt;
=== APKBUILD variables/functions  ===&lt;br /&gt;
&lt;br /&gt;
==== source  ====&lt;br /&gt;
&lt;br /&gt;
The source variable is not only used to list the remote source files to fetch, it is also used to list the local files that abuild will need in order to build the apk. Examples of such local files include: init.d files, conf.d files, install files (see [[Creating an Alpine package#install|install variable]]), patches, and all other necessary files.&lt;br /&gt;
&lt;br /&gt;
Here are few things to note:&lt;br /&gt;
&lt;br /&gt;
* When you are finished adding local and/or remote files to &#039;&#039;source&#039;&#039;, you can execute the following command to add their checksums to the APKBUILD file:&lt;br /&gt;
: {{cmd|abuild checksum}}&lt;br /&gt;
: {{Note|When later updating the content of &#039;&#039;source&#039;&#039;, or updating a file that is listed in &#039;&#039;source&#039;&#039;, you must also update their checksums again with the same command.}}&lt;br /&gt;
&lt;br /&gt;
* When the remote file is hosted at SourceForge, it&#039;s best to specify the special mirrors link used by SourceForge:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
: (or similar depending on the package).&lt;br /&gt;
&lt;br /&gt;
* When the remote filename is not specified in the URI (ie, does not end in &#039;/software-1.0.tar.gz&#039;), such as:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
: You must prepend &#039;${pkgname}-${pkgver}.tar.gz::&#039; to the protocol, like so:&lt;br /&gt;
: &amp;lt;pre&amp;gt;source=&amp;quot;${pkgname}-${pkgver}.tar.gz::http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
: This causes the file to be saved as &#039;&#039;software-1.0.tar.gz&#039;&#039; where abuild can use it, instead of &#039;&#039;?get=software&amp;amp;ver=1.0&#039;&#039;, where abuild cannot use it.&lt;br /&gt;
&lt;br /&gt;
* Some projects didn&#039;t provide a release tarball. Beware that some git services (gitweg, cgit, …?) doesn’t provide &#039;&#039;stable&#039;&#039; tarballs, so when you point source to an tarball like &amp;lt;tt&amp;gt;https://repo.or.cz/w/gitstats.git/snapshot/ad7efbb9399e60cee6cb217c6b47e604174a8093.tar.gz&amp;lt;/tt&amp;gt;, then you will run into issues because the checksum changes when downloading on the build system. This is not a problem on GitHub, GitLab and other decent services provides, they provide &#039;&#039;stable&#039;&#039; tarballs.&lt;br /&gt;
&lt;br /&gt;
* abuild currently supports the following protocols for remote file retrieval:&lt;br /&gt;
** http&lt;br /&gt;
** https&lt;br /&gt;
** ftp&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--: {{Note|If the you want to download from https, you need GNU wget installed on your system.}}--&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
* abuild currently supports the following archive types/archive file extensions:&lt;br /&gt;
** .tar&lt;br /&gt;
** .tar.gz / .tgz&lt;br /&gt;
** .tar.bz2&lt;br /&gt;
** .tar.lz (only in Alpine &amp;gt;=3.7)&lt;br /&gt;
** .tar.lzma&lt;br /&gt;
** .tar.xz&lt;br /&gt;
** .zip&lt;br /&gt;
&lt;br /&gt;
==== depends &amp;amp;amp; makedepends  ====&lt;br /&gt;
&lt;br /&gt;
Depends are the actual running dependencies that a package would need when it is running. Makedepends are only needed when you are building a package. If you set a package in depends, you do not need to add it to makedepends as well. The best way to find out what the depends and makedepends of a package are is to [https://en.wikipedia.org/wiki/Rtfm RTFM]. &lt;br /&gt;
&lt;br /&gt;
No kidding, lots of important information can be found in the package INSTALL and README files (or the likes). Another good way is the run &amp;lt;code&amp;gt;./configure --help&amp;lt;/code&amp;gt; from the source directory to see which options are needed for configure to finish without errors. If you do not yet have a source directory you can create one with the command: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild unpack}}&lt;br /&gt;
&lt;br /&gt;
Running &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt; will also show you how you can disable a specific option for this package. For instance, a good example is &amp;quot;--disable-nls&amp;quot; which will disable native language support and thus does not depend on gettext (libiconv, glib, ...). &lt;br /&gt;
&lt;br /&gt;
Alpine likes to keep things small, so we try to disable as much as possible without losing too many features. The exact disable/enable options are decided by the package builder but please try to follow Alpine&#039;s design concept as much as possible.&lt;br /&gt;
&lt;br /&gt;
An easy way of quickly finding out the build info for a package is to check Arch Linux (Alpine package management and build scripts are similar) or Gentoo Linux ebuilds (previous versions of Alpine were based on Gentoo).&lt;br /&gt;
&lt;br /&gt;
* [https://gitweb.gentoo.org/repo/gentoo.git/tree/ Gentoo Ebuilds] &lt;br /&gt;
* [https://archlinux.org/packages/?q=search Arch Linux packages] [https://aur.archlinux.org/ Arch Linux User Repository]&lt;br /&gt;
&lt;br /&gt;
==== license  ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;license&#039;&#039;&#039; tag must reflect the license of the source code. Please check the source tarball for COPYING, LICENSE, or other files with names that indicates that it contains licensing information. Beside the license file most developer include headers in the source code files with licensing details.&lt;br /&gt;
&lt;br /&gt;
If the license is on the [https://spdx.org/licenses/ SPDX License List] or [https://spdx.org/licenses/exceptions-index.html SPDX License Exceptions], use the identifier specified by SPDX.&lt;br /&gt;
&lt;br /&gt;
Note that some licenses have additional requirements that should be adhered to. The &amp;lt;code&amp;gt;MIT&amp;lt;/code&amp;gt; license for example has the requirement:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that we need to include the license as shipped with the project.&lt;br /&gt;
&lt;br /&gt;
If a package has a special/custom license or is not listed as [https://opensource.org/licenses/alphabetical OSI approved], use the identifier &amp;quot;custom&amp;quot;. In that case we need to provide the license file with the package as well.&lt;br /&gt;
&lt;br /&gt;
Because we want to save space and don&#039;t like to have licenses all over our system we have decided to include the license in the doc subpackage. Please follow the following guidelines to add a proper license. Locate the license file inside the source package. Add the doc subpackage to the $subpackages variable as follows: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a similar line to the following to your package() function, depending on the license description file: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 COPYING &amp;quot;$pkgdir&amp;quot;/usr/share/licenses/$pkgname/COPYING}}&lt;br /&gt;
&lt;br /&gt;
If you follow these steps then abuild will automatically add the license to the package-doc apk for you.&lt;br /&gt;
&lt;br /&gt;
{{Warning|It is not acceptable to package software with &amp;quot;unknown&amp;quot; license! If you can&#039;t find the license of the source code, please contact the author and ask them to specify the license. }}&lt;br /&gt;
&lt;br /&gt;
==== arch ====&lt;br /&gt;
&lt;br /&gt;
The package architecture(s) to build for.  This can be one of: &#039;&#039;x86, x86_64, all,&#039;&#039; or &#039;&#039;noarch&#039;&#039;, where &#039;&#039;all&#039;&#039; means all architectures, and &#039;&#039;noarch&#039;&#039; means it&#039;s architecture-independent (e.g., a pure-python package).&lt;br /&gt;
{{Tip|To determine if your APKBUILD can use &#039;&#039;noarch&#039;&#039;, build the package for your architecture and then run &amp;quot;scanelf -R pkg&amp;quot; from the directory that the APKBUILD resides in, in order to scan for ELF files in the &#039;&#039;./pkg&#039;&#039; directory.  If you do NOT get output from this, then &#039;&#039;noarch&#039;&#039; can be used.}}&lt;br /&gt;
&lt;br /&gt;
==== url  ====&lt;br /&gt;
&lt;br /&gt;
Website address for the program. This is useful later on when either finding documentation or other information about the package.&lt;br /&gt;
&lt;br /&gt;
==== pkgdesc  ====&lt;br /&gt;
&lt;br /&gt;
A brief, one line, description of what the package does. Useful for the package management system. It should start with a capital letter and does &#039;&#039;&#039;not&#039;&#039;&#039; end with a period.&lt;br /&gt;
&lt;br /&gt;
Here is an example from apk_info for the OpenSSH client package:&lt;br /&gt;
&lt;br /&gt;
 pkgdesc=&amp;quot;Port of OpenBSD&#039;s free SSH release - client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== pkgver  ====&lt;br /&gt;
&lt;br /&gt;
Provide the release number of the package you are building.&lt;br /&gt;
&lt;br /&gt;
==== pkgrel  ====&lt;br /&gt;
&lt;br /&gt;
The $pkgrel versioning is made so that if you change something in your APKBUILD file without changing the actual $pkgver, you can increment pkgrel so apk tools will detect it as an update. For instance, if you forget to add a dependency, you can add it afterward and you can +1 pkgver so apk finds this update and adds the missing dependency. When there&#039;s an upstream version change, we reset the pkgrel to 0.&lt;br /&gt;
&lt;br /&gt;
==== pkgname  ====&lt;br /&gt;
&lt;br /&gt;
The base name of the package you are creating.  For Freeswitch 1.0.6, you would use &amp;quot;freeswitch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== install  ====&lt;br /&gt;
&lt;br /&gt;
There are 6 different kinds of install scripts. Each script is called with the $pkgname.&#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; where &#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; is one of the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before package is installed. Typical use is when package needs a group and a user to be created. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
addgroup -S clamav 2&amp;gt;/dev/null&lt;br /&gt;
adduser -S -D -H -s /bin/false -G clamav -g clamav clamav 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the &#039;&#039;exit 0&#039;&#039; at the end. If the script exits with failure (if the user already exist), the package will not be installed and &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; will exit with failure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after the package is installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as pre-install but is executed before upgrading/downgrading/reinstalling an already installed package. Note that exiting with failure will not cause apk to exit with failure, but will mark the package as broken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as post-install but is executed after upgrading/downgrading/reinstalling an already installed package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before uninstalling a package. If script exits with failure apk will not uninstall the package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after a package have been uninstalled. For example, can be used to restore busybox links:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
busybox --install -s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the package has a pre-install and post-install script the APKBUILD should have the &#039;&#039;install&#039;&#039; variable defined:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
install=&amp;quot;$pkgname.pre-install $pkgname.post-install&amp;quot;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== subpackages  ====&lt;br /&gt;
&lt;br /&gt;
$subpackages are made to split up the normal &amp;quot;make install&amp;quot; into separate packages. The most common subpackages we use are doc and dev. Because we like to keep our target system small we move documentation and development files (only needed when building packages) into separate packages. To use the specific program a user only need to install the base apk without package-doc or package-dev, but if he wants to read the manual he will need to install package-doc. &lt;br /&gt;
&lt;br /&gt;
The easiest way to find out if you need to use -dev and -doc is to first build the package without these options set and wait until the build finishes. When its finished you should have a pkg directory which is the fake root directory. Inside this directory you will see the structure as how it would be installed in / on the target system. &lt;br /&gt;
&lt;br /&gt;
To see if you need the -dev package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/ -name &#039;*.[acho]&#039; -o -name &#039;*.la&#039;}}&lt;br /&gt;
&lt;br /&gt;
If this returns any files you need to include the -dev package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; To see if you need the -doc package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/share -name doc -o -name man -o -name info -o -name html -o -name sgml -o -name licenses}}&lt;br /&gt;
&lt;br /&gt;
If this returns any directories you need to include the -doc package. &lt;br /&gt;
&lt;br /&gt;
===== Custom subpackages  =====&lt;br /&gt;
&lt;br /&gt;
Some software additionally has non-essential files that do not qualify as either documentation or development content. These files should be placed in their own, specialized subpackage(s). Some packages include large test suites which are only needed in specific circumstances or binaries which have depends which we prefer not to install. To handle those we create our own package/function. In the APKBUILD below the build() function we create another function: &lt;br /&gt;
&lt;br /&gt;
 test() {&lt;br /&gt;
        mkdir -p &amp;quot;$subpkgdir&amp;quot;/usr&lt;br /&gt;
        mv &amp;quot;$pkgdir&amp;quot;/usr/package-test &amp;quot;$subpkgdir&amp;quot;/usr/&lt;br /&gt;
        # or amove usr/package-test&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We also need to add the package info to $subpackages variable: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc $pkgname-dev $pkgname-test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
After we finish building the package you should see another apk called packagename-test.apk which includes the files which we moved to the $subpkgdir dir. &lt;br /&gt;
&lt;br /&gt;
The above mentioned variables can also be used in our custom function. If we want for instance to build the test() function with perl support we would add: &lt;br /&gt;
&lt;br /&gt;
 depends=&amp;quot;perl&amp;quot;&lt;br /&gt;
 makedepends=&amp;quot;perl-dev&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we would install the base package it would not install perl, but if we install the package-test package it would.&lt;br /&gt;
&lt;br /&gt;
==== Patches  ====&lt;br /&gt;
&lt;br /&gt;
Please make sure you always submit human readable patches. Ways to create them are: &lt;br /&gt;
&lt;br /&gt;
directory compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -Nurp original_directory new_directory &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
file compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -up original.file new.file &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
If a patch contains a completely new file but not *.rej or *.orig file, you need to add -N option to diff, but you may need to add exclusions with &amp;lt;code&amp;gt;--exclude PATTERN&amp;lt;/code&amp;gt; so that you do not inadvertently add files.  You may need to manually delete unwanted files inside the patch file.&lt;br /&gt;
&lt;br /&gt;
Because multiple patches can patch the same file, they can change the offsets required by subsequent patches. To make sure we always patch in a specific way, we should number the patches as follows: &lt;br /&gt;
&lt;br /&gt;
 10-patch1.patch 20-patch2.patch 30-patch3.patch&lt;br /&gt;
&lt;br /&gt;
This way we are always sure that patch 1 is applied first, and if we want to add additional patches between them we can use appropriate indexes (e.g. 11, 12, 21, 22).&lt;br /&gt;
&lt;br /&gt;
Add the names of the patch files to the &#039;&#039;source&#039;&#039; variable. If you haven&#039;t declared a custom &#039;&#039;prepare&#039;&#039; function, no further action is necessary. Otherwise, be sure to call &#039;&#039;default_prepare&#039;&#039; in your &#039;&#039;prepare&#039;&#039; function. For example:&lt;br /&gt;
&lt;br /&gt;
 prepare() {&lt;br /&gt;
 	default_prepare&lt;br /&gt;
 &lt;br /&gt;
 	# do your stuff&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Note: Some older packages contain a &#039;&#039;for&#039;&#039; loop in the &#039;&#039;prepare&#039;&#039; function to apply patches. This is not needed anymore, as patches are handled by &#039;&#039;default_prepare&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In Alpine &amp;gt;=3.4 you can define patch_args to supply the patch level.  This only works if all the patches have the same patch level.  If there are a lot of patches from different sources, there is a good chance that you may need to edit them, as discussed below.&lt;br /&gt;
&lt;br /&gt;
To automatically patch the package (available only in Alpine &amp;gt;=3.4) if it uses a patch level (-pX) other than the default (-p1), you need to carefully modify the patch.  First, you&#039;ll need a text editor that does not automatically convert  between Windows and Unix new lines (or, disable this feature) so that it preserves the old code.  The next thing you&#039;ll need to do is modify the paths on &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines in the .patch file.  You can begin the path with a/ and b/ like shown below.  Next, you need to adjust the paths so that the relative base path is from inside $builddir.  Anything to the left of $builddir, including $builddir itself, needs to be removed from the path.  So, if $builddir is /home/USER/aports/community/chromium/src/chromium-65, you need to erase it on the &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines.  Inside the chromium-65 folder you can see a src folder that has 3rdparty as a descendant.  If a patch originally has a deeper patch level, you may need to fill in the missing portion of the path.  For example, use the &amp;lt;code&amp;gt;find . -name &amp;quot;Assertions.cpp&amp;quot;&amp;lt;/code&amp;gt; command to find the full path to the file relative to the base.&lt;br /&gt;
&lt;br /&gt;
{{Cat|example.patch|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Author: John Doe &amp;lt;johndoe@mail.com&amp;gt;&lt;br /&gt;
URL: http://.....&lt;br /&gt;
Summary: Fixes musl compatibility&lt;br /&gt;
----&lt;br /&gt;
--- a/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp.orig&lt;br /&gt;
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp&lt;br /&gt;
@@ -142,7 +142,7 @@&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 FrameToNameScope::FrameToNameScope(void* addr) : m_name(0), m_cxaDemangled(0) {&lt;br /&gt;
-#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; !defined(__UCLIBC__))&lt;br /&gt;
+#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; defined(__GLIBC__))&lt;br /&gt;
   Dl_info info;&lt;br /&gt;
   if (!dladdr(addr, &amp;amp;info) || !info.dli_sname)&lt;br /&gt;
return;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Portions of the patch may be outdated, removed completely as in the source code file completely removed, or moved or renamed files.  You need to delete that section of the patch or find where that section of code changed and re-diff it.&lt;br /&gt;
&lt;br /&gt;
It is good etiquette to give credit at the top and the location of where you originally found them with notes.&lt;br /&gt;
&lt;br /&gt;
Excluding patches with global variable resembling patch_opts is not available on Alpine.  To exclude patches you need to create your own custom prepare().&lt;br /&gt;
&lt;br /&gt;
If you have a monolithic patch where there are a bunch of patches in one big patch, you could use filterdiff which is available in the patchutils package.&lt;br /&gt;
&lt;br /&gt;
Just do something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
makedepends=&amp;quot;patchutils&amp;quot;&lt;br /&gt;
&lt;br /&gt;
prepare() {&lt;br /&gt;
  ...&lt;br /&gt;
  cd &amp;quot;$builddir&amp;quot;&lt;br /&gt;
  filterdiff -x &#039;*drivers/video/logo*&#039; &amp;quot;$srcdir&amp;quot;/original.patch &amp;gt; &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
  patch -p1 -i &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to put the wildcard pattern in single quotes for it to work.&lt;br /&gt;
&lt;br /&gt;
==== Configure options  ====&lt;br /&gt;
&lt;br /&gt;
Alpine has some default configure options we set by default. We use /usr for prefix to make sure everything is installed with /usr in front of it. If you notice that anything is installed in the wrong directory please run {{Cmd|./configure --help}} and see if you can set the correct location. &lt;br /&gt;
&lt;br /&gt;
We are not covering the depend switches here we have discussed this already in the depend section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Make options  ====&lt;br /&gt;
&lt;br /&gt;
If you notice weird problems when compiling or installing the package with make/make install you could try to disable [https://www.gnu.org/software/make/manual/make.html#Parallel parallel] building/installing. A normal make line would be: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make}}&lt;br /&gt;
&lt;br /&gt;
To disable parallel we use: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make -j1}}&lt;br /&gt;
&lt;br /&gt;
We can use the same for make install. &lt;br /&gt;
&lt;br /&gt;
Because we do not want to install the package in our build environment but we want to install it in a fake root directory we need to tell &#039;make install&#039; to use another destination directory instead of &#039;/&#039;. We do this by setting a variable when we execute make install as followed: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make DESTDIR{{=}}&amp;quot;$pkgdir&amp;quot; install}}&lt;br /&gt;
&lt;br /&gt;
Please note that some Makefiles do not support this variable and will always install software in &#039;/&#039;. To make sure you do not mess up your build system NEVER run your build system as root but always use a custom user and doas when needed. If by accident the Makefile does not support DESTDIR variable it will fail to install in our build system system directories.&lt;br /&gt;
&lt;br /&gt;
==== builddir ====&lt;br /&gt;
If you used &amp;lt;tt&amp;gt;newapkbuild&amp;lt;/tt&amp;gt; to create your APKBUILD file, you must specify the path to your unpacked sources. Inside the sections during the prepare/build/install process &#039;&#039;builddir&#039;&#039; is used. Most of the time a combination of &#039;&#039;$srcdir&#039;&#039; and &#039;&#039;$pkgname-$pkgver&#039;&#039; will work. When not, check the /src directory or the source tarball for the right string. Especially when you are working with automatically generated tarballs (like from github and gitorious), this needs to be adjusted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
builddir=&amp;quot;$srcdir&amp;quot;/$pkgname-$pkgver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Additional files  ====&lt;br /&gt;
&lt;br /&gt;
If you want/need to install additional files not mentioned above you can use the following cmd (this is an example of a conf file): &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 doc/$pkgname.conf &amp;quot;$pkgdir&amp;quot;/etc/$pkgname.conf}}&lt;br /&gt;
&lt;br /&gt;
== Build the package  ==&lt;br /&gt;
&lt;br /&gt;
If you did not already create the checksums as mentioned above you can do so now: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $pkgname&lt;br /&gt;
abuild checksum}}&lt;br /&gt;
&lt;br /&gt;
It&#039;s about time we build our package. Because a build system should never have all the package installed to prevent linking to packages we don&#039;t want it to link we use a abuild recursively with the &#039;&#039;&#039;-r&#039;&#039;&#039; switch. It will install all dependencies from your repository and builds it, afterwards it will uninstall all those depending packages again.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -r}}&lt;br /&gt;
&lt;br /&gt;
See also [[Abuild_and_Helpers|Abuild and Helpers]].&lt;br /&gt;
&lt;br /&gt;
== Testing the package locally ==&lt;br /&gt;
&lt;br /&gt;
When it completes, your package will be found in a subfolder of &amp;lt;code&amp;gt;~/packages&amp;lt;/code&amp;gt;.  You may want to test it on your machine but only if the package is not a critical system package like musl or apk-tools package.  To avoid borking your system (as in making it impossible to use &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; or to restore back the system and the compiler toolchain) for a critical system package, you should test on a chroot first before using it live.&lt;br /&gt;
&lt;br /&gt;
The best way to test a package locally is to modify your &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; so that it includes the indexes to your locally built packages - the directories that contain &amp;lt;code&amp;gt;ARCH/APKINDEX.tar.gz&amp;lt;/code&amp;gt;. For example the &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; below includes locally built packages in testing, community and main. To use this example change &amp;lt;code&amp;gt;USER&amp;lt;/code&amp;gt; to your login name.&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/apk/repositories|/home/USER/packages/testing/&lt;br /&gt;
/home/USER/packages/main/&lt;br /&gt;
/home/USER/packages/community/&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you prefer to test a package without changing any other configuration you can use the &amp;lt;code&amp;gt;-X, --repository&amp;lt;/code&amp;gt; option to &amp;lt;code&amp;gt;apk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|doas apk add --repository /home/USER/packages/testing $pkgname}}&lt;br /&gt;
&lt;br /&gt;
== Code review ==&lt;br /&gt;
&lt;br /&gt;
To successfully have your package pass through code reviewers (as of Feb 18, 2018 are nmeum and jirutka on GitHub) and possible increased acceptance, the following conventions need to be followed:&lt;br /&gt;
&lt;br /&gt;
# Custom global variables should be prefixed with underscore (_).&lt;br /&gt;
# Compact code as in merged commands, removed unused variables, removal of functions that do the same thing that are automatically handled by abuild.&lt;br /&gt;
# Versioning is done properly.  For details see [[APKBUILD_Reference#pkgver]].&lt;br /&gt;
# Licensing is done properly. Remove unnecessary copying of licensing that is already OSI approved.&lt;br /&gt;
# Naming conventions rules for unofficial variables as in _gitrev is preferred over commit.&lt;br /&gt;
# Indent with tabs not spaces.&lt;br /&gt;
# Removal of explicit return 1.  (They are still found the old APKBUILD files if you are learning but are now strongly discouraged.)&lt;br /&gt;
# Disabling check() requires either (1) a comment (#) stating next to options=&amp;quot;!check&amp;quot; that there is no test suite/unit tests or (2) functioning working check() function.&lt;br /&gt;
# Explicit call to subpackages=&amp;quot;$pkgname-doc&amp;quot; must be used instead of explicit gzip man page compression.&lt;br /&gt;
# Ideally, lines should be no more than 80 columns wide&lt;br /&gt;
&lt;br /&gt;
Additionally, make sure to run the linter on your package:&lt;br /&gt;
{{Cmd|doas apk add atools&lt;br /&gt;
apkbuild-lint APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
For more information see [[Development using git:Quality assurance]] and [[Package_policies]].&lt;br /&gt;
Also check out [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/COMMITSTYLE.md?ref_type=heads aports/COMMITSTYLE.md] and [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/CODINGSTYLE.md?ref_type=heads aports/CODINGSTYLE.md]&lt;br /&gt;
&lt;br /&gt;
== Commit your work  ==&lt;br /&gt;
&lt;br /&gt;
After you successfully build your package and properly followed the conventions and requirements in the code review section, you can submit your APKBUILD to Alpine&#039;s git repository. &lt;br /&gt;
&lt;br /&gt;
Update your git repo, before adding new files: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git pull}}&lt;br /&gt;
&lt;br /&gt;
This should pull all the changes made by others into your local git repo.&lt;br /&gt;
&lt;br /&gt;
When you think you are ready you can add your files to git: &lt;br /&gt;
&lt;br /&gt;
NOTE: when using our Gitlab instance, you can create MR&#039;s for each package. Please squash all commits related to the same package into a single one per MR.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git add testing/$pkgdir (include any other files needed for the build; $pkgname.install...)&lt;br /&gt;
git commit}}&lt;br /&gt;
&lt;br /&gt;
Use the following commit message template for new aports (without the comments):&lt;br /&gt;
&lt;br /&gt;
{{Cat|template|testing/$pkgname: new aport   # this will be the subject line&lt;br /&gt;
                              # a blank line&lt;br /&gt;
$url                          # project homepage&lt;br /&gt;
$pkgdesc                      # one line description}}&lt;br /&gt;
&lt;br /&gt;
Or you could add the following and &amp;lt;code&amp;gt;chmod +x ports/.git/hooks/prepare-commit-msg&amp;lt;/code&amp;gt; to automatically generate commit message which the default aports/.githooks/ does not:&lt;br /&gt;
&lt;br /&gt;
{{Cat|aports/.git/hooks/prepare-commit-msg|&amp;lt;nowiki&amp;gt;#!/bin/sh&lt;br /&gt;
case &amp;quot;$2,$3&amp;quot; in&lt;br /&gt;
  ,|template,)&lt;br /&gt;
    if git diff-index --diff-filter=A --name-only --cached HEAD \&lt;br /&gt;
        | grep -q &#039;/APKBUILD$&#039;; then&lt;br /&gt;
      meta() { git diff --staged | grep &amp;quot;^+$1&amp;quot; | sed &#039;s/.*=&amp;quot;\?//;s/&amp;quot;$//&#039;;}&lt;br /&gt;
      printf &#039;testing/%s: new aport\n\n%s\n%s\n&#039; &amp;quot;$(meta pkgname)&amp;quot; \&lt;br /&gt;
        &amp;quot;$(meta url)&amp;quot; &amp;quot;$(meta pkgdesc)&amp;quot; &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      printf &#039;%s\n\n%s&#039; `git diff-index --name-only --cached HEAD \&lt;br /&gt;
        | sed -n &#039;s/\/APKBUILD$//p;q&#039;` &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    fi;;&lt;br /&gt;
esac&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Now your changes are only available locally in your repository.&lt;br /&gt;
&lt;br /&gt;
Because you do not have push rights to the Alpine aports repository you need to create a merge request to [https://gitlab.alpinelinux.org/alpine/aports Alpine&#039;s GitLab instance].&lt;br /&gt;
&lt;br /&gt;
Alternatively you can also create a diff (patch) of the changes you made and send this patch to the &lt;br /&gt;
[https://lists.alpinelinux.org/~alpine/aports  alpine-aports mailinglist].&lt;br /&gt;
&lt;br /&gt;
To create a diff patch:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^}}&lt;br /&gt;
&lt;br /&gt;
or if you have sprunge, you can create a link to your patch for convenience&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^ --stdout &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; sprunge}}&lt;br /&gt;
&lt;br /&gt;
== Automated flagging of outdated ports ==&lt;br /&gt;
Consider adding your port to [https://release-monitoring.org/ Anitya], so it will be flagged as outdated&lt;br /&gt;
as soon as a new stable version is released by upstream.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[APKBUILD Reference]]&lt;br /&gt;
* [[APKBUILD examples]]&lt;br /&gt;
* [[Development using git]]&lt;br /&gt;
* [[Development using git:Quality assurance]]&lt;br /&gt;
&lt;br /&gt;
[[category: Package Manager]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26374</id>
		<title>Creating an Alpine package</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Creating_an_Alpine_package&amp;diff=26374"/>
		<updated>2024-02-11T23:37:38Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: Added a Quickstart/Overview.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
This is a brief list of the steps to add a new package. Details are below, but a NB can miss a few steps.&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Create an account on github.alpine&lt;br /&gt;
&amp;lt;li&amp;gt;Fork the aports repository. &lt;br /&gt;
&amp;lt;li&amp;gt;Clone your new fork.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a new branch (don&#039;t use master).&lt;br /&gt;
&amp;lt;li&amp;gt;Add a new directory under testing that is your new package name.&lt;br /&gt;
&amp;lt;li&amp;gt;Add your APKBUILD file.&lt;br /&gt;
&amp;lt;li&amp;gt;Run aport makesum&lt;br /&gt;
&amp;lt;li&amp;gt;Make sure you run the apklint and aport -r and there are no warnings.&lt;br /&gt;
&amp;lt;li&amp;gt;Commit your APKBUILD with the commit message: &#039;testing/packagename: new aport&#039;&lt;br /&gt;
&amp;lt;li&amp;gt;Push your changes to github.alpine.&lt;br /&gt;
&amp;lt;li&amp;gt;Create a merge request.&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please see the rest of this wiki for details on the steps above.&lt;br /&gt;
&lt;br /&gt;
== Requirements ==&lt;br /&gt;
&lt;br /&gt;
To build a package for Alpine Linux you need an Alpine Linux installation. Check the [[Installation]] page to see all available installation options.&lt;br /&gt;
&lt;br /&gt;
== Setup your system and account  ==&lt;br /&gt;
{{:Setup_your_system_and_account_for_building_packages}}&lt;br /&gt;
&lt;br /&gt;
== Getting some help ==&lt;br /&gt;
&lt;br /&gt;
It might be wise to start by checking what the [[Abuild and Helpers|abuild]] program can/cannot do.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -h}}&lt;br /&gt;
&lt;br /&gt;
For real help, you can also go on #alpine-devel on [[IRC]].&lt;br /&gt;
&lt;br /&gt;
A reference for APKBUILD files is available as [[APKBUILD Reference]] wiki page or a man page in the &#039;abuild-doc&#039; package:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|man APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Creating an APKBUILD file  ==&lt;br /&gt;
&lt;br /&gt;
=== Use a template APKBUILD ===&lt;br /&gt;
&lt;br /&gt;
To create the actual APKBUILD file {{Pkg|newapkbuild}} can serve you a template to start with. It will create a directory with the given package name, place an example/template APKBUILD file to the given directory, and fill some variables if those are provided. Please check the [[Package_policies| package policies]] page about naming details.&lt;br /&gt;
&lt;br /&gt;
If you doubt to which repository your package belongs to you can safely use &#039;&#039;&#039;testing&#039;&#039;&#039;. Building package in your aports/testing directory is not mandatory but this way the package is already at the right place.&lt;br /&gt;
&lt;br /&gt;
{{:Abuild and Helpers}}&lt;br /&gt;
&lt;br /&gt;
{{Note|On older Alpine systems, abuild -c -n &#039;&#039;packagename&#039;&#039; was the way to create APKBUILD files. The &#039;packagename&#039; was a parameter to the -n option so order of -c and -n matters. }}&lt;br /&gt;
&lt;br /&gt;
[[Abuild_and_Helpers#apkbuild-cpan|apkbuild-cpan]] simplifies the creation of perl packages from CPAN and [[Abuild_and_Helpers#apkbuild-pypi|apkbuild-pypi]] ease the generation of APKBUILD files for python packages from PyPi.  &lt;br /&gt;
&lt;br /&gt;
If you are creating a daemon package which needs initd scripts you can add the -c making it: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|newapkbuild -c &#039;&#039;packagename&#039;&#039;}}&lt;br /&gt;
&lt;br /&gt;
This will copy the sample initd and confd files to the build directory.&amp;lt;BR&amp;gt;&lt;br /&gt;
A third file sample.install file will be copied as well (we will discuss this later on).&lt;br /&gt;
&lt;br /&gt;
=== Modify your APKBUILD ===&lt;br /&gt;
Edit APKBUILD and fill in the needed info (especially pkgname, pkgver, pkgdesc, url, license, depends and source). &lt;br /&gt;
&lt;br /&gt;
If you are going to use any of the variables for directories like $pkgdir, always make sure they are double quoted like: &lt;br /&gt;
&lt;br /&gt;
 &amp;quot;$pkgdir&amp;quot;/somedir&lt;br /&gt;
&lt;br /&gt;
This will prevent issues with spaces/special characters in the future. &lt;br /&gt;
&lt;br /&gt;
{{Note|If you like syntax highlighting we suggest you to install vim. We have setup vim to recognize the APKBUILD file as a bash scripts so its easier to read them.}}&lt;br /&gt;
&lt;br /&gt;
=== APKBUILD variables/functions  ===&lt;br /&gt;
&lt;br /&gt;
==== source  ====&lt;br /&gt;
&lt;br /&gt;
The source variable is not only used to list the remote source files to fetch, it is also used to list the local files that abuild will need in order to build the apk. Examples of such local files include: init.d files, conf.d files, install files (see [[Creating an Alpine package#install|install variable]]), patches, and all other necessary files.&lt;br /&gt;
&lt;br /&gt;
Here are few things to note:&lt;br /&gt;
&lt;br /&gt;
* When you are finished adding local and/or remote files to &#039;&#039;source&#039;&#039;, you can execute the following command to add their checksums to the APKBUILD file:&lt;br /&gt;
: {{cmd|abuild checksum}}&lt;br /&gt;
: {{Note|When later updating the content of &#039;&#039;source&#039;&#039;, or updating a file that is listed in &#039;&#039;source&#039;&#039;, you must also update their checksums again with the same command.}}&lt;br /&gt;
&lt;br /&gt;
* When the remote file is hosted at SourceForge, it&#039;s best to specify the special mirrors link used by SourceForge:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://downloads.sourceforge.net/$pkgname/$pkgname-$pkgver.tar.gz&amp;lt;/pre&amp;gt;&lt;br /&gt;
: (or similar depending on the package).&lt;br /&gt;
&lt;br /&gt;
* When the remote filename is not specified in the URI (ie, does not end in &#039;/software-1.0.tar.gz&#039;), such as:&lt;br /&gt;
: &amp;lt;pre&amp;gt;http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;lt;/pre&amp;gt;&lt;br /&gt;
: You must prepend &#039;${pkgname}-${pkgver}.tar.gz::&#039; to the protocol, like so:&lt;br /&gt;
: &amp;lt;pre&amp;gt;source=&amp;quot;${pkgname}-${pkgver}.tar.gz::http://oss.example.org/?get=software&amp;amp;ver=1.0&amp;quot;&amp;lt;/pre&amp;gt;&lt;br /&gt;
: This causes the file to be saved as &#039;&#039;software-1.0.tar.gz&#039;&#039; where abuild can use it, instead of &#039;&#039;?get=software&amp;amp;ver=1.0&#039;&#039;, where abuild cannot use it.&lt;br /&gt;
&lt;br /&gt;
* Some projects didn&#039;t provide a release tarball. Beware that some git services (gitweg, cgit, …?) doesn’t provide &#039;&#039;stable&#039;&#039; tarballs, so when you point source to an tarball like &amp;lt;tt&amp;gt;https://repo.or.cz/w/gitstats.git/snapshot/ad7efbb9399e60cee6cb217c6b47e604174a8093.tar.gz&amp;lt;/tt&amp;gt;, then you will run into issues because the checksum changes when downloading on the build system. This is not a problem on GitHub, GitLab and other decent services provides, they provide &#039;&#039;stable&#039;&#039; tarballs.&lt;br /&gt;
&lt;br /&gt;
* abuild currently supports the following protocols for remote file retrieval:&lt;br /&gt;
** http&lt;br /&gt;
** https&lt;br /&gt;
** ftp&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--: {{Note|If the you want to download from https, you need GNU wget installed on your system.}}--&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
* abuild currently supports the following archive types/archive file extensions:&lt;br /&gt;
** .tar&lt;br /&gt;
** .tar.gz / .tgz&lt;br /&gt;
** .tar.bz2&lt;br /&gt;
** .tar.lz (only in Alpine &amp;gt;=3.7)&lt;br /&gt;
** .tar.lzma&lt;br /&gt;
** .tar.xz&lt;br /&gt;
** .zip&lt;br /&gt;
&lt;br /&gt;
==== depends &amp;amp;amp; makedepends  ====&lt;br /&gt;
&lt;br /&gt;
Depends are the actual running dependencies that a package would need when it is running. Makedepends are only needed when you are building a package. If you set a package in depends, you do not need to add it to makedepends as well. The best way to find out what the depends and makedepends of a package are is to [https://en.wikipedia.org/wiki/Rtfm RTFM]. &lt;br /&gt;
&lt;br /&gt;
No kidding, lots of important information can be found in the package INSTALL and README files (or the likes). Another good way is the run &amp;lt;code&amp;gt;./configure --help&amp;lt;/code&amp;gt; from the source directory to see which options are needed for configure to finish without errors. If you do not yet have a source directory you can create one with the command: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild unpack}}&lt;br /&gt;
&lt;br /&gt;
Running &amp;lt;code&amp;gt;configure&amp;lt;/code&amp;gt; will also show you how you can disable a specific option for this package. For instance, a good example is &amp;quot;--disable-nls&amp;quot; which will disable native language support and thus does not depend on gettext (libiconv, glib, ...). &lt;br /&gt;
&lt;br /&gt;
Alpine likes to keep things small, so we try to disable as much as possible without losing too many features. The exact disable/enable options are decided by the package builder but please try to follow Alpine&#039;s design concept as much as possible.&lt;br /&gt;
&lt;br /&gt;
An easy way of quickly finding out the build info for a package is to check Arch Linux (Alpine package management and build scripts are similar) or Gentoo Linux ebuilds (previous versions of Alpine were based on Gentoo).&lt;br /&gt;
&lt;br /&gt;
* [https://gitweb.gentoo.org/repo/gentoo.git/tree/ Gentoo Ebuilds] &lt;br /&gt;
* [https://archlinux.org/packages/?q=search Arch Linux packages] [https://aur.archlinux.org/ Arch Linux User Repository]&lt;br /&gt;
&lt;br /&gt;
==== license  ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;license&#039;&#039;&#039; tag must reflect the license of the source code. Please check the source tarball for COPYING, LICENSE, or other files with names that indicates that it contains licensing information. Beside the license file most developer include headers in the source code files with licensing details.&lt;br /&gt;
&lt;br /&gt;
If the license is on the [https://spdx.org/licenses/ SPDX License List] or [https://spdx.org/licenses/exceptions-index.html SPDX License Exceptions], use the identifier specified by SPDX.&lt;br /&gt;
&lt;br /&gt;
Note that some licenses have additional requirements that should be adhered to. The &amp;lt;code&amp;gt;MIT&amp;lt;/code&amp;gt; license for example has the requirement:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This means that we need to include the license as shipped with the project.&lt;br /&gt;
&lt;br /&gt;
If a package has a special/custom license or is not listed as [https://opensource.org/licenses/alphabetical OSI approved], use the identifier &amp;quot;custom&amp;quot;. In that case we need to provide the license file with the package as well.&lt;br /&gt;
&lt;br /&gt;
Because we want to save space and don&#039;t like to have licenses all over our system we have decided to include the license in the doc subpackage. Please follow the following guidelines to add a proper license. Locate the license file inside the source package. Add the doc subpackage to the $subpackages variable as follows: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Add a similar line to the following to your package() function, depending on the license description file: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 COPYING &amp;quot;$pkgdir&amp;quot;/usr/share/licenses/$pkgname/COPYING}}&lt;br /&gt;
&lt;br /&gt;
If you follow these steps then abuild will automatically add the license to the package-doc apk for you.&lt;br /&gt;
&lt;br /&gt;
{{Warning|It is not acceptable to package software with &amp;quot;unknown&amp;quot; license! If you can&#039;t find the license of the source code, please contact the author and ask them to specify the license. }}&lt;br /&gt;
&lt;br /&gt;
==== arch ====&lt;br /&gt;
&lt;br /&gt;
The package architecture(s) to build for.  This can be one of: &#039;&#039;x86, x86_64, all,&#039;&#039; or &#039;&#039;noarch&#039;&#039;, where &#039;&#039;all&#039;&#039; means all architectures, and &#039;&#039;noarch&#039;&#039; means it&#039;s architecture-independent (e.g., a pure-python package).&lt;br /&gt;
{{Tip|To determine if your APKBUILD can use &#039;&#039;noarch&#039;&#039;, build the package for your architecture and then run &amp;quot;scanelf -R pkg&amp;quot; from the directory that the APKBUILD resides in, in order to scan for ELF files in the &#039;&#039;./pkg&#039;&#039; directory.  If you do NOT get output from this, then &#039;&#039;noarch&#039;&#039; can be used.}}&lt;br /&gt;
&lt;br /&gt;
==== url  ====&lt;br /&gt;
&lt;br /&gt;
Website address for the program. This is useful later on when either finding documentation or other information about the package.&lt;br /&gt;
&lt;br /&gt;
==== pkgdesc  ====&lt;br /&gt;
&lt;br /&gt;
A brief, one line, description of what the package does. Useful for the package management system. It should start with a capital letter and does &#039;&#039;&#039;not&#039;&#039;&#039; end with a period.&lt;br /&gt;
&lt;br /&gt;
Here is an example from apk_info for the OpenSSH client package:&lt;br /&gt;
&lt;br /&gt;
 pkgdesc=&amp;quot;Port of OpenBSD&#039;s free SSH release - client&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== pkgver  ====&lt;br /&gt;
&lt;br /&gt;
Provide the release number of the package you are building.&lt;br /&gt;
&lt;br /&gt;
==== pkgrel  ====&lt;br /&gt;
&lt;br /&gt;
The $pkgrel versioning is made so that if you change something in your APKBUILD file without changing the actual $pkgver, you can increment pkgrel so apk tools will detect it as an update. For instance, if you forget to add a dependency, you can add it afterward and you can +1 pkgver so apk finds this update and adds the missing dependency. When there&#039;s an upstream version change, we reset the pkgrel to 0.&lt;br /&gt;
&lt;br /&gt;
==== pkgname  ====&lt;br /&gt;
&lt;br /&gt;
The base name of the package you are creating.  For Freeswitch 1.0.6, you would use &amp;quot;freeswitch&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== install  ====&lt;br /&gt;
&lt;br /&gt;
There are 6 different kinds of install scripts. Each script is called with the $pkgname.&#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; where &#039;&#039;&amp;lt;action&amp;gt;&#039;&#039; is one of the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dl&amp;gt;&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before package is installed. Typical use is when package needs a group and a user to be created. For example:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
addgroup -S clamav 2&amp;gt;/dev/null&lt;br /&gt;
adduser -S -D -H -s /bin/false -G clamav -g clamav clamav 2&amp;gt;/dev/null&lt;br /&gt;
&lt;br /&gt;
exit 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note the &#039;&#039;exit 0&#039;&#039; at the end. If the script exits with failure (if the user already exist), the package will not be installed and &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; will exit with failure.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-install&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after the package is installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as pre-install but is executed before upgrading/downgrading/reinstalling an already installed package. Note that exiting with failure will not cause apk to exit with failure, but will mark the package as broken.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-upgrade&lt;br /&gt;
&amp;lt;dd&amp;gt;Same as post-install but is executed after upgrading/downgrading/reinstalling an already installed package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.pre-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed before uninstalling a package. If script exits with failure apk will not uninstall the package.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;dt&amp;gt;$pkgname.post-deinstall&lt;br /&gt;
&amp;lt;dd&amp;gt;This script is executed after a package have been uninstalled. For example, can be used to restore busybox links:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
busybox --install -s&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/dl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the package has a pre-install and post-install script the APKBUILD should have the &#039;&#039;install&#039;&#039; variable defined:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
install=&amp;quot;$pkgname.pre-install $pkgname.post-install&amp;quot;&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== subpackages  ====&lt;br /&gt;
&lt;br /&gt;
$subpackages are made to split up the normal &amp;quot;make install&amp;quot; into separate packages. The most common subpackages we use are doc and dev. Because we like to keep our target system small we move documentation and development files (only needed when building packages) into separate packages. To use the specific program a user only need to install the base apk without package-doc or package-dev, but if he wants to read the manual he will need to install package-doc. &lt;br /&gt;
&lt;br /&gt;
The easiest way to find out if you need to use -dev and -doc is to first build the package without these options set and wait until the build finishes. When its finished you should have a pkg directory which is the fake root directory. Inside this directory you will see the structure as how it would be installed in / on the target system. &lt;br /&gt;
&lt;br /&gt;
To see if you need the -dev package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/ -name &#039;*.[acho]&#039; -o -name &#039;*.la&#039;}}&lt;br /&gt;
&lt;br /&gt;
If this returns any files you need to include the -dev package. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; To see if you need the -doc package you can run the following cmd: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|find pkg/usr/share -name doc -o -name man -o -name info -o -name html -o -name sgml -o -name licenses}}&lt;br /&gt;
&lt;br /&gt;
If this returns any directories you need to include the -doc package. &lt;br /&gt;
&lt;br /&gt;
===== Custom subpackages  =====&lt;br /&gt;
&lt;br /&gt;
Some software additionally has non-essential files that do not qualify as either documentation or development content. These files should be placed in their own, specialized subpackage(s). Some packages include large test suites which are only needed in specific circumstances or binaries which have depends which we prefer not to install. To handle those we create our own package/function. In the APKBUILD below the build() function we create another function: &lt;br /&gt;
&lt;br /&gt;
 test() {&lt;br /&gt;
        mkdir -p &amp;quot;$subpkgdir&amp;quot;/usr&lt;br /&gt;
        mv &amp;quot;$pkgdir&amp;quot;/usr/package-test &amp;quot;$subpkgdir&amp;quot;/usr/&lt;br /&gt;
        # or amove usr/package-test&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
We also need to add the package info to $subpackages variable: &lt;br /&gt;
&lt;br /&gt;
 subpackages=&amp;quot;$pkgname-doc $pkgname-dev $pkgname-test&amp;quot;&lt;br /&gt;
&lt;br /&gt;
After we finish building the package you should see another apk called packagename-test.apk which includes the files which we moved to the $subpkgdir dir. &lt;br /&gt;
&lt;br /&gt;
The above mentioned variables can also be used in our custom function. If we want for instance to build the test() function with perl support we would add: &lt;br /&gt;
&lt;br /&gt;
 depends=&amp;quot;perl&amp;quot;&lt;br /&gt;
 makedepends=&amp;quot;perl-dev&amp;quot;&lt;br /&gt;
&lt;br /&gt;
If we would install the base package it would not install perl, but if we install the package-test package it would.&lt;br /&gt;
&lt;br /&gt;
==== Patches  ====&lt;br /&gt;
&lt;br /&gt;
Please make sure you always submit human readable patches. Ways to create them are: &lt;br /&gt;
&lt;br /&gt;
directory compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -Nurp original_directory new_directory &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
file compare: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|diff -up original.file new.file &amp;amp;gt; filename.patch}}&lt;br /&gt;
&lt;br /&gt;
If a patch contains a completely new file but not *.rej or *.orig file, you need to add -N option to diff, but you may need to add exclusions with &amp;lt;code&amp;gt;--exclude PATTERN&amp;lt;/code&amp;gt; so that you do not inadvertently add files.  You may need to manually delete unwanted files inside the patch file.&lt;br /&gt;
&lt;br /&gt;
Because multiple patches can patch the same file, they can change the offsets required by subsequent patches. To make sure we always patch in a specific way, we should number the patches as follows: &lt;br /&gt;
&lt;br /&gt;
 10-patch1.patch 20-patch2.patch 30-patch3.patch&lt;br /&gt;
&lt;br /&gt;
This way we are always sure that patch 1 is applied first, and if we want to add additional patches between them we can use appropriate indexes (e.g. 11, 12, 21, 22).&lt;br /&gt;
&lt;br /&gt;
Add the names of the patch files to the &#039;&#039;source&#039;&#039; variable. If you haven&#039;t declared a custom &#039;&#039;prepare&#039;&#039; function, no further action is necessary. Otherwise, be sure to call &#039;&#039;default_prepare&#039;&#039; in your &#039;&#039;prepare&#039;&#039; function. For example:&lt;br /&gt;
&lt;br /&gt;
 prepare() {&lt;br /&gt;
 	default_prepare&lt;br /&gt;
 &lt;br /&gt;
 	# do your stuff&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Note: Some older packages contain a &#039;&#039;for&#039;&#039; loop in the &#039;&#039;prepare&#039;&#039; function to apply patches. This is not needed anymore, as patches are handled by &#039;&#039;default_prepare&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In Alpine &amp;gt;=3.4 you can define patch_args to supply the patch level.  This only works if all the patches have the same patch level.  If there are a lot of patches from different sources, there is a good chance that you may need to edit them, as discussed below.&lt;br /&gt;
&lt;br /&gt;
To automatically patch the package (available only in Alpine &amp;gt;=3.4) if it uses a patch level (-pX) other than the default (-p1), you need to carefully modify the patch.  First, you&#039;ll need a text editor that does not automatically convert  between Windows and Unix new lines (or, disable this feature) so that it preserves the old code.  The next thing you&#039;ll need to do is modify the paths on &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines in the .patch file.  You can begin the path with a/ and b/ like shown below.  Next, you need to adjust the paths so that the relative base path is from inside $builddir.  Anything to the left of $builddir, including $builddir itself, needs to be removed from the path.  So, if $builddir is /home/USER/aports/community/chromium/src/chromium-65, you need to erase it on the &amp;quot;+++&amp;quot; and &amp;quot;---&amp;quot; lines.  Inside the chromium-65 folder you can see a src folder that has 3rdparty as a descendant.  If a patch originally has a deeper patch level, you may need to fill in the missing portion of the path.  For example, use the &amp;lt;code&amp;gt;find . -name &amp;quot;Assertions.cpp&amp;quot;&amp;lt;/code&amp;gt; command to find the full path to the file relative to the base.&lt;br /&gt;
&lt;br /&gt;
{{Cat|example.patch|&amp;lt;nowiki&amp;gt;&lt;br /&gt;
Author: John Doe &amp;lt;johndoe@mail.com&amp;gt;&lt;br /&gt;
URL: http://.....&lt;br /&gt;
Summary: Fixes musl compatibility&lt;br /&gt;
----&lt;br /&gt;
--- a/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp.orig&lt;br /&gt;
+++ b/src/3rdparty/chromium/third_party/WebKit/Source/wtf/Assertions.cpp&lt;br /&gt;
@@ -142,7 +142,7 @@&lt;br /&gt;
 };&lt;br /&gt;
 &lt;br /&gt;
 FrameToNameScope::FrameToNameScope(void* addr) : m_name(0), m_cxaDemangled(0) {&lt;br /&gt;
-#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; !defined(__UCLIBC__))&lt;br /&gt;
+#if OS(MACOSX) || (OS(LINUX) &amp;amp;&amp;amp; defined(__GLIBC__))&lt;br /&gt;
   Dl_info info;&lt;br /&gt;
   if (!dladdr(addr, &amp;amp;info) || !info.dli_sname)&lt;br /&gt;
return;&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Portions of the patch may be outdated, removed completely as in the source code file completely removed, or moved or renamed files.  You need to delete that section of the patch or find where that section of code changed and re-diff it.&lt;br /&gt;
&lt;br /&gt;
It is good etiquette to give credit at the top and the location of where you originally found them with notes.&lt;br /&gt;
&lt;br /&gt;
Excluding patches with global variable resembling patch_opts is not available on Alpine.  To exclude patches you need to create your own custom prepare().&lt;br /&gt;
&lt;br /&gt;
If you have a monolithic patch where there are a bunch of patches in one big patch, you could use filterdiff which is available in the patchutils package.&lt;br /&gt;
&lt;br /&gt;
Just do something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
makedepends=&amp;quot;patchutils&amp;quot;&lt;br /&gt;
&lt;br /&gt;
prepare() {&lt;br /&gt;
  ...&lt;br /&gt;
  cd &amp;quot;$builddir&amp;quot;&lt;br /&gt;
  filterdiff -x &#039;*drivers/video/logo*&#039; &amp;quot;$srcdir&amp;quot;/original.patch &amp;gt; &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
  patch -p1 -i &amp;quot;$builddir&amp;quot;/modified.patch&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You need to put the wildcard pattern in single quotes for it to work.&lt;br /&gt;
&lt;br /&gt;
==== Configure options  ====&lt;br /&gt;
&lt;br /&gt;
Alpine has some default configure options we set by default. We use /usr for prefix to make sure everything is installed with /usr in front of it. If you notice that anything is installed in the wrong directory please run {{Cmd|./configure --help}} and see if you can set the correct location. &lt;br /&gt;
&lt;br /&gt;
We are not covering the depend switches here we have discussed this already in the depend section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Make options  ====&lt;br /&gt;
&lt;br /&gt;
If you notice weird problems when compiling or installing the package with make/make install you could try to disable [https://www.gnu.org/software/make/manual/make.html#Parallel parallel] building/installing. A normal make line would be: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make}}&lt;br /&gt;
&lt;br /&gt;
To disable parallel we use: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make -j1}}&lt;br /&gt;
&lt;br /&gt;
We can use the same for make install. &lt;br /&gt;
&lt;br /&gt;
Because we do not want to install the package in our build environment but we want to install it in a fake root directory we need to tell &#039;make install&#039; to use another destination directory instead of &#039;/&#039;. We do this by setting a variable when we execute make install as followed: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|make DESTDIR{{=}}&amp;quot;$pkgdir&amp;quot; install}}&lt;br /&gt;
&lt;br /&gt;
Please note that some Makefiles do not support this variable and will always install software in &#039;/&#039;. To make sure you do not mess up your build system NEVER run your build system as root but always use a custom user and doas when needed. If by accident the Makefile does not support DESTDIR variable it will fail to install in our build system system directories.&lt;br /&gt;
&lt;br /&gt;
==== builddir ====&lt;br /&gt;
If you used &amp;lt;tt&amp;gt;newapkbuild&amp;lt;/tt&amp;gt; to create your APKBUILD file, you must specify the path to your unpacked sources. Inside the sections during the prepare/build/install process &#039;&#039;builddir&#039;&#039; is used. Most of the time a combination of &#039;&#039;$srcdir&#039;&#039; and &#039;&#039;$pkgname-$pkgver&#039;&#039; will work. When not, check the /src directory or the source tarball for the right string. Especially when you are working with automatically generated tarballs (like from github and gitorious), this needs to be adjusted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
builddir=&amp;quot;$srcdir&amp;quot;/$pkgname-$pkgver&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Additional files  ====&lt;br /&gt;
&lt;br /&gt;
If you want/need to install additional files not mentioned above you can use the following cmd (this is an example of a conf file): &lt;br /&gt;
&lt;br /&gt;
{{Cmd|install -Dm644 doc/$pkgname.conf &amp;quot;$pkgdir&amp;quot;/etc/$pkgname.conf}}&lt;br /&gt;
&lt;br /&gt;
== Build the package  ==&lt;br /&gt;
&lt;br /&gt;
If you did not already create the checksums as mentioned above you can do so now: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $pkgname&lt;br /&gt;
abuild checksum}}&lt;br /&gt;
&lt;br /&gt;
It&#039;s about time we build our package. Because a build system should never have all the package installed to prevent linking to packages we don&#039;t want it to link we use a abuild recursively with the &#039;&#039;&#039;-r&#039;&#039;&#039; switch. It will install all dependencies from your repository and builds it, afterwards it will uninstall all those depending packages again.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|abuild -r}}&lt;br /&gt;
&lt;br /&gt;
See also [[Abuild_and_Helpers|Abuild and Helpers]].&lt;br /&gt;
&lt;br /&gt;
== Testing the package locally ==&lt;br /&gt;
&lt;br /&gt;
When it completes, your package will be found in a subfolder of &amp;lt;code&amp;gt;~/packages&amp;lt;/code&amp;gt;.  You may want to test it on your machine but only if the package is not a critical system package like musl or apk-tools package.  To avoid borking your system (as in making it impossible to use &amp;lt;code&amp;gt;apk add&amp;lt;/code&amp;gt; or to restore back the system and the compiler toolchain) for a critical system package, you should test on a chroot first before using it live.&lt;br /&gt;
&lt;br /&gt;
The best way to test a package locally is to modify your &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; so that it includes the indexes to your locally built packages - the directories that contain &amp;lt;code&amp;gt;ARCH/APKINDEX.tar.gz&amp;lt;/code&amp;gt;. For example the &amp;lt;code&amp;gt;/etc/apk/repositories&amp;lt;/code&amp;gt; below includes locally built packages in testing, community and main. To use this example change &amp;lt;code&amp;gt;USER&amp;lt;/code&amp;gt; to your login name.&lt;br /&gt;
&lt;br /&gt;
{{Cat|/etc/apk/repositories|/home/USER/packages/testing/&lt;br /&gt;
/home/USER/packages/main/&lt;br /&gt;
/home/USER/packages/community/&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/main&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/community&lt;br /&gt;
https://dl-cdn.alpinelinux.org/alpine/edge/testing&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
If you prefer to test a package without changing any other configuration you can use the &amp;lt;code&amp;gt;-X, --repository&amp;lt;/code&amp;gt; option to &amp;lt;code&amp;gt;apk&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|doas apk add --repository /home/USER/packages/testing $pkgname}}&lt;br /&gt;
&lt;br /&gt;
== Code review ==&lt;br /&gt;
&lt;br /&gt;
To successfully have your package pass through code reviewers (as of Feb 18, 2018 are nmeum and jirutka on GitHub) and possible increased acceptance, the following conventions need to be followed:&lt;br /&gt;
&lt;br /&gt;
# Custom global variables should be prefixed with underscore (_).&lt;br /&gt;
# Compact code as in merged commands, removed unused variables, removal of functions that do the same thing that are automatically handled by abuild.&lt;br /&gt;
# Versioning is done properly.  For details see [[APKBUILD_Reference#pkgver]].&lt;br /&gt;
# Licensing is done properly. Remove unnecessary copying of licensing that is already OSI approved.&lt;br /&gt;
# Naming conventions rules for unofficial variables as in _gitrev is preferred over commit.&lt;br /&gt;
# Indent with tabs not spaces.&lt;br /&gt;
# Removal of explicit return 1.  (They are still found the old APKBUILD files if you are learning but are now strongly discouraged.)&lt;br /&gt;
# Disabling check() requires either (1) a comment (#) stating next to options=&amp;quot;!check&amp;quot; that there is no test suite/unit tests or (2) functioning working check() function.&lt;br /&gt;
# Explicit call to subpackages=&amp;quot;$pkgname-doc&amp;quot; must be used instead of explicit gzip man page compression.&lt;br /&gt;
# Ideally, lines should be no more than 80 columns wide&lt;br /&gt;
&lt;br /&gt;
Additionally, make sure to run the linter on your package:&lt;br /&gt;
{{Cmd|doas apk add atools&lt;br /&gt;
apkbuild-lint APKBUILD}}&lt;br /&gt;
&lt;br /&gt;
For more information see [[Development using git:Quality assurance]] and [[Package_policies]].&lt;br /&gt;
Also check out [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/COMMITSTYLE.md?ref_type=heads aports/COMMITSTYLE.md] and [https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/CODINGSTYLE.md?ref_type=heads aports/CODINGSTYLE.md]&lt;br /&gt;
&lt;br /&gt;
== Commit your work  ==&lt;br /&gt;
&lt;br /&gt;
After you successfully build your package and properly followed the conventions and requirements in the code review section, you can submit your APKBUILD to Alpine&#039;s git repository. &lt;br /&gt;
&lt;br /&gt;
Update your git repo, before adding new files: &lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git pull}}&lt;br /&gt;
&lt;br /&gt;
This should pull all the changes made by others into your local git repo.&lt;br /&gt;
&lt;br /&gt;
When you think you are ready you can add your files to git: &lt;br /&gt;
&lt;br /&gt;
NOTE: when using our Gitlab instance, you can create MR&#039;s for each package. Please squash all commits related to the same package into a single one per MR.&lt;br /&gt;
&lt;br /&gt;
{{Cmd|cd $aportsdir&lt;br /&gt;
git add testing/$pkgdir (include any other files needed for the build; $pkgname.install...)&lt;br /&gt;
git commit}}&lt;br /&gt;
&lt;br /&gt;
Use the following commit message template for new aports (without the comments):&lt;br /&gt;
&lt;br /&gt;
{{Cat|template|testing/$pkgname: new aport   # this will be the subject line&lt;br /&gt;
                              # a blank line&lt;br /&gt;
$url                          # project homepage&lt;br /&gt;
$pkgdesc                      # one line description}}&lt;br /&gt;
&lt;br /&gt;
Or you could add the following and &amp;lt;code&amp;gt;chmod +x ports/.git/hooks/prepare-commit-msg&amp;lt;/code&amp;gt; to automatically generate commit message which the default aports/.githooks/ does not:&lt;br /&gt;
&lt;br /&gt;
{{Cat|aports/.git/hooks/prepare-commit-msg|&amp;lt;nowiki&amp;gt;#!/bin/sh&lt;br /&gt;
case &amp;quot;$2,$3&amp;quot; in&lt;br /&gt;
  ,|template,)&lt;br /&gt;
    if git diff-index --diff-filter=A --name-only --cached HEAD \&lt;br /&gt;
        | grep -q &#039;/APKBUILD$&#039;; then&lt;br /&gt;
      meta() { git diff --staged | grep &amp;quot;^+$1&amp;quot; | sed &#039;s/.*=&amp;quot;\?//;s/&amp;quot;$//&#039;;}&lt;br /&gt;
      printf &#039;testing/%s: new aport\n\n%s\n%s\n&#039; &amp;quot;$(meta pkgname)&amp;quot; \&lt;br /&gt;
        &amp;quot;$(meta url)&amp;quot; &amp;quot;$(meta pkgdesc)&amp;quot; &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      printf &#039;%s\n\n%s&#039; `git diff-index --name-only --cached HEAD \&lt;br /&gt;
        | sed -n &#039;s/\/APKBUILD$//p;q&#039;` &amp;quot;$(cat $1)&amp;quot; &amp;gt; &amp;quot;$1&amp;quot;&lt;br /&gt;
    fi;;&lt;br /&gt;
esac&amp;lt;/nowiki&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
Now your changes are only available locally in your repository.&lt;br /&gt;
&lt;br /&gt;
Because you do not have push rights to the Alpine aports repository you need to create a merge request to [https://gitlab.alpinelinux.org/alpine/aports Alpine&#039;s GitLab instance].&lt;br /&gt;
&lt;br /&gt;
Alternatively you can also create a diff (patch) of the changes you made and send this patch to the &lt;br /&gt;
[https://lists.alpinelinux.org/~alpine/aports  alpine-aports mailinglist].&lt;br /&gt;
&lt;br /&gt;
To create a diff patch:&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^}}&lt;br /&gt;
&lt;br /&gt;
or if you have sprunge, you can create a link to your patch for convenience&lt;br /&gt;
&lt;br /&gt;
{{Cmd|git format-patch HEAD^ --stdout &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; sprunge}}&lt;br /&gt;
&lt;br /&gt;
== Automated flagging of outdated ports ==&lt;br /&gt;
Consider adding your port to [https://release-monitoring.org/ Anitya], so it will be flagged as outdated&lt;br /&gt;
as soon as a new stable version is released by upstream.&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
* [[APKBUILD Reference]]&lt;br /&gt;
* [[APKBUILD examples]]&lt;br /&gt;
* [[Development using git]]&lt;br /&gt;
* [[Development using git:Quality assurance]]&lt;br /&gt;
&lt;br /&gt;
[[category: Package Manager]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22915</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22915"/>
		<updated>2023-01-17T04:00:55Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: Added nano pi build for latest alpine/kernel&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This page describes building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and an internal LAN with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise, it comprises 13 GB of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
* Obtain a microSD card (or HDD) you can wipe the data from. We will assume it is /dev/sdc.&lt;br /&gt;
* Make a 256M FAT16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* The rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* Untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all of the files to the fat16 partition which can be as large as 2G. &lt;br /&gt;
* Make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* Add this to usercfg.txt at the root of the FAT16 partition:&lt;br /&gt;
  enable_uart=1&lt;br /&gt;
  gpu_mem=16&lt;br /&gt;
  dtparam=audio=off&lt;br /&gt;
* This is the contents of cmdline.txt:&lt;br /&gt;
  modules=loop,squashfs,sd-mod,usb-storage console=tty1 console=ttyAMA0,115200&lt;br /&gt;
&lt;br /&gt;
=== First Boot ===&lt;br /&gt;
* Put the SD into the pi zero&lt;br /&gt;
* Connect the serial port&lt;br /&gt;
* Run minicom with the parameters set to 115200,n,8,1, no flow control.&lt;br /&gt;
* Power up the Pi.&lt;br /&gt;
&lt;br /&gt;
=== Copy Root ===&lt;br /&gt;
* mkdir /stage&lt;br /&gt;
* mount /dev/sda2 /stage&lt;br /&gt;
* for d in $(ls -1 /|grep -v &#039;media\|stage\|dev\|proc\|sys&#039;); do cp -a /$d /stage; done&lt;br /&gt;
* modules are loop mounted to /.modloop, and lib/modules is symlinked to that, so&lt;br /&gt;
* rm /stage/lib/modules&lt;br /&gt;
* cp -a /.modloop /stage/lib/modules&lt;br /&gt;
* Fix cmdline.txt&lt;br /&gt;
  mount -o remount,rw /media/mmcblk0p1&lt;br /&gt;
  echo &#039;root=/dev/mmcblk0p2&#039; &amp;gt;&amp;gt; /media/mmcblk0p1/cmdline.txt&lt;br /&gt;
* reboot&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* verify you are now operating from the ext2 filesystem where you copied the rootfs.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
* edit all the configurations supplied here.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
This has two subnets. One for normal dhcp, the other for pseudo static - dhcp provided by MAC. One example here.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=br0&lt;br /&gt;
except-interface=eth0&lt;br /&gt;
dhcp-range=subnet0,192.168.0.10,192.168.0.100,255.255.255.0,24h&lt;br /&gt;
dhcp-range=subnet1,192.168.0.4,192.168.0.6,255.255.255.0,24h&lt;br /&gt;
bind-interfaces&lt;br /&gt;
#log-queries&lt;br /&gt;
#log-dhcp&lt;br /&gt;
dhcp-host=70:85:66:c4:48:55,192.168.0.4,nas&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== /etc/hosts =====&lt;br /&gt;
dnsmasq provides DNS answers from the hosts file. Nice. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
127.0.0.1	localhost localhost.localdomain&lt;br /&gt;
::1		localhost localhost.localdomain&lt;br /&gt;
192.168.0.3     wireless&lt;br /&gt;
192.168.0.4     nas&lt;br /&gt;
192.168.0.5     mpd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=wlan0&lt;br /&gt;
bridge=br0&lt;br /&gt;
hw_mode=g&lt;br /&gt;
channel=7&lt;br /&gt;
wmm_enabled=0&lt;br /&gt;
macaddr_acl=0&lt;br /&gt;
auth_algs=1&lt;br /&gt;
ignore_broadcast_ssid=0&lt;br /&gt;
wpa=2&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&lt;br /&gt;
wpa_pairwise=TKIP&lt;br /&gt;
rsn_pairwise=CCMP&lt;br /&gt;
ssid=Whatever&lt;br /&gt;
wpa_passphrase=YouMakeItUp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname ANYNAME&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&lt;br /&gt;
&lt;br /&gt;
iface eth1 inet manual&lt;br /&gt;
iface wlan0 inet manual&lt;br /&gt;
&lt;br /&gt;
auto br0&lt;br /&gt;
iface br0 inet static&lt;br /&gt;
        pre-up ifconfig eth1 up&lt;br /&gt;
        bridge-ports eth1 wlan0&lt;br /&gt;
        bridge-stp off&lt;br /&gt;
        address 192.168.0.3&lt;br /&gt;
        broadcaset 192.168.1.255&lt;br /&gt;
        netmask 255.255.255.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! There is NO protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&amp;lt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create, index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Related =====&lt;br /&gt;
[https://github.com/rickyrockrat/nanopi-alpine NanoPi NEO build script]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Alpine_on_ARM&amp;diff=22914</id>
		<title>Alpine on ARM</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Alpine_on_ARM&amp;diff=22914"/>
		<updated>2023-01-17T02:48:29Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Specific guides */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
{{Style}}&lt;br /&gt;
{{Move|ARM SOCs}}&lt;br /&gt;
&lt;br /&gt;
(Parts of this page are WIP, still incomplete and some might be incorrect.)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Supported SoCs==&lt;br /&gt;
&lt;br /&gt;
Currently Alpine supports armv6/armhf arch on the following SoCs&lt;br /&gt;
&lt;br /&gt;
(This is taken from the DTBs which Alpine includes)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable collapsible&amp;quot;&lt;br /&gt;
| am335x-base0033&lt;br /&gt;
| am335x-bone&lt;br /&gt;
| am335x-boneblack&lt;br /&gt;
| am335x-evm&lt;br /&gt;
| am335x-evmsk&lt;br /&gt;
| am335x-nano&lt;br /&gt;
| am335x-pepper&lt;br /&gt;
| am3517-craneboard&lt;br /&gt;
| am3517-evm&lt;br /&gt;
| am3517_mt_ventoux&lt;br /&gt;
| am437x-gp-evm&lt;br /&gt;
|-&lt;br /&gt;
| am437x-sk-evm&lt;br /&gt;
| am43x-epos-evm&lt;br /&gt;
| exynos4210-origen&lt;br /&gt;
| exynos4210-smdkv310&lt;br /&gt;
| exynos4210-trats&lt;br /&gt;
| exynos4210-universal_c210&lt;br /&gt;
| exynos4412-odroidu3&lt;br /&gt;
| exynos4412-odroidx&lt;br /&gt;
| exynos4412-odroidx2&lt;br /&gt;
| exynos4412-origen&lt;br /&gt;
| exynos4412-smdk4412&lt;br /&gt;
| exynos4412-tiny4412&lt;br /&gt;
|-&lt;br /&gt;
| exynos4412-trats2&lt;br /&gt;
| exynos5250-arndale&lt;br /&gt;
| exynos5250-smdk5250&lt;br /&gt;
| exynos5250-snow&lt;br /&gt;
| exynos5260-xyref5260&lt;br /&gt;
| exynos5410-smdk5410&lt;br /&gt;
| exynos5420-arndale-octa&lt;br /&gt;
| exynos5420-peach-pit&lt;br /&gt;
| exynos5420-smdk5420&lt;br /&gt;
| exynos5440-sd5v1&lt;br /&gt;
| exynos5440-ssdk5440&lt;br /&gt;
| exynos5800-peach-pi&lt;br /&gt;
|-&lt;br /&gt;
| imx1-ads&lt;br /&gt;
| imx1-apf9328&lt;br /&gt;
| imx25-eukrea-mbimxsd25-baseboard-cmo-qvga&lt;br /&gt;
| imx25-eukrea-mbimxsd25-baseboard-dvi-svga&lt;br /&gt;
| imx25-eukrea-mbimxsd25-baseboard-dvi-vga&lt;br /&gt;
| imx25-eukrea-mbimxsd25-baseboard&lt;br /&gt;
| imx25-karo-tx25&lt;br /&gt;
| imx25-pdk&lt;br /&gt;
| imx27-apf27&lt;br /&gt;
| imx27-apf27dev&lt;br /&gt;
| imx27-eukrea-mbimxsd27-baseboard&lt;br /&gt;
| imx27-pdk&lt;br /&gt;
|-&lt;br /&gt;
| imx27-phytec-phycard-s-rdk&lt;br /&gt;
| imx27-phytec-phycore-rdk&lt;br /&gt;
| imx31-bug&lt;br /&gt;
| imx35-eukrea-mbimxsd35-baseboard&lt;br /&gt;
| imx35-pdk&lt;br /&gt;
| imx50-evk&lt;br /&gt;
| imx51-apf51&lt;br /&gt;
| imx51-apf51dev&lt;br /&gt;
| imx51-babbage&lt;br /&gt;
| imx51-digi-connectcore-jsk&lt;br /&gt;
| imx51-eukrea-mbimxsd51-baseboard&lt;br /&gt;
| imx53-ard&lt;br /&gt;
|-&lt;br /&gt;
| imx53-m53evk&lt;br /&gt;
| imx53-mba53&lt;br /&gt;
| imx53-qsb&lt;br /&gt;
| imx53-qsrb&lt;br /&gt;
| imx53-smd&lt;br /&gt;
| imx53-tx53-x03x&lt;br /&gt;
| imx53-tx53-x13x&lt;br /&gt;
| imx53-voipac-bsb&lt;br /&gt;
| imx6dl-aristainetos_4&lt;br /&gt;
| imx6dl-aristainetos_7&lt;br /&gt;
| imx6dl-cubox-i&lt;br /&gt;
| imx6dl-dfi-fs700-m60&lt;br /&gt;
|-&lt;br /&gt;
| imx6dl-gw51xx&lt;br /&gt;
| imx6dl-gw52xx&lt;br /&gt;
| imx6dl-gw53xx&lt;br /&gt;
| imx6dl-gw54xx&lt;br /&gt;
| imx6dl-gw552x&lt;br /&gt;
| imx6dl-hummingboard&lt;br /&gt;
| imx6dl-nitrogen6x&lt;br /&gt;
| imx6dl-phytec-pbab01&lt;br /&gt;
| imx6dl-rex-basic&lt;br /&gt;
| imx6dl-riotboard&lt;br /&gt;
| imx6dl-sabreauto&lt;br /&gt;
| imx6dl-sabrelite&lt;br /&gt;
|-&lt;br /&gt;
| imx6dl-sabresd&lt;br /&gt;
| imx6dl-tx6dl-comtft&lt;br /&gt;
| imx6dl-tx6u-801x&lt;br /&gt;
| imx6dl-tx6u-811x&lt;br /&gt;
| imx6dl-wandboard-revb1&lt;br /&gt;
| imx6dl-wandboard&lt;br /&gt;
| imx6q-arm2&lt;br /&gt;
| imx6q-cm-fx6&lt;br /&gt;
| imx6q-cubox-i&lt;br /&gt;
| imx6q-dfi-fs700-m60&lt;br /&gt;
| imx6q-dmo-edmqmx6&lt;br /&gt;
| imx6q-gk802&lt;br /&gt;
|-&lt;br /&gt;
| imx6q-gw51xx&lt;br /&gt;
| imx6q-gw52xx&lt;br /&gt;
| imx6q-gw53xx&lt;br /&gt;
| imx6q-gw5400-a&lt;br /&gt;
| imx6q-gw54xx&lt;br /&gt;
| imx6q-gw552x&lt;br /&gt;
| imx6q-hummingboard&lt;br /&gt;
| imx6q-nitrogen6x&lt;br /&gt;
| imx6q-phytec-pbab01&lt;br /&gt;
| imx6q-rex-pro&lt;br /&gt;
| imx6q-sabreauto&lt;br /&gt;
| imx6q-sabrelite&lt;br /&gt;
|-&lt;br /&gt;
| imx6q-sabresd&lt;br /&gt;
| imx6q-sbc6x&lt;br /&gt;
| imx6q-tx6q-1010-comtft&lt;br /&gt;
| imx6q-tx6q-1010&lt;br /&gt;
| imx6q-tx6q-1020-comtft&lt;br /&gt;
| imx6q-tx6q-1020&lt;br /&gt;
| imx6q-tx6q-1110&lt;br /&gt;
| imx6q-udoo&lt;br /&gt;
| imx6q-wandboard-revb1&lt;br /&gt;
| imx6q-wandboard&lt;br /&gt;
| imx6sl-evk&lt;br /&gt;
| imx6sx-sdb&lt;br /&gt;
|-&lt;br /&gt;
| armada-3720-espressobin-v7-emmc&lt;br /&gt;
|-&lt;br /&gt;
| omap3-beagle-xm-ab&lt;br /&gt;
| omap3-beagle-xm&lt;br /&gt;
| omap3-beagle&lt;br /&gt;
| omap3-cm-t3517&lt;br /&gt;
| omap3-cm-t3530&lt;br /&gt;
| omap3-cm-t3730&lt;br /&gt;
| omap3-devkit8000&lt;br /&gt;
| omap3-evm-37xx&lt;br /&gt;
| omap3-evm&lt;br /&gt;
| omap3-gta04a3&lt;br /&gt;
| omap3-gta04a4&lt;br /&gt;
| omap3-gta04a5&lt;br /&gt;
|-&lt;br /&gt;
| omap3-ha-lcd&lt;br /&gt;
| omap3-ha&lt;br /&gt;
| omap3-igep0020&lt;br /&gt;
| omap3-igep0030&lt;br /&gt;
| omap3-ldp&lt;br /&gt;
| omap3-lilly-dbb056&lt;br /&gt;
| omap3-n9&lt;br /&gt;
| omap3-n900&lt;br /&gt;
| omap3-n950&lt;br /&gt;
| omap3-overo-alto35&lt;br /&gt;
| omap3-overo-chestnut43&lt;br /&gt;
| omap3-overo-gallop43&lt;br /&gt;
|-&lt;br /&gt;
| omap3-overo-palo43&lt;br /&gt;
| omap3-overo-storm-alto35&lt;br /&gt;
| omap3-overo-storm-chestnut43&lt;br /&gt;
| omap3-overo-storm-gallop43&lt;br /&gt;
| omap3-overo-storm-palo43&lt;br /&gt;
| omap3-overo-storm-summit&lt;br /&gt;
| omap3-overo-storm-tobi&lt;br /&gt;
| omap3-overo-summit&lt;br /&gt;
| omap3-overo-tobi&lt;br /&gt;
| omap3-sbc-t3517&lt;br /&gt;
| omap3-sbc-t3530&lt;br /&gt;
| omap3-sbc-t3730&lt;br /&gt;
|-&lt;br /&gt;
| omap3-thunder&lt;br /&gt;
| omap3-zoom3&lt;br /&gt;
| omap3430-sdp&lt;br /&gt;
| omap4-duovero-parlor&lt;br /&gt;
| omap4-panda-a4&lt;br /&gt;
| omap4-panda-es&lt;br /&gt;
| omap4-panda&lt;br /&gt;
| omap4-sdp-es23plus&lt;br /&gt;
| omap4-sdp&lt;br /&gt;
| omap4-var-dvk-om44&lt;br /&gt;
| omap4-var-stk-om44&lt;br /&gt;
| omap5-cm-t54&lt;br /&gt;
|-&lt;br /&gt;
| omap5-sbc-t54&lt;br /&gt;
| omap5-uevm&lt;br /&gt;
| qcom-apq8064-cm-qs600&lt;br /&gt;
| qcom-apq8064-ifc6410&lt;br /&gt;
| qcom-apq8074-dragonboard&lt;br /&gt;
| qcom-apq8084-ifc6540&lt;br /&gt;
| qcom-apq8084-mtp&lt;br /&gt;
| qcom-ipq8064-ap148&lt;br /&gt;
| qcom-msm8660-surf&lt;br /&gt;
| qcom-msm8960-cdp&lt;br /&gt;
| qcom-msm8974-sony-xperia-honami&lt;br /&gt;
| sun4i-a10-a1000&lt;br /&gt;
|-&lt;br /&gt;
| sun4i-a10-ba10-tvbox&lt;br /&gt;
| sun4i-a10-cubieboard&lt;br /&gt;
| sun4i-a10-hackberry&lt;br /&gt;
| sun4i-a10-inet97fv2&lt;br /&gt;
| sun4i-a10-mini-xplus&lt;br /&gt;
| sun4i-a10-olinuxino-lime&lt;br /&gt;
| sun4i-a10-pcduino&lt;br /&gt;
| sun5i-a10s-olinuxino-micro&lt;br /&gt;
| sun5i-a10s-r7-tv-dongle&lt;br /&gt;
| sun5i-a13-hsg-h702&lt;br /&gt;
| sun5i-a13-olinuxino-micro&lt;br /&gt;
| sun5i-a13-olinuxino&lt;br /&gt;
|-&lt;br /&gt;
| sun6i-a31-app4-evb1&lt;br /&gt;
| sun6i-a31-colombus&lt;br /&gt;
| sun6i-a31-hummingbird&lt;br /&gt;
| sun6i-a31-m9&lt;br /&gt;
| sun7i-a20-cubieboard2&lt;br /&gt;
| sun7i-a20-cubietruck&lt;br /&gt;
| sun7i-a20-hummingbird&lt;br /&gt;
| sun7i-a20-i12-tvbox&lt;br /&gt;
| sun7i-a20-olinuxino-lime&lt;br /&gt;
| sun7i-a20-olinuxino-micro&lt;br /&gt;
| sun7i-a20-pcduino3&lt;br /&gt;
| sun8i-a23-ippo-q8h-v5&lt;br /&gt;
|-&lt;br /&gt;
| vexpress-v2p-ca15-tc1&lt;br /&gt;
| vexpress-v2p-ca15_a7&lt;br /&gt;
| vexpress-v2p-ca5s&lt;br /&gt;
| vexpress-v2p-ca9&lt;br /&gt;
| vf610-colibri-eval-v3&lt;br /&gt;
| vf610-cosmic&lt;br /&gt;
| vf610-twr&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Install Alpine on supported SoCs==&lt;br /&gt;
&lt;br /&gt;
=== Generic information ===&lt;br /&gt;
&lt;br /&gt;
(If anyone has one of the above devices and has successfully installed Alpine on it, please consider adding the missing info here.)&lt;br /&gt;
&lt;br /&gt;
==== Example with Wandboard ====&lt;br /&gt;
&lt;br /&gt;
===== Get latest Alpine image =====&lt;br /&gt;
Download the last Generic ARM image on https://alpinelinux.org/downloads/&lt;br /&gt;
Extract the archive somewhere.&lt;br /&gt;
&lt;br /&gt;
===== Prepare SD Card =====&lt;br /&gt;
First install SPL and u-boot.img (this could change for other board):&lt;br /&gt;
in root, write the SPL from Alpine extracted files :&lt;br /&gt;
 dd if=u-boot/wandboard/SPL of=/dev/sdX seek=1 bs=1k&lt;br /&gt;
and the u-boot.img :&lt;br /&gt;
 dd if=u-boot/wandboard/u-boot.img of=/dev/sdX seek=69 bs=1k&lt;br /&gt;
&lt;br /&gt;
After create the partition on the sd-card with fdisk, then copy folders apks/ boot/ efi/ extlinux/ u-boot/ to the sd-card partition. (I&#039;m not sure all folder as useful).&lt;br /&gt;
&lt;br /&gt;
After you can put the sd-card in the Wandboard and boot it with serial console connected.&amp;lt;br&amp;gt;&lt;br /&gt;
The board should boot on the sd-card. When the prompt ask a login, enter &#039;root&#039;.&lt;br /&gt;
Then launch &#039;setup-alpine&#039; to configure the system.&lt;br /&gt;
&lt;br /&gt;
=== Specific guides ===&lt;br /&gt;
&lt;br /&gt;
* [[DIY Fully working Alpine Linux for Allwinner and Other ARM SOCs]]&lt;br /&gt;
* [[Raspberry_Pi]]&lt;br /&gt;
* [[Raspberry_Pi_4_-_Persistent_system_acting_as_a_NAS_and_Time_Machine]]&lt;br /&gt;
* [[Odroid-C2]]&lt;br /&gt;
* [https://github.com/rickyrockrat/nanopi-alpine NanoPi Neo build script]&lt;br /&gt;
&lt;br /&gt;
==Unupported SoCs==&lt;br /&gt;
&lt;br /&gt;
If you have an armv6/armv7 SoC which is not listed above but is supported by mainline uboot/kernel then it&#039;s still possible to install Alpine&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
&lt;br /&gt;
* Alpine&#039;s forked uboot to support tarballs (fabled?)&lt;br /&gt;
* serial console&lt;br /&gt;
* crosscompiler/toolchain if you can not compile natively&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===The embedded world===&lt;br /&gt;
&lt;br /&gt;
A lot of the SoCs have their own way of doing things, although they use uboot and Linux kernel but often they are heavily modified to suit easy flashing of &amp;quot;ROMs&amp;quot; or other unknown reasons, e.g. Rockchip&#039;s notion &amp;quot;partition&amp;quot; are neither DOS nor GPT partitions.&lt;br /&gt;
We will discuss to install Alpine in a more standard way like x86 with either DOS or GPT partitions. You will most likely have to install/flash the mainline uboot, which can be non-destructive if you use external storage.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Storage====&lt;br /&gt;
&lt;br /&gt;
One can load uboot from the following block devices if it&#039;s supported.&lt;br /&gt;
* NAND&lt;br /&gt;
* eMMC&lt;br /&gt;
* SD card&lt;br /&gt;
* USB&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Power on====&lt;br /&gt;
&lt;br /&gt;
Some SoCs need both SPL and uboot, you need to check uboot for your board. Most (if not all) boards boots from the internal storage first (either NAND or eMMC) you will have to check documentation of your board if you wish to boot the SPL/uboot from SD/USB.&lt;br /&gt;
&lt;br /&gt;
One can view SPL+uboot as BIOS and boot-loader on PC. Think that you could put the BIOS on an external storage :D&lt;br /&gt;
&lt;br /&gt;
Once you have loaded the &amp;quot;standard&amp;quot; uboot, things are more or less like on x86.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Partitioning====&lt;br /&gt;
&lt;br /&gt;
Either DOS or GPT patitions should work. Start of the first partition should be on block 2048 so there is space for SPL/uboot and marked bootable (with&lt;br /&gt;
the MBR bootable flag, or GPT legacy_bios_bootable attribute).&lt;br /&gt;
* SPL starts at block 64 (please consult the docs for your board)&lt;br /&gt;
* uboot starts at block 256 (please consult the docs for your board)&lt;br /&gt;
Just dd SPL and boot with the correct offset to the media you wish to boot&lt;br /&gt;
&lt;br /&gt;
====Booting Linux kernel====&lt;br /&gt;
&lt;br /&gt;
* uboot uses extlinux.conf file to locate the kernel/initramfs/... just like syslinx, you need to put that file on the partitions which is marked bootable in the /boot directory&lt;br /&gt;
* there should be an extra line &amp;quot;FDTDIR&amp;quot; which points to the DTBs&lt;br /&gt;
e.g.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
label Fedora (3.17.0-0.rc4.git2.1.fc22.armv7hl) 22 (Rawhide)&lt;br /&gt;
	kernel /boot/vmlinuz-3.17.0-0.rc4.git2.1.fc22.armv7hl&lt;br /&gt;
	append ro root=UUID=8eac677f-8ea8-4270-8479-d5ddbb797450 console=ttyS0,115200n8 LANG=en_US.UTF-8 drm.debug=0xf&lt;br /&gt;
	fdtdir /boot/dtb-3.17.0-0.rc4.git2.1.fc22.armv7hl&lt;br /&gt;
	initrd /boot/initramfs-3.17.0-0.rc4.git2.1.fc22.armv7hl.img&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Using QEMU==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
qemu-system-arm -M vexpress-a9 -kernel zImage -initrd initramfs-grsec -dtb vexpress-v2p-ca9.dtb -hda hda.img -serial stdio&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.armadeus.org/wiki/index.php?title=Kernel-with-device-tree dtb (Device Tree Binary)]&lt;br /&gt;
* [https://forum.odroid.com/viewtopic.php?t=30459 Odroid-C2] 2018 &#039;&#039;([https://archlinuxarm.org/platforms/armv8/amlogic/odroid-c2 ARMv8, AArch64];  [https://forum.odroid.com/viewtopic.php?f=138&amp;amp;t=32608 Alpine Linux custom build])&#039;&#039;&lt;br /&gt;
* [https://cusdeb.com/ CusDeb.com] - bootstrap SD-card images for single-board computers online; &#039;&#039;([https://github.com/tolstoyevsky/pieman Pieman])&#039;&#039;&lt;br /&gt;
* [https://kernelci.org/soc/ &amp;lt;s&amp;gt;Available&amp;lt;/s&amp;gt; SoCs]&lt;br /&gt;
&lt;br /&gt;
[[Category:Hardware]]&lt;br /&gt;
[[category:ARM]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22750</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22750"/>
		<updated>2022-12-08T05:26:55Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* hostapd.conf */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This page describes building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and an internal LAN with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise, it comprises 13 GB of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
* Obtain a microSD card (or HDD) you can wipe the data from. We will assume it is /dev/sdc.&lt;br /&gt;
* Make a 256M FAT16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* The rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* Untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all of the files to the fat16 partition which can be as large as 2G. &lt;br /&gt;
* Make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* Add this to usercfg.txt at the root of the FAT16 partition:&lt;br /&gt;
  enable_uart=1&lt;br /&gt;
  gpu_mem=16&lt;br /&gt;
  dtparam=audio=off&lt;br /&gt;
* This is the contents of cmdline.txt:&lt;br /&gt;
  modules=loop,squashfs,sd-mod,usb-storage console=tty1 console=ttyAMA0,115200&lt;br /&gt;
&lt;br /&gt;
=== First Boot ===&lt;br /&gt;
* Put the SD into the pi zero&lt;br /&gt;
* Connect the serial port&lt;br /&gt;
* Run minicom with the parameters set to 115200,n,8,1, no flow control.&lt;br /&gt;
* Power up the Pi.&lt;br /&gt;
&lt;br /&gt;
=== Copy Root ===&lt;br /&gt;
* mkdir /stage&lt;br /&gt;
* mount /dev/sda2 /stage&lt;br /&gt;
* for d in $(ls -1 /|grep -v &#039;media\|stage\|dev\|proc\|sys&#039;); do cp -a /$d /stage; done&lt;br /&gt;
* modules are loop mounted to /.modloop, and lib/modules is symlinked to that, so&lt;br /&gt;
* rm /stage/lib/modules&lt;br /&gt;
* cp -a /.modloop /stage/lib/modules&lt;br /&gt;
* Fix cmdline.txt&lt;br /&gt;
  mount -o remount,rw /media/mmcblk0p1&lt;br /&gt;
  echo &#039;root=/dev/mmcblk0p2&#039; &amp;gt;&amp;gt; /media/mmcblk0p1/cmdline.txt&lt;br /&gt;
* reboot&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* verify you are now operating from the ext2 filesystem where you copied the rootfs.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
* edit all the configurations supplied here.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
This has two subnets. One for normal dhcp, the other for pseudo static - dhcp provided by MAC. One example here.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=br0&lt;br /&gt;
except-interface=eth0&lt;br /&gt;
dhcp-range=subnet0,192.168.0.10,192.168.0.100,255.255.255.0,24h&lt;br /&gt;
dhcp-range=subnet1,192.168.0.4,192.168.0.6,255.255.255.0,24h&lt;br /&gt;
bind-interfaces&lt;br /&gt;
#log-queries&lt;br /&gt;
#log-dhcp&lt;br /&gt;
dhcp-host=70:85:66:c4:48:55,192.168.0.4,nas&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== /etc/hosts =====&lt;br /&gt;
dnsmasq provides DNS answers from the hosts file. Nice. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
127.0.0.1	localhost localhost.localdomain&lt;br /&gt;
::1		localhost localhost.localdomain&lt;br /&gt;
192.168.0.3     wireless&lt;br /&gt;
192.168.0.4     nas&lt;br /&gt;
192.168.0.5     mpd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=wlan0&lt;br /&gt;
bridge=br0&lt;br /&gt;
hw_mode=g&lt;br /&gt;
channel=7&lt;br /&gt;
wmm_enabled=0&lt;br /&gt;
macaddr_acl=0&lt;br /&gt;
auth_algs=1&lt;br /&gt;
ignore_broadcast_ssid=0&lt;br /&gt;
wpa=2&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&lt;br /&gt;
wpa_pairwise=TKIP&lt;br /&gt;
rsn_pairwise=CCMP&lt;br /&gt;
ssid=Whatever&lt;br /&gt;
wpa_passphrase=YouMakeItUp&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname ANYNAME&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&lt;br /&gt;
&lt;br /&gt;
iface eth1 inet manual&lt;br /&gt;
iface wlan0 inet manual&lt;br /&gt;
&lt;br /&gt;
auto br0&lt;br /&gt;
iface br0 inet static&lt;br /&gt;
        pre-up ifconfig eth1 up&lt;br /&gt;
        bridge-ports eth1 wlan0&lt;br /&gt;
        bridge-stp off&lt;br /&gt;
        address 192.168.0.3&lt;br /&gt;
        broadcaset 192.168.1.255&lt;br /&gt;
        netmask 255.255.255.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! There is NO protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&amp;lt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create, index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22749</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22749"/>
		<updated>2022-12-08T05:25:15Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* interfaces */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This page describes building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and an internal LAN with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise, it comprises 13 GB of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
* Obtain a microSD card (or HDD) you can wipe the data from. We will assume it is /dev/sdc.&lt;br /&gt;
* Make a 256M FAT16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* The rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* Untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all of the files to the fat16 partition which can be as large as 2G. &lt;br /&gt;
* Make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* Add this to usercfg.txt at the root of the FAT16 partition:&lt;br /&gt;
  enable_uart=1&lt;br /&gt;
  gpu_mem=16&lt;br /&gt;
  dtparam=audio=off&lt;br /&gt;
* This is the contents of cmdline.txt:&lt;br /&gt;
  modules=loop,squashfs,sd-mod,usb-storage console=tty1 console=ttyAMA0,115200&lt;br /&gt;
&lt;br /&gt;
=== First Boot ===&lt;br /&gt;
* Put the SD into the pi zero&lt;br /&gt;
* Connect the serial port&lt;br /&gt;
* Run minicom with the parameters set to 115200,n,8,1, no flow control.&lt;br /&gt;
* Power up the Pi.&lt;br /&gt;
&lt;br /&gt;
=== Copy Root ===&lt;br /&gt;
* mkdir /stage&lt;br /&gt;
* mount /dev/sda2 /stage&lt;br /&gt;
* for d in $(ls -1 /|grep -v &#039;media\|stage\|dev\|proc\|sys&#039;); do cp -a /$d /stage; done&lt;br /&gt;
* modules are loop mounted to /.modloop, and lib/modules is symlinked to that, so&lt;br /&gt;
* rm /stage/lib/modules&lt;br /&gt;
* cp -a /.modloop /stage/lib/modules&lt;br /&gt;
* Fix cmdline.txt&lt;br /&gt;
  mount -o remount,rw /media/mmcblk0p1&lt;br /&gt;
  echo &#039;root=/dev/mmcblk0p2&#039; &amp;gt;&amp;gt; /media/mmcblk0p1/cmdline.txt&lt;br /&gt;
* reboot&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* verify you are now operating from the ext2 filesystem where you copied the rootfs.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
* edit all the configurations supplied here.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
This has two subnets. One for normal dhcp, the other for pseudo static - dhcp provided by MAC. One example here.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=br0&lt;br /&gt;
except-interface=eth0&lt;br /&gt;
dhcp-range=subnet0,192.168.0.10,192.168.0.100,255.255.255.0,24h&lt;br /&gt;
dhcp-range=subnet1,192.168.0.4,192.168.0.6,255.255.255.0,24h&lt;br /&gt;
bind-interfaces&lt;br /&gt;
#log-queries&lt;br /&gt;
#log-dhcp&lt;br /&gt;
dhcp-host=70:85:66:c4:48:55,192.168.0.4,nas&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== /etc/hosts =====&lt;br /&gt;
dnsmasq provides DNS answers from the hosts file. Nice. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
127.0.0.1	localhost localhost.localdomain&lt;br /&gt;
::1		localhost localhost.localdomain&lt;br /&gt;
192.168.0.3     wireless&lt;br /&gt;
192.168.0.4     nas&lt;br /&gt;
192.168.0.5     mpd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
bridge=br0&amp;lt;br&amp;gt;&lt;br /&gt;
hw_mode=g&amp;lt;br&amp;gt;&lt;br /&gt;
channel=7&amp;lt;br&amp;gt;&lt;br /&gt;
wmm_enabled=0&amp;lt;br&amp;gt;&lt;br /&gt;
macaddr_acl=0&amp;lt;br&amp;gt;&lt;br /&gt;
auth_algs=1&amp;lt;br&amp;gt;&lt;br /&gt;
ignore_broadcast_ssid=0&amp;lt;br&amp;gt;&lt;br /&gt;
wpa=2&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_pairwise=TKIP&amp;lt;br&amp;gt;&lt;br /&gt;
rsn_pairwise=CCMP&amp;lt;br&amp;gt;&lt;br /&gt;
ssid=Whatever&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_passphrase=YouMakeItUp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
auto lo&lt;br /&gt;
iface lo inet loopback&lt;br /&gt;
&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname ANYNAME&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&lt;br /&gt;
&lt;br /&gt;
iface eth1 inet manual&lt;br /&gt;
iface wlan0 inet manual&lt;br /&gt;
&lt;br /&gt;
auto br0&lt;br /&gt;
iface br0 inet static&lt;br /&gt;
        pre-up ifconfig eth1 up&lt;br /&gt;
        bridge-ports eth1 wlan0&lt;br /&gt;
        bridge-stp off&lt;br /&gt;
        address 192.168.0.3&lt;br /&gt;
        broadcaset 192.168.1.255&lt;br /&gt;
        netmask 255.255.255.0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! There is NO protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&amp;lt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create, index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22748</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22748"/>
		<updated>2022-12-08T05:23:45Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* /etc/hosts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This page describes building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and an internal LAN with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise, it comprises 13 GB of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
* Obtain a microSD card (or HDD) you can wipe the data from. We will assume it is /dev/sdc.&lt;br /&gt;
* Make a 256M FAT16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* The rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* Untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all of the files to the fat16 partition which can be as large as 2G. &lt;br /&gt;
* Make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* Add this to usercfg.txt at the root of the FAT16 partition:&lt;br /&gt;
  enable_uart=1&lt;br /&gt;
  gpu_mem=16&lt;br /&gt;
  dtparam=audio=off&lt;br /&gt;
* This is the contents of cmdline.txt:&lt;br /&gt;
  modules=loop,squashfs,sd-mod,usb-storage console=tty1 console=ttyAMA0,115200&lt;br /&gt;
&lt;br /&gt;
=== First Boot ===&lt;br /&gt;
* Put the SD into the pi zero&lt;br /&gt;
* Connect the serial port&lt;br /&gt;
* Run minicom with the parameters set to 115200,n,8,1, no flow control.&lt;br /&gt;
* Power up the Pi.&lt;br /&gt;
&lt;br /&gt;
=== Copy Root ===&lt;br /&gt;
* mkdir /stage&lt;br /&gt;
* mount /dev/sda2 /stage&lt;br /&gt;
* for d in $(ls -1 /|grep -v &#039;media\|stage\|dev\|proc\|sys&#039;); do cp -a /$d /stage; done&lt;br /&gt;
* modules are loop mounted to /.modloop, and lib/modules is symlinked to that, so&lt;br /&gt;
* rm /stage/lib/modules&lt;br /&gt;
* cp -a /.modloop /stage/lib/modules&lt;br /&gt;
* Fix cmdline.txt&lt;br /&gt;
  mount -o remount,rw /media/mmcblk0p1&lt;br /&gt;
  echo &#039;root=/dev/mmcblk0p2&#039; &amp;gt;&amp;gt; /media/mmcblk0p1/cmdline.txt&lt;br /&gt;
* reboot&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* verify you are now operating from the ext2 filesystem where you copied the rootfs.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
* edit all the configurations supplied here.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
This has two subnets. One for normal dhcp, the other for pseudo static - dhcp provided by MAC. One example here.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=br0&lt;br /&gt;
except-interface=eth0&lt;br /&gt;
dhcp-range=subnet0,192.168.0.10,192.168.0.100,255.255.255.0,24h&lt;br /&gt;
dhcp-range=subnet1,192.168.0.4,192.168.0.6,255.255.255.0,24h&lt;br /&gt;
bind-interfaces&lt;br /&gt;
#log-queries&lt;br /&gt;
#log-dhcp&lt;br /&gt;
dhcp-host=70:85:66:c4:48:55,192.168.0.4,nas&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== /etc/hosts =====&lt;br /&gt;
dnsmasq provides DNS answers from the hosts file. Nice. &amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
127.0.0.1	localhost localhost.localdomain&lt;br /&gt;
::1		localhost localhost.localdomain&lt;br /&gt;
192.168.0.3     wireless&lt;br /&gt;
192.168.0.4     nas&lt;br /&gt;
192.168.0.5     mpd&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
bridge=br0&amp;lt;br&amp;gt;&lt;br /&gt;
hw_mode=g&amp;lt;br&amp;gt;&lt;br /&gt;
channel=7&amp;lt;br&amp;gt;&lt;br /&gt;
wmm_enabled=0&amp;lt;br&amp;gt;&lt;br /&gt;
macaddr_acl=0&amp;lt;br&amp;gt;&lt;br /&gt;
auth_algs=1&amp;lt;br&amp;gt;&lt;br /&gt;
ignore_broadcast_ssid=0&amp;lt;br&amp;gt;&lt;br /&gt;
wpa=2&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_pairwise=TKIP&amp;lt;br&amp;gt;&lt;br /&gt;
rsn_pairwise=CCMP&amp;lt;br&amp;gt;&lt;br /&gt;
ssid=Whatever&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_passphrase=YouMakeItUp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
auto lo&amp;lt;br&amp;gt;&lt;br /&gt;
iface lo inet loopback&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto eth0&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth0 inet dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
        hostname ANYNAME&amp;lt;br&amp;gt;&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth1 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
iface wlan0 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto br0&amp;lt;br&amp;gt;&lt;br /&gt;
iface br0 inet static&amp;lt;br&amp;gt;&lt;br /&gt;
        pre-up ifconfig eth1 up&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-ports eth1 wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-stp off&amp;lt;br&amp;gt;&lt;br /&gt;
        address 192.168.0.3&amp;lt;br&amp;gt;&lt;br /&gt;
        broadcaset 192.168.1.255&amp;lt;br&amp;gt;&lt;br /&gt;
        netmask 255.255.255.0&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! There is NO protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&amp;lt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create, index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22747</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=22747"/>
		<updated>2022-12-08T05:23:05Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* dnsmasq.conf */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This page describes building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and an internal LAN with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise, it comprises 13 GB of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
* Obtain a microSD card (or HDD) you can wipe the data from. We will assume it is /dev/sdc.&lt;br /&gt;
* Make a 256M FAT16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* The rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* Untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all of the files to the fat16 partition which can be as large as 2G. &lt;br /&gt;
* Make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* Add this to usercfg.txt at the root of the FAT16 partition:&lt;br /&gt;
  enable_uart=1&lt;br /&gt;
  gpu_mem=16&lt;br /&gt;
  dtparam=audio=off&lt;br /&gt;
* This is the contents of cmdline.txt:&lt;br /&gt;
  modules=loop,squashfs,sd-mod,usb-storage console=tty1 console=ttyAMA0,115200&lt;br /&gt;
&lt;br /&gt;
=== First Boot ===&lt;br /&gt;
* Put the SD into the pi zero&lt;br /&gt;
* Connect the serial port&lt;br /&gt;
* Run minicom with the parameters set to 115200,n,8,1, no flow control.&lt;br /&gt;
* Power up the Pi.&lt;br /&gt;
&lt;br /&gt;
=== Copy Root ===&lt;br /&gt;
* mkdir /stage&lt;br /&gt;
* mount /dev/sda2 /stage&lt;br /&gt;
* for d in $(ls -1 /|grep -v &#039;media\|stage\|dev\|proc\|sys&#039;); do cp -a /$d /stage; done&lt;br /&gt;
* modules are loop mounted to /.modloop, and lib/modules is symlinked to that, so&lt;br /&gt;
* rm /stage/lib/modules&lt;br /&gt;
* cp -a /.modloop /stage/lib/modules&lt;br /&gt;
* Fix cmdline.txt&lt;br /&gt;
  mount -o remount,rw /media/mmcblk0p1&lt;br /&gt;
  echo &#039;root=/dev/mmcblk0p2&#039; &amp;gt;&amp;gt; /media/mmcblk0p1/cmdline.txt&lt;br /&gt;
* reboot&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* verify you are now operating from the ext2 filesystem where you copied the rootfs.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
* edit all the configurations supplied here.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
This has two subnets. One for normal dhcp, the other for pseudo static - dhcp provided by MAC. One example here.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
interface=br0&lt;br /&gt;
except-interface=eth0&lt;br /&gt;
dhcp-range=subnet0,192.168.0.10,192.168.0.100,255.255.255.0,24h&lt;br /&gt;
dhcp-range=subnet1,192.168.0.4,192.168.0.6,255.255.255.0,24h&lt;br /&gt;
bind-interfaces&lt;br /&gt;
#log-queries&lt;br /&gt;
#log-dhcp&lt;br /&gt;
dhcp-host=70:85:66:c4:48:55,192.168.0.4,nas&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== /etc/hosts =====&lt;br /&gt;
dnsmasq provides DNS answers from the hosts file. Nice. &amp;lt;br&amp;gt;&lt;br /&gt;
127.0.0.1	localhost localhost.localdomain&amp;lt;br&amp;gt;&lt;br /&gt;
::1		localhost localhost.localdomain&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.3     wireless&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.4     nas&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.5     mpd&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
bridge=br0&amp;lt;br&amp;gt;&lt;br /&gt;
hw_mode=g&amp;lt;br&amp;gt;&lt;br /&gt;
channel=7&amp;lt;br&amp;gt;&lt;br /&gt;
wmm_enabled=0&amp;lt;br&amp;gt;&lt;br /&gt;
macaddr_acl=0&amp;lt;br&amp;gt;&lt;br /&gt;
auth_algs=1&amp;lt;br&amp;gt;&lt;br /&gt;
ignore_broadcast_ssid=0&amp;lt;br&amp;gt;&lt;br /&gt;
wpa=2&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_pairwise=TKIP&amp;lt;br&amp;gt;&lt;br /&gt;
rsn_pairwise=CCMP&amp;lt;br&amp;gt;&lt;br /&gt;
ssid=Whatever&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_passphrase=YouMakeItUp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
auto lo&amp;lt;br&amp;gt;&lt;br /&gt;
iface lo inet loopback&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto eth0&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth0 inet dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
        hostname ANYNAME&amp;lt;br&amp;gt;&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth1 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
iface wlan0 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto br0&amp;lt;br&amp;gt;&lt;br /&gt;
iface br0 inet static&amp;lt;br&amp;gt;&lt;br /&gt;
        pre-up ifconfig eth1 up&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-ports eth1 wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-stp off&amp;lt;br&amp;gt;&lt;br /&gt;
        address 192.168.0.3&amp;lt;br&amp;gt;&lt;br /&gt;
        broadcaset 192.168.1.255&amp;lt;br&amp;gt;&lt;br /&gt;
        netmask 255.255.255.0&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! There is NO protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&amp;lt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create, index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18456</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18456"/>
		<updated>2021-01-03T14:01:46Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise. That is 13G of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple, short, and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
=== Prepare ===&lt;br /&gt;
* Find a microsd (or HDD) you can wipe. We will assume it is /dev/sdc.&lt;br /&gt;
* make a 256M fat16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* the rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all files to the fat16 partition which is good for up to 2G. &lt;br /&gt;
* make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* add this to usercfg.txt at the root of the FAT16:&lt;br /&gt;
  enable_uart=1&lt;br /&gt;
  gpu_mem=16&lt;br /&gt;
  dtparam=audio=off&lt;br /&gt;
* This is the contents of cmdline.txt:&lt;br /&gt;
  modules=loop,squashfs,sd-mod,usb-storage console=tty1 console=ttyAMA0,115200&lt;br /&gt;
=== First Boot ===&lt;br /&gt;
* Put the SD into the pi zero&lt;br /&gt;
* Connect the serial port&lt;br /&gt;
* fire up minicom with 115200,n,8,1, with no software or hardware flow.&lt;br /&gt;
* Power up the Pi.&lt;br /&gt;
&lt;br /&gt;
=== Copy Root ===&lt;br /&gt;
* mkdir /stage&lt;br /&gt;
* mount /dev/sda2 /stage&lt;br /&gt;
* for d in $(ls -1 /|grep -v &#039;media\|stage\|dev\|proc\|sys&#039;); do cp -a /$d /stage; done&lt;br /&gt;
* modules are loop mounted to /.modloop, and lib/modules is symlinked to that, so&lt;br /&gt;
* rm /stage/lib/modules&lt;br /&gt;
* cp -a /.modloop /stage/lib/modules&lt;br /&gt;
* Fixup cmdline.txt&lt;br /&gt;
  mount -o remount,rw /media/mmcblk0p1&lt;br /&gt;
  echo &#039;root=/dev/mmcblk0p2&#039; &amp;gt;&amp;gt; /media/mmcblk0p1/cmdline.txt&lt;br /&gt;
* reboot&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* verify you are now operating off of the ext2 FS where you copied over the rootfs.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
* edit all the configurations supplied here.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
This has two subnets. One for normal dhcp, the other for pseudo static - dhcp provided by MAC. One example here.&amp;lt;br&amp;gt;&lt;br /&gt;
interface=br0&amp;lt;br&amp;gt;&lt;br /&gt;
except-interface=eth0&amp;lt;br&amp;gt;&lt;br /&gt;
dhcp-range=subnet0,192.168.0.10,192.168.0.100,255.255.255.0,24h&amp;lt;br&amp;gt;&lt;br /&gt;
dhcp-range=subnet1,192.168.0.4,192.168.0.6,255.255.255.0,24h&amp;lt;br&amp;gt;&lt;br /&gt;
bind-interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
#log-queries&amp;lt;br&amp;gt;&lt;br /&gt;
#log-dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
dhcp-host=70:85:66:c4:48:55,192.168.0.4,nas&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== /etc/hosts =====&lt;br /&gt;
dnsmasq provides DNS answers from the hosts file. Nice. &amp;lt;br&amp;gt;&lt;br /&gt;
127.0.0.1	localhost localhost.localdomain&amp;lt;br&amp;gt;&lt;br /&gt;
::1		localhost localhost.localdomain&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.3     wireless&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.4     nas&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.5     mpd&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
bridge=br0&amp;lt;br&amp;gt;&lt;br /&gt;
hw_mode=g&amp;lt;br&amp;gt;&lt;br /&gt;
channel=7&amp;lt;br&amp;gt;&lt;br /&gt;
wmm_enabled=0&amp;lt;br&amp;gt;&lt;br /&gt;
macaddr_acl=0&amp;lt;br&amp;gt;&lt;br /&gt;
auth_algs=1&amp;lt;br&amp;gt;&lt;br /&gt;
ignore_broadcast_ssid=0&amp;lt;br&amp;gt;&lt;br /&gt;
wpa=2&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_pairwise=TKIP&amp;lt;br&amp;gt;&lt;br /&gt;
rsn_pairwise=CCMP&amp;lt;br&amp;gt;&lt;br /&gt;
ssid=Whatever&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_passphrase=YouMakeItUp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
auto lo&amp;lt;br&amp;gt;&lt;br /&gt;
iface lo inet loopback&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto eth0&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth0 inet dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
        hostname ANYNAME&amp;lt;br&amp;gt;&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth1 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
iface wlan0 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto br0&amp;lt;br&amp;gt;&lt;br /&gt;
iface br0 inet static&amp;lt;br&amp;gt;&lt;br /&gt;
        pre-up ifconfig eth1 up&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-ports eth1 wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-stp off&amp;lt;br&amp;gt;&lt;br /&gt;
        address 192.168.0.3&amp;lt;br&amp;gt;&lt;br /&gt;
        broadcaset 192.168.1.255&amp;lt;br&amp;gt;&lt;br /&gt;
        netmask 255.255.255.0&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! This has no protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&amp;lt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create and index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi_Zero_W_-_Installation|PiZeroW Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18455</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18455"/>
		<updated>2021-01-03T13:46:25Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise. That is 13G of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple, short, and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* Find a microsd (or HDD) you can wipe. We will assume it is /dev/sdc.&lt;br /&gt;
* make a 256M fat16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* the rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all files to the fat16 partition which is good for up to 2G. &lt;br /&gt;
* make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
This has two subnets. One for normal dhcp, the other for pseudo static - dhcp provided by MAC. One example here.&amp;lt;br&amp;gt;&lt;br /&gt;
interface=br0&amp;lt;br&amp;gt;&lt;br /&gt;
except-interface=eth0&amp;lt;br&amp;gt;&lt;br /&gt;
dhcp-range=subnet0,192.168.0.10,192.168.0.100,255.255.255.0,24h&amp;lt;br&amp;gt;&lt;br /&gt;
dhcp-range=subnet1,192.168.0.4,192.168.0.6,255.255.255.0,24h&amp;lt;br&amp;gt;&lt;br /&gt;
bind-interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
#log-queries&amp;lt;br&amp;gt;&lt;br /&gt;
#log-dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
dhcp-host=70:85:66:c4:48:55,192.168.0.4,nas&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== /etc/hosts =====&lt;br /&gt;
dnsmasq provides DNS answers from the hosts file. Nice. &amp;lt;br&amp;gt;&lt;br /&gt;
127.0.0.1	localhost localhost.localdomain&amp;lt;br&amp;gt;&lt;br /&gt;
::1		localhost localhost.localdomain&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.3     wireless&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.4     nas&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.0.5     mpd&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
bridge=br0&amp;lt;br&amp;gt;&lt;br /&gt;
hw_mode=g&amp;lt;br&amp;gt;&lt;br /&gt;
channel=7&amp;lt;br&amp;gt;&lt;br /&gt;
wmm_enabled=0&amp;lt;br&amp;gt;&lt;br /&gt;
macaddr_acl=0&amp;lt;br&amp;gt;&lt;br /&gt;
auth_algs=1&amp;lt;br&amp;gt;&lt;br /&gt;
ignore_broadcast_ssid=0&amp;lt;br&amp;gt;&lt;br /&gt;
wpa=2&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_pairwise=TKIP&amp;lt;br&amp;gt;&lt;br /&gt;
rsn_pairwise=CCMP&amp;lt;br&amp;gt;&lt;br /&gt;
ssid=Whatever&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_passphrase=YouMakeItUp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
auto lo&amp;lt;br&amp;gt;&lt;br /&gt;
iface lo inet loopback&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto eth0&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth0 inet dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
        hostname ANYNAME&amp;lt;br&amp;gt;&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth1 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
iface wlan0 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto br0&amp;lt;br&amp;gt;&lt;br /&gt;
iface br0 inet static&amp;lt;br&amp;gt;&lt;br /&gt;
        pre-up ifconfig eth1 up&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-ports eth1 wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-stp off&amp;lt;br&amp;gt;&lt;br /&gt;
        address 192.168.0.3&amp;lt;br&amp;gt;&lt;br /&gt;
        broadcaset 192.168.1.255&amp;lt;br&amp;gt;&lt;br /&gt;
        netmask 255.255.255.0&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! This has no protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&amp;lt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create and index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi_Zero_W_-_Installation|PiZeroW Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18452</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18452"/>
		<updated>2021-01-03T13:06:09Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise. That is 13G of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple, short, and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* Find a microsd (or HDD) you can wipe. We will assume it is /dev/sdc.&lt;br /&gt;
* make a 256M fat16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* the rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all files to the fat16 partition which is good for up to 2G. &lt;br /&gt;
* make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=br0&amp;lt;br&amp;gt;&lt;br /&gt;
except-interface=eth0&amp;lt;br&amp;gt;&lt;br /&gt;
dhcp-range=192.168.0.10,192.168.0.100,255.255.255.0,24h&amp;lt;br&amp;gt;&lt;br /&gt;
bind-interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
#log-queries&amp;lt;br&amp;gt;&lt;br /&gt;
#log-dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
bridge=br0&amp;lt;br&amp;gt;&lt;br /&gt;
hw_mode=g&amp;lt;br&amp;gt;&lt;br /&gt;
channel=7&amp;lt;br&amp;gt;&lt;br /&gt;
wmm_enabled=0&amp;lt;br&amp;gt;&lt;br /&gt;
macaddr_acl=0&amp;lt;br&amp;gt;&lt;br /&gt;
auth_algs=1&amp;lt;br&amp;gt;&lt;br /&gt;
ignore_broadcast_ssid=0&amp;lt;br&amp;gt;&lt;br /&gt;
wpa=2&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_pairwise=TKIP&amp;lt;br&amp;gt;&lt;br /&gt;
rsn_pairwise=CCMP&amp;lt;br&amp;gt;&lt;br /&gt;
ssid=Whatever&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_passphrase=YouMakeItUp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
auto lo&amp;lt;br&amp;gt;&lt;br /&gt;
iface lo inet loopback&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto eth0&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth0 inet dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
        hostname ANYNAME&amp;lt;br&amp;gt;&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth1 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
iface wlan0 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto br0&amp;lt;br&amp;gt;&lt;br /&gt;
iface br0 inet static&amp;lt;br&amp;gt;&lt;br /&gt;
        pre-up ifconfig eth1 up&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-ports eth1 wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-stp off&amp;lt;br&amp;gt;&lt;br /&gt;
        address 192.168.0.3&amp;lt;br&amp;gt;&lt;br /&gt;
        broadcaset 192.168.1.255&amp;lt;br&amp;gt;&lt;br /&gt;
        netmask 255.255.255.0&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Permissive iptables =====&lt;br /&gt;
Do NOT use this connected to the internet! This has no protection.&amp;lt;br&amp;gt;&lt;br /&gt;
This is my stopopen in my replacement iptables&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P INPUT ACCEPT&amp;lt;br&amp;gt;&amp;lt;&lt;br /&gt;
iptables -F INPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P OUTPUT ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F OUTPUT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -P FORWARD ACCEPT&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F FORWARD&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F -t nat&amp;lt;br&amp;gt;&lt;br /&gt;
iptables -F&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== References ===&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create and index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi_Zero_W_-_Installation|PiZeroW Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18451</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18451"/>
		<updated>2021-01-03T12:52:11Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise. That is 13G of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple, short, and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* Find a microsd (or HDD) you can wipe. We will assume it is /dev/sdc.&lt;br /&gt;
* make a 256M fat16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* the rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all files to the fat16 partition which is good for up to 2G. &lt;br /&gt;
* make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== dnsmasq.conf =====&lt;br /&gt;
/etc/dnsmasq.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=br0&amp;lt;br&amp;gt;&lt;br /&gt;
except-interface=eth0&amp;lt;br&amp;gt;&lt;br /&gt;
dhcp-range=192.168.0.10,192.168.0.100,255.255.255.0,24h&amp;lt;br&amp;gt;&lt;br /&gt;
bind-interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
#log-queries&amp;lt;br&amp;gt;&lt;br /&gt;
#log-dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== hostapd.conf =====&lt;br /&gt;
/etc/hostapd/hostapd.conf&amp;lt;br&amp;gt;&lt;br /&gt;
interface=wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
bridge=br0&amp;lt;br&amp;gt;&lt;br /&gt;
hw_mode=g&amp;lt;br&amp;gt;&lt;br /&gt;
channel=7&amp;lt;br&amp;gt;&lt;br /&gt;
wmm_enabled=0&amp;lt;br&amp;gt;&lt;br /&gt;
macaddr_acl=0&amp;lt;br&amp;gt;&lt;br /&gt;
auth_algs=1&amp;lt;br&amp;gt;&lt;br /&gt;
ignore_broadcast_ssid=0&amp;lt;br&amp;gt;&lt;br /&gt;
wpa=2&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_key_mgmt=WPA-PSK&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_pairwise=TKIP&amp;lt;br&amp;gt;&lt;br /&gt;
rsn_pairwise=CCMP&amp;lt;br&amp;gt;&lt;br /&gt;
ssid=Whatever&amp;lt;br&amp;gt;&lt;br /&gt;
wpa_passphrase=YouMakeItUp&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== interfaces =====&lt;br /&gt;
/etc/network/interfaces&amp;lt;br&amp;gt;&lt;br /&gt;
auto lo&amp;lt;br&amp;gt;&lt;br /&gt;
iface lo inet loopback&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto eth0&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth0 inet dhcp&amp;lt;br&amp;gt;&lt;br /&gt;
        hostname ANYNAME&amp;lt;br&amp;gt;&lt;br /&gt;
        hwaddress ether FE:ED:BE:EF:33:DD&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
iface eth1 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
iface wlan0 inet manual&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
auto br0&amp;lt;br&amp;gt;&lt;br /&gt;
iface br0 inet static&amp;lt;br&amp;gt;&lt;br /&gt;
        pre-up ifconfig eth1 up&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-ports eth1 wlan0&amp;lt;br&amp;gt;&lt;br /&gt;
        bridge-stp off&amp;lt;br&amp;gt;&lt;br /&gt;
        address 192.168.0.3&amp;lt;br&amp;gt;&lt;br /&gt;
        broadcaset 192.168.1.255&amp;lt;br&amp;gt;&lt;br /&gt;
        netmask 255.255.255.0&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create and index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi_Zero_W_-_Installation|PiZeroW Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18450</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18450"/>
		<updated>2021-01-03T12:43:47Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise. That is 13G of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple, short, and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct, but I can install).&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* Find a microsd (or HDD) you can wipe. We will assume it is /dev/sdc.&lt;br /&gt;
* make a 256M fat16 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* the rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all files to the fat16 partition which is good for up to 2G. &lt;br /&gt;
* make sure you have all the packages from the package list below installed on the SD card. This will save you lots of time.&lt;br /&gt;
* install openssh, openssh-server, openssh-client, openssh-server-common,&lt;br /&gt;
* install dnsmasq, ethtool, hostapd*, busybox extras, iptables*, iw,net-tools, tree, wireless-tools.&lt;br /&gt;
&lt;br /&gt;
===== ssh config =====&lt;br /&gt;
The allowed users are not normal names since I want the names to be a little obfuscated. Not that it really matters, since this is a key driven setup&amp;lt;br&amp;gt;&lt;br /&gt;
AddressFamily inet&amp;lt;br&amp;gt;&lt;br /&gt;
ListenAddress 0.0.0.0&amp;lt;br&amp;gt;&lt;br /&gt;
HostKey /etc/ssh/ssh_host_rsa_key&amp;lt;br&amp;gt;&lt;br /&gt;
LogLevel INFO&amp;lt;br&amp;gt;&lt;br /&gt;
LoginGraceTime 30&amp;lt;br&amp;gt;&lt;br /&gt;
PermitRootLogin no&amp;lt;br&amp;gt;&lt;br /&gt;
StrictModes yes&amp;lt;br&amp;gt;&lt;br /&gt;
AllowUsers Som123X Extern4524User&amp;lt;br&amp;gt;&lt;br /&gt;
PubkeyAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
AuthorizedKeysFile	/etc/ssh/authorized_keys&amp;lt;br&amp;gt;&lt;br /&gt;
HostbasedAuthentication yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreUserKnownHosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
IgnoreRhosts yes&amp;lt;br&amp;gt;&lt;br /&gt;
PasswordAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
ChallengeResponseAuthentication no&amp;lt;br&amp;gt;&lt;br /&gt;
AllowTcpForwarding yes&amp;lt;br&amp;gt;&lt;br /&gt;
GatewayPorts yes&amp;lt;br&amp;gt;&lt;br /&gt;
X11Forwarding no&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create and index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repository lists are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/504100/how-to-create-ssh-reverse-tunnel-with-iptables-forwarding Reverse SSH tunnel]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi_Zero_W_-_Installation|PiZeroW Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Package List ====&lt;br /&gt;
Put these in the apks/armhf directory on the 256M Fat partition:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
iptables-1.8.4-r2.apk                       openssh-8.3_p1-r1.apk&lt;br /&gt;
iptables-openrc-1.8.4-r2.apk                openssh-client-8.3_p1-r1.apk&lt;br /&gt;
abuild-3.6.0-r1.apk                         iw-5.4-r0.apk                               openssh-keygen-8.3_p1-r1.apk&lt;br /&gt;
alpine-base-3.12.3-r0.apk                   kbd-bkeymaps-2.2.0-r2.apk                   openssh-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-baselayout-3.2.0-r7.apk              libacl-2.2.53-r0.apk                        openssh-server-common-8.3_p1-r1.apk&lt;br /&gt;
alpine-conf-3.9.0-r1.apk                    libattr-2.4.48-r0.apk                       openssh-sftp-server-8.3_p1-r1.apk&lt;br /&gt;
alpine-keys-2.2-r0.apk                      libblkid-2.35.2-r0.apk                      openssl-1.1.1i-r0.apk&lt;br /&gt;
alpine-mirrors-3.5.10-r0.apk                libc-utils-0.7.2-r3.apk                     patch-2.7.6-r6.apk&lt;br /&gt;
apk-tools-2.10.5-r1.apk                     libcap-2.27-r0.apk                          pcsc-lite-libs-1.8.26-r0.apk&lt;br /&gt;
attr-2.4.48-r0.apk                          libcom_err-1.45.6-r0.apk                    pkgconf-1.7.2-r0.apk&lt;br /&gt;
bash-5.0.17-r0.apk                          libcrypto1.1-1.1.1i-r0.apk                  ppp-atm-2.4.8-r2.apk&lt;br /&gt;
bash-completion-2.10-r0.apk                 libcurl-7.69.1-r3.apk                       ppp-chat-2.4.8-r2.apk&lt;br /&gt;
bonding-2.6-r4.apk                          libedit-20191231.3.1-r0.apk                 ppp-daemon-2.4.8-r2.apk&lt;br /&gt;
bridge-1.5-r4.apk                           libev-4.33-r0.apk                           ppp-l2tp-2.4.8-r2.apk&lt;br /&gt;
bridge-utils-1.6-r0.apk                     libgcc-9.3.0-r2.apk                         ppp-minconn-2.4.8-r2.apk&lt;br /&gt;
busybox-1.31.1-r19.apk                      libmnl-1.0.4-r0.apk                         ppp-passprompt-2.4.8-r2.apk&lt;br /&gt;
busybox-extras-1.31.1-r19.apk               libnftnl-1.1.6-r0.apk                       ppp-passwordfd-2.4.8-r2.apk&lt;br /&gt;
busybox-initscripts-3.2-r2.apk              libnftnl-libs-1.1.6-r0.apk                  ppp-pppoe-2.4.8-r2.apk&lt;br /&gt;
busybox-suid-1.31.1-r19.apk                 libnl3-3.5.0-r0.apk                         ppp-radius-2.4.8-r2.apk&lt;br /&gt;
c-ares-1.16.1-r0.apk                        libpcap-1.9.1-r2.apk                        ppp-winbind-2.4.8-r2.apk&lt;br /&gt;
ca-certificates-20191127-r4.apk             libssl1.1-1.1.1i-r0.apk                     readline-8.0.4-r0.apk&lt;br /&gt;
ca-certificates-bundle-20191127-r4.apk      libstdc++-9.3.0-r2.apk                      scanelf-1.2.6-r0.apk&lt;br /&gt;
chrony-3.5.1-r0.apk                         libtls-standalone-2.9.1-r1.apk              signature.tar.gz&lt;br /&gt;
chrony-openrc-3.5.1-r0.apk                  libusb-1.0.23-r0.apk                        ssl_client-1.31.1-r19.apk&lt;br /&gt;
curl-7.69.1-r3.apk                          libuuid-2.35.2-r0.apk                       tar-1.32-r1.apk&lt;br /&gt;
dbus-libs-1.12.18-r0.apk                    lzip-1.21-r0.apk                            tcpdump-4.9.3-r2.apk&lt;br /&gt;
dnsmasq-2.81-r0.apk                         mii-tool-1.60_git20140218-r2.apk            tree-1.8.0-r0.apk&lt;br /&gt;
e2fsprogs-1.45.6-r0.apk                     musl-1.1.24-r10.apk                         tzdata-2020c-r1.apk&lt;br /&gt;
e2fsprogs-libs-1.45.6-r0.apk                musl-utils-1.1.24-r10.apk                   usb-modeswitch-2.6.0-r1.apk&lt;br /&gt;
ethtool-5.6-r0.apk                          ncurses-libs-6.2_p20200523-r0.apk           vlan-2.2-r0.apk&lt;br /&gt;
ez-ipupdate-3.0.10-r9.apk                   ncurses-terminfo-base-6.2_p20200523-r0.apk  wireless-tools-30_pre9-r1.apk&lt;br /&gt;
fakeroot-1.24-r0.apk                        net-tools-1.60_git20140218-r2.apk           wpa_supplicant-2.9-r5.apk&lt;br /&gt;
haveged-1.9.8-r1.apk                        network-extras-1.2-r0.apk                   wpa_supplicant-openrc-2.9-r5.apk&lt;br /&gt;
haveged-openrc-1.9.8-r1.apk                 nghttp2-1.41.0-r0.apk                       zlib-1.2.11-r3.apk&lt;br /&gt;
hostapd-2.9-r2.apk                          nghttp2-libs-1.41.0-r0.apk&lt;br /&gt;
hostapd-openrc-2.9-r2.apk                   openrc-0.42.1-r11.apk&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18449</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18449"/>
		<updated>2021-01-03T04:22:32Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise. That is 13G of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple, short, and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct).&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
* Find a microsd (or HDD) you can wipe. We will assume it is /dev/sdc.&lt;br /&gt;
* make a 256M fat16/fat23 partition (sudo mkfs.vfat -n ALPBOOT /dev/sdc1)&lt;br /&gt;
* the rest of the device can be ext2 (ext3/4 on HDD) (sudo mke2fs -m1 -L alext3 /dev/sdc2).&lt;br /&gt;
* untar the alpine-rpi-3.12.3-armhf.tar.gz and copy all files to the fat16/32 partition 16 is good for up 2 2G. &lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create and index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repositories are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
[https://en.wikipedia.org/wiki/File_Allocation_Table FAT16/32 limits]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://stevessmarthomeguide.com/home-network-dns-dnsmasq Set Static DNS names]&amp;lt;br&amp;gt;&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi_Zero_W_-_Installation|PiZeroW Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18447</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18447"/>
		<updated>2021-01-02T22:48:24Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The intent is to provide this:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;eth1 &amp;lt;--&amp;gt;| &lt;br /&gt;
Internet &amp;lt;--&amp;gt; eth0 &amp;lt;--&amp;gt;FireWall&amp;lt;--&amp;gt;br0           Internal&amp;lt;--&amp;gt; ssh,bind,dhcp, with ssh reverse ssh connections.&lt;br /&gt;
                                    |&amp;lt;--&amp;gt;wlan0&amp;lt;--&amp;gt;|&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by Red Hot Irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise. That is 13G of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
* It is simple, short, and to the point.&lt;br /&gt;
* The same tool provides *repo* level dependency reporting!&lt;br /&gt;
* Install of single packages without repo signing (I never did get the signing correct).&lt;br /&gt;
&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
apk notes:&lt;br /&gt;
&lt;br /&gt;
* Create and index and check dependencies on a list of apk files: apk index -o APKINDEX.unsigned.tar.gz *.apk&lt;br /&gt;
* Install a package: apk add iw OR apk add /path/to/iw-5.4-r0.apk&lt;br /&gt;
* remove a package: apk del iw&lt;br /&gt;
* repositories are in: /etc/apk/repositories&lt;br /&gt;
  * Local URL: /media/mmcblk0p1/apks&lt;br /&gt;
  * Remote URL: http://dl-cdn.alpinelinux.org/alpine/v3.12/main&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi_Zero_W_-_Installation|PiZeroW Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18446</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18446"/>
		<updated>2021-01-02T22:36:44Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Pi Zero W Wireless Router */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
=== Overview ===&lt;br /&gt;
I generally run Debian and  when forced by red hot irons, Red Hat. This is my first foray into Alpine. So far I am very impressed. I mirrored the 3.12 armhf repos so I had things local when I needed them. Word to the wise. That is 13G of apk files.&amp;lt;br&amp;gt;&lt;br /&gt;
One *really* nice feature of Alpine is apk, the yum/apt replacement:&amp;lt;br&amp;gt;&lt;br /&gt;
It is simple, short, and to the point.&lt;br /&gt;
=== Install ===&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[rsync://rsync.alpinelinux.org/alpine Alpine Repos]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi_Zero_W_-_Installation|PiZeroW Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Classic_install_or_sys_mode_on_Raspberry_Pi|Classic Sys Install on Pi]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18445</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18445"/>
		<updated>2021-01-02T22:27:37Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://wiki.archlinux.org/index.php/IPv6#Disable_IPv6 Disable IPV6]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://github.com/imp/dnsmasq/blob/master/dnsmasq.conf.example dnsmasq Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://man.openbsd.org/hostapd.conf.5 HostApd Docs]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Raspberry_Pi|Alpine Install]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18444</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18444"/>
		<updated>2021-01-02T22:22:40Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://unix.stackexchange.com/questions/222264/how-do-i-limit-dnsmasq-listening-to-only-one-interface dnsmasq listen restrictions]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/81486/raspberry-pi-wifi-to-ethernet-bridge-for-a-server/81518 WiFi Bridge]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18443</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18443"/>
		<updated>2021-01-02T22:20:05Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&amp;lt;br&amp;gt;&lt;br /&gt;
[[Connecting_to_a_wireless_access_point|Connect to wireless AP]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Pi Specific =====&lt;br /&gt;
[https://raspberrypi.stackexchange.com/questions/89803/access-point-as-wifi-router-repeater-optional-with-bridge/89804 Pi Wifi Repeater]&amp;lt;br&amp;gt;&lt;br /&gt;
==== Not Related, but Interesting ====&lt;br /&gt;
[https://blog.thewalr.us/2017/09/26/raspberry-pi-zero-w-simultaneous-ap-and-managed-mode-wifi AP and Managed Mode]&amp;lt;br&amp;gt;&lt;br /&gt;
[https://www.instructables.com/Using-a-Raspberry-PI-Zero-W-As-an-Access-Point-and AP and MQTT]&amp;lt;br&amp;gt;&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18442</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18442"/>
		<updated>2021-01-02T22:13:01Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&lt;br /&gt;
[[https://udhcp.busybox.net/README.udhcpc udhcpc]]&lt;br /&gt;
[[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]]&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18441</id>
		<title>How to set up Alpine as a wireless router</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=How_to_set_up_Alpine_as_a_wireless_router&amp;diff=18441"/>
		<updated>2021-01-02T22:12:36Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: Created page with &amp;quot;=== Pi Zero W Wireless Router ===  This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the in...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Pi Zero W Wireless Router ===&lt;br /&gt;
&lt;br /&gt;
This is a page to describe building a Wireless Access Point with two wired ethernet ports for building a home router that connects to the internet with one wired port, and internal Lan with the second wired port and the on-board WiFi.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== References ====&lt;br /&gt;
&lt;br /&gt;
[https://udhcp.busybox.net/README.udhcpc udhcpc]&lt;br /&gt;
[https://linux.die.net/man/8/ez-ipupdate ez-ipupdate]&lt;br /&gt;
[[Alpine_Linux:FAQ#Dynamic_DNS|Dynamic_DNS]]&lt;br /&gt;
[[Bridge|Alpine Linux Bridge]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=18440</id>
		<title>Tutorials and Howtos</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Tutorials_and_Howtos&amp;diff=18440"/>
		<updated>2021-01-02T21:47:26Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: /* Networking */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Todo|This material needs to be re-organized .. as &#039;&#039;&#039;Howtos are smaller articles&#039;&#039;&#039; and &#039;&#039;&#039;tutorials are more detailed document&#039;&#039;&#039; both need to be reordered as independent sections }}&lt;br /&gt;
&lt;br /&gt;
[[Image:package_edutainment.svg|right|link=]]&lt;br /&gt;
{{TOC left}}&lt;br /&gt;
&#039;&#039;&#039;Welcome to Tutorials and Howtos, a place of basic and advanced configuration tasks for your Alpine Linux.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The tutorials are hands-on&#039;&#039;&#039; and the reader is expected to try and achieve the goals described in each step, possibly with the help of a good example. The output in one step is the starting point for the following step.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Howtos are smaller articles&#039;&#039;&#039; explaining how to perform a particular task with Alpine Linux, that expects a minimal knowledge from reader to perform actions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT:&#039;&#039;&#039; contributions on those pages must be complete articles as well as requesting topics to be covered, don&#039;t override already made contributions. If you want to request a topic, please add your request in this page&#039;s [[Talk:Tutorials_and_Howtos|Discussion]].&lt;br /&gt;
&lt;br /&gt;
-----------------------------------------------------------------&lt;br /&gt;
&lt;br /&gt;
All of &#039;&#039;&#039;those linked pages here will help you make many things&#039;&#039;&#039; over the Alpine &#039;&#039;&#039;O&#039;&#039;&#039;perating &#039;&#039;&#039;S&#039;&#039;&#039;ystem or Alpine &#039;&#039;&#039;OS&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Alpine are the main program named &#039;&#039;&#039;OS&#039;&#039;&#039; (means Operating System), that&#039;s runs on top of the &#039;&#039;&#039;machine/PC/laptop&#039;&#039;&#039;, and subsequently over this &#039;&#039;&#039;OS&#039;&#039;&#039; run the programs such like the internet web browser ({{Pkg|firefox}}, {{Pkg|chromium}}), and the web pages like &amp;quot;facebook&amp;quot; runs over that internet web browser.&lt;br /&gt;
&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
== New users and Newbies ==&lt;br /&gt;
&lt;br /&gt;
* [[Newbie Alpine Ecosystem]] (for overall information in funny sections)&lt;br /&gt;
&lt;br /&gt;
==== Installation: Use cases ====&lt;br /&gt;
&lt;br /&gt;
* [[Alpine newbie install manual]]&lt;br /&gt;
** [[Alpine Install: from a disc to a new computer single only boot]]&lt;br /&gt;
** [[Alpine Install: from a disc to a old computer single only boot]]&lt;br /&gt;
** [[Alpine Install: from a disc to a virtualbox machine single only]]&lt;br /&gt;
** [[Alpine Install: from a iso to a virtualbox machine with external disc]]&lt;br /&gt;
* [[Alpine_newbie_install_manual#Ways_to_install_Alpine_listed_by_architectures|Ways to install listed by architectures]]&lt;br /&gt;
** [[Alpine_newbie_install_manual#x86_64_x86_32_x86|x86_64 x86_32 x86 s390]]&lt;br /&gt;
** [[Alpine_newbie_install_manual#armhf_armv7|armhf armv7 aarch64]]&lt;br /&gt;
** [[Alpine_newbie_install_manual#ppc64le|ppc64le others PPC]]&lt;br /&gt;
&lt;br /&gt;
==== Postinstall: desktops and applications ====&lt;br /&gt;
&lt;br /&gt;
* [[Alpine newbie apk packages|Overall info and minimal packages common to any working desktop]]&lt;br /&gt;
** [[Alpine newbie desktops|Alpine newbie desktops, (overall information only)]]&lt;br /&gt;
** [[Alpine Newbies XFCE Desktop Environment]]&lt;br /&gt;
** [[Alpine Newbies LXDE Desktop Environment]]&lt;br /&gt;
** [[Alpine Newbies Openbox Window Manager|Alpine Newbies Xorg and Openbox Window Manager]]&lt;br /&gt;
** [[MATE|Alpine Newbies MATE Desktop Environment]]&lt;br /&gt;
* [[Alpine and UEFI|Alpine and UEFI Support Status and related topics]]&lt;br /&gt;
&lt;br /&gt;
==== Developers: compilers, IDE&#039;s and tools ====&lt;br /&gt;
&lt;br /&gt;
* [[Alpine newbie developer]]&lt;br /&gt;
** [[Alpine_newbie_developer: gitea|Alpine_newbie_developer: Git management web frontend gitea]]&lt;br /&gt;
** [[Alpine newbie developer: full stack web]]&lt;br /&gt;
&lt;br /&gt;
==== Servers: deploy in production ====&lt;br /&gt;
&lt;br /&gt;
* [[Alpine production deploy]]&lt;br /&gt;
** [[Production Web server: Lighttpd‎‎]]&lt;br /&gt;
** [[Production DataBases : mysql]]&lt;br /&gt;
** [[Production LAMP system: Lighttpd + PHP + MySQL‎‎]]&lt;br /&gt;
* Alpine production monitoring&lt;br /&gt;
** [[Cacti: traffic analysis and monitoring network]]&lt;br /&gt;
&lt;br /&gt;
== Storage ==&lt;br /&gt;
&lt;br /&gt;
* [[Alpine local backup|Alpine local backup (lbu)]] &#039;&#039;(Permanently store your modifications in case your box needs reboot)&#039;&#039; &amp;lt;!-- Installation and Storage --&amp;gt;&lt;br /&gt;
** [[Back Up a Flash Memory Installation]] &amp;lt;!-- Installation and Storage --&amp;gt;&lt;br /&gt;
** [[Manually editing a existing apkovl]]&lt;br /&gt;
&lt;br /&gt;
* [[Setting up disks manually]] &amp;lt;!-- Installation and Storage --&amp;gt;&lt;br /&gt;
* [[Setting up a software RAID array]]&lt;br /&gt;
&amp;lt;!-- ** [[Setting up a /var partition on software IDE raid1]]  Obsolete, Installation and Storage --&amp;gt; &lt;br /&gt;
* [[Raid Administration]]&lt;br /&gt;
* [[Setting up encrypted volumes with LUKS]]&lt;br /&gt;
* [[Setting up LVM on LUKS]]&lt;br /&gt;
* [[Setting up Logical Volumes with LVM]]&lt;br /&gt;
** [[Setting up LVM on GPT-labeled disks]]&lt;br /&gt;
** [[Installing on GPT LVM]]&lt;br /&gt;
* [[Filesystems|Formatting HD/Floppy/Other]] &amp;lt;!-- just a stub --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Setting up iSCSI]]&lt;br /&gt;
** [[iSCSI Raid and Clustered File Systems]]&lt;br /&gt;
* [[Setting up NBD]]&lt;br /&gt;
* [[Setting up ZFS on LUKS]]&lt;br /&gt;
* [[Setting up ZFS with native encryption]]&lt;br /&gt;
* [[High performance SCST iSCSI Target on Linux software Raid]] &#039;&#039;(deprecated)&#039;&#039; &amp;lt;!-- solution --&amp;gt;&lt;br /&gt;
* [[Linux iSCSI Target (TCM)]]&lt;br /&gt;
* [[Disk Replication with DRBD]] &amp;lt;!-- draft --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Burning ISOs]] &amp;lt;!-- just some links now --&amp;gt;&lt;br /&gt;
* [[Partitioning and Bootmanagers]]&lt;br /&gt;
* [[Migrating data]]&lt;br /&gt;
* [[Create a bootable SDHC from a Mac]]&lt;br /&gt;
* [[Alpine on ARM]]&lt;br /&gt;
&lt;br /&gt;
== Networking ==&lt;br /&gt;
&lt;br /&gt;
* [[Configure Networking]]&lt;br /&gt;
* [[Connecting to a wireless access point]]&lt;br /&gt;
* [[Bonding]]&lt;br /&gt;
* [[Vlan]]&lt;br /&gt;
* [[Bridge]]&lt;br /&gt;
* [[Bridge wlan0 to eth0]]&lt;br /&gt;
* [[OpenVSwitch]]&lt;br /&gt;
* [[How to configure static routes]]&lt;br /&gt;
* [[Configure a Wireguard interface (wg)]]&lt;br /&gt;
&lt;br /&gt;
* [[Alpine Wall]] - [[How-To Alpine Wall]] - [[Alpine Wall User&#039;s Guide]] &#039;&#039;(a new firewall management framework)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[PXE boot]]&lt;br /&gt;
&lt;br /&gt;
* [[Using serial modem]]&lt;br /&gt;
* [[Using HSDPA modem]]&lt;br /&gt;
* [[Setting up Satellite Internet Connection]]&lt;br /&gt;
* [[Using Alpine on Windows domain with IPSEC isolation]]&lt;br /&gt;
&lt;br /&gt;
* [[Setting up a ssh-server]] &#039;&#039;(Using ssh is a good way to administer your box remotely)&#039;&#039; &amp;lt;!-- Server and Networking --&amp;gt;&lt;br /&gt;
* [[How to setup a wireless access point]] &#039;&#039;(Setting up Secure Wireless AP w/ WPA encryption with bridge to wired network)&#039;&#039;&lt;br /&gt;
* [[How to set up Alpine as a wireless router]] &#039;&#039;(Setting up a firewalled, Wireless AP with wired network on a Pi Zero W)&#039;&#039;&lt;br /&gt;
* [[Setting up a OpenVPN server with Alpine]] &#039;&#039;(Allowing single users or devices to remotely connect to your network)&#039;&#039;&lt;br /&gt;
&amp;lt;!-- [[Using Racoon for Remote Sites]] is a different VPN tunnelling method, but that article is just a stub --&amp;gt;&lt;br /&gt;
* [[Experiences with OpenVPN-client on ALIX.2D3]]  &amp;lt;!-- solution --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Generating SSL certs with ACF]] &amp;lt;!-- Generating SSL certs with ACF 1.9 --&amp;gt;&lt;br /&gt;
* [[Setting up unbound DNS server]]&lt;br /&gt;
* [[Setting up nsd DNS server]]&lt;br /&gt;
* [[TinyDNS Format]]&lt;br /&gt;
* [[Fault Tolerant Routing with Alpine Linux]] &amp;lt;!-- solution --&amp;gt;&lt;br /&gt;
* [[Freeradius Active Directory Integration]]&lt;br /&gt;
* [[Multi_ISP]] &#039;&#039;(Dual-ISP setup with load-balancing and automatic failover)&#039;&#039;&lt;br /&gt;
* [[OwnCloud]] &#039;&#039;(Installing OwnCloud)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[Seafile: setting up your own private cloud]]&lt;br /&gt;
&lt;br /&gt;
* [[GNUnet]]&lt;br /&gt;
&lt;br /&gt;
== Post-Install ==&lt;br /&gt;
&amp;lt;!-- If you edit this, please coordinate with Installation and Developer_Documentation#Package_management.  Note that these three sections are not exact duplicates. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Alpine_newbie_apk_packages|Alpine newbie users post install and easy setups]]&lt;br /&gt;
** [[Alpine_newbie_apk_packages#New_users:_hostname_and_network_wired_connection|First steps at post install]]&lt;br /&gt;
** [[Alpine_newbie_apk_packages#New_users:_common_needed_package_to_install|Enable repositories]]&lt;br /&gt;
** [[Alpine_newbie_apk_packages#New_users:_management_of_users_and_logins|Added the first user to use the system]]&lt;br /&gt;
** [[Alpine_newbie_apk_packages#install_basic_tools|First packages to install]] (need the previous [[Alpine_newbie_apk_packages#New_users:_common_needed_package_to_install|Enable repositories]]) already done!&lt;br /&gt;
&lt;br /&gt;
* [[Setting up a new user]]&lt;br /&gt;
* [[Enable Community Repository]] &#039;&#039;(Providing additional packages)&#039;&#039;&lt;br /&gt;
* [[Alpine Linux package management|Package Management (apk)]] &#039;&#039;(How to add/remove packages on your Alpine)&#039;&#039;&lt;br /&gt;
   &amp;lt;!-- [[Alpine Linux package management#Local_Cache|How to enable APK caching]] --&amp;gt;&lt;br /&gt;
** [[Comparison with other distros]]&lt;br /&gt;
* [[Alpine local backup|Alpine local backup (lbu)]] &#039;&#039;(Permanently store your modifications in case your box needs reboot)&#039;&#039;&lt;br /&gt;
** [[Back Up a Flash Memory Installation]] &amp;lt;!-- new --&amp;gt;&lt;br /&gt;
** [[Manually editing a existing apkovl]]&lt;br /&gt;
* [[Alpine Linux Init System|Init System (OpenRC)]] &#039;&#039;(Configure a service to automatically boot at next reboot)&#039;&#039;&lt;br /&gt;
** [[Multiple Instances of Services]]&lt;br /&gt;
   &amp;lt;!-- [[Writing Init Scripts]] --&amp;gt;&lt;br /&gt;
* [[Alpine setup scripts#setup-xorg-base|Setting up Xorg]]&lt;br /&gt;
* [[Upgrading Alpine]]&lt;br /&gt;
&amp;lt;!-- Obsolete&lt;br /&gt;
 [[Upgrading Alpine - v1.9.x]]&lt;br /&gt;
 [[Upgrading Alpine - CD v1.8.x]]&lt;br /&gt;
 [[Upgrading Alpine - HD v1.8.x]]&lt;br /&gt;
 [[Upgrade to repository main|Upgrading to signed repositories]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Setting up a ssh-server]] &#039;&#039;(Using ssh is a good way to administer your box remotely)&#039;&#039;&lt;br /&gt;
* [[setup-acf]] &#039;&#039;(Configures ACF (webconfiguration) so you can manage your box through https)&#039;&#039;&lt;br /&gt;
* [[Changing passwords for ACF|Changing passwords]]&lt;br /&gt;
* [[Ansible]] &#039;&#039;(Configuration management)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[Enable Serial Console on Boot]]&lt;br /&gt;
&amp;lt;!-- Obsolete?&lt;br /&gt;
* [[Error message on boot: Address space collision: host bridge window conflicts with Adaptor ROM]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [[How to get regular stuff working]] &#039;&#039;some notes on need-to-know topics&#039;&#039;&lt;br /&gt;
* [[Installing Oracle Java]]&lt;br /&gt;
* [[Rsnapshot|Setting up periodic backups with &amp;lt;samp&amp;gt;rsnapshot&amp;lt;/samp&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
== Virtualization==&lt;br /&gt;
&lt;br /&gt;
* [[Xen Dom0]] &#039;&#039;(Setting up Alpine as a dom0 for Xen hypervisor)&#039;&#039;&lt;br /&gt;
* [[Xen Dom0 on USB or SD]]&lt;br /&gt;
* [[Create Alpine Linux PV DomU]]&lt;br /&gt;
* [[Xen PCI Passthrough]]&lt;br /&gt;
* [[Xen LiveCD]]&lt;br /&gt;
* [[qemu]]&lt;br /&gt;
* [[KVM]] &#039;&#039;(Setting up Alpine as a KVM hypervisor)&#039;&#039;&lt;br /&gt;
* [[LXC]] &#039;&#039;(Setting up a Linux container in Alpine Linux)&#039;&#039;&lt;br /&gt;
* [[Docker]]&lt;br /&gt;
* [[Install_Alpine_on_VirtualBox]]&lt;br /&gt;
* [[Install Alpine on VMWare]]&lt;br /&gt;
&lt;br /&gt;
== Desktop Environment ==&lt;br /&gt;
&lt;br /&gt;
* [[Awesome(wm) Setup]]&lt;br /&gt;
* [[dwm]] &#039;&#039;(dynamic window manager for X)&#039;&#039;&lt;br /&gt;
* [[EyeOS]] &#039;&#039;(Cloud Computing Desktop)&#039;&#039;&lt;br /&gt;
* [[Gnome Setup]]&lt;br /&gt;
* [[MATE|MATE Setup]]&lt;br /&gt;
* [[Oneye]] &#039;&#039;(Cloud Computing Desktop - Dropbox Alternative)&#039;&#039;&lt;br /&gt;
* [[Owncloud]] &#039;&#039;(Cloud Computing Desktop - Dropbox Alternative)&#039;&#039;&lt;br /&gt;
** (to be merged with [[OwnCloud]] &#039;&#039;(Your personal Cloud for storing and sharing your data on-line)&#039;&#039;)&lt;br /&gt;
* [[Remote Desktop Server]]&lt;br /&gt;
* [[Suspend on LID close]]&lt;br /&gt;
* [[Sway]]&lt;br /&gt;
* [[XFCE Setup]] and [[Xfce Desktop|Desktop Ideas]]&lt;br /&gt;
* [[Installing Adobe flash player for Firefox]]&lt;br /&gt;
* [[Sound Setup]]&lt;br /&gt;
* [[Printer Setup]]&lt;br /&gt;
* [[Default applications]]&lt;br /&gt;
&lt;br /&gt;
== Raspberry Pi ==&lt;br /&gt;
&lt;br /&gt;
* [[Raspberry Pi|Raspberry Pi (Installation)]]&lt;br /&gt;
* [[Classic install or sys mode on Raspberry Pi]]&lt;br /&gt;
* [[RPI Video Receiver]] &#039;&#039;(network video decoder using Rasperry Pi and omxplayer)&#039;&#039;&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi]]&lt;br /&gt;
* [[Linux Router with VPN on a Raspberry Pi (IPv6)]]&lt;br /&gt;
* [[Raspberry Pi 4 - Persistent system acting as a NAS and Time Machine]]&lt;br /&gt;
* [[Raspberry Pi 3 - Configuring it as wireless access point -AP Mode]]&lt;br /&gt;
* [[Raspberry Pi 3 - Setting Up Bluetooth]]&lt;br /&gt;
* [[Raspberry Pi 3 - Browser Client]]&lt;br /&gt;
* [[Raspberry Pi Zero W - Installation]]&lt;br /&gt;
* [[Raspberry Pi - Headless Installation]]&lt;br /&gt;
&lt;br /&gt;
== PowerPC ==&lt;br /&gt;
&lt;br /&gt;
* [[Ppc64le|Powepc64le (Installation)]]&lt;br /&gt;
&lt;br /&gt;
== IBM Z (IBM z Systems) ==&lt;br /&gt;
&lt;br /&gt;
* [[s390x|s390x (Installation)]]&lt;br /&gt;
&lt;br /&gt;
== Applications ==&lt;br /&gt;
&lt;br /&gt;
=== Telephony ===&lt;br /&gt;
* [[Setting up Zaptel/Asterisk on Alpine]]&lt;br /&gt;
** [[Setting up Streaming an Asterisk Channel]]&lt;br /&gt;
* [[Freepbx on Alpine Linux]]&lt;br /&gt;
* [[FreePBX_V3]] &#039;&#039;(FreeSWITCH, Asterisk GUI web acces tool)&#039;&#039;&lt;br /&gt;
* [[2600hz]] &#039;&#039;(FreeSWITCH, Asterisk GUI web access tool)&#039;&#039;&lt;br /&gt;
* [[Kamailio]] &#039;&#039;(SIP Server, formerly OpenSER)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Mail ===&lt;br /&gt;
* [[Hosting services on Alpine]] &#039;&#039;(Hosting mail, webservices and other services)&#039;&#039;&lt;br /&gt;
** [[Hosting Web/Email services on Alpine]]&lt;br /&gt;
* [[ISP Mail Server HowTo]] &amp;lt;!-- solution, Mail --&amp;gt;&lt;br /&gt;
** [[ISP Mail Server Upgrade 2.x]]&lt;br /&gt;
** [[ISP Mail Server 2.x HowTo]] &#039;&#039;(Beta, please test)&#039;&#039;&lt;br /&gt;
** [[ISP Mail Server 3.x HowTo]]&lt;br /&gt;
* [[Roundcube]] &#039;&#039;(Webmail system)&#039;&#039;&lt;br /&gt;
* [[Setting up postfix with virtual domains]]&lt;br /&gt;
* [[Protecting your email server with Alpine]]&lt;br /&gt;
* [[Setting up clamsmtp]]&lt;br /&gt;
* [[Setting up dovecot with imap and ssl]]&lt;br /&gt;
* [[relay email to gmail (msmtp, mailx, sendmail]]&lt;br /&gt;
&lt;br /&gt;
=== HTTP ===&lt;br /&gt;
* [[Lighttpd]]&lt;br /&gt;
** [[Lighttpd Https access]]&lt;br /&gt;
** [[Setting Up Lighttpd with PHP]]&lt;br /&gt;
** [[Setting Up Lighttpd With FastCGI]]&lt;br /&gt;
* [[Cherokee]]&lt;br /&gt;
* [[Nginx]]&lt;br /&gt;
** [[Nginx_with_PHP#Nginx_with_PHP|Nginx with PHP]]&lt;br /&gt;
** [[Nginx as reverse proxy with acme (letsencrypt)]]&lt;br /&gt;
* [[Apache]]&lt;br /&gt;
** [[Apache with php-fpm]]&lt;br /&gt;
** [[Setting Up Apache with PHP]]&lt;br /&gt;
** [[Apache authentication: NTLM Single Signon]]&lt;br /&gt;
&lt;br /&gt;
* [[High Availability High Performance Web Cache]] &#039;&#039;(uCarp + HAProxy for High Availability Services such as Squid web proxy)&#039;&#039; &amp;lt;!-- solution, Server --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Setting up Transparent Squid Proxy]] &amp;lt;!-- draft --&amp;gt;&lt;br /&gt;
** [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
** [[Obtaining user information via SNMP]] &#039;&#039;(Using squark-auth-snmp as a Squid authentication helper)&#039;&#039; &amp;lt;!-- Networking and Server, &amp;lt;== Using squark-auth-snmp --&amp;gt;&lt;br /&gt;
* [[Setting up Explicit Squid Proxy]]&lt;br /&gt;
&lt;br /&gt;
* [[Drupal]] &#039;&#039;(Content Management System (CMS) written in PHP)&#039;&#039;&lt;br /&gt;
* [[WordPress]] &#039;&#039;(Web software to create website or blog)&#039;&#039;&lt;br /&gt;
* [[MediaWiki]] &#039;&#039;(Free web-based wiki software application)&#039;&#039;&lt;br /&gt;
* [[DokuWiki]]&lt;br /&gt;
* [[Darkhttpd]]&lt;br /&gt;
* [[Tomcat]]&lt;br /&gt;
&lt;br /&gt;
=== Other Servers ===&lt;br /&gt;
* [[Setting up a ssh-server]] &#039;&#039;(Using ssh is a good way to administer your box remotely)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[Setting up a nfs-server]]&lt;br /&gt;
* [[Setting up a samba-server]] &#039;&#039;(standard file sharing)&#039;&#039;&lt;br /&gt;
* [[Setting up a samba-ad-dc]] &#039;&#039;(Active Directory compatible domain controller)&#039;&#039;&lt;br /&gt;
* [[Phpizabi]] &#039;&#039;(Social Networking Platform)&#039;&#039;&lt;br /&gt;
* [[Statusnet]] &#039;&#039;(Microblogging Platform)&#039;&#039;&lt;br /&gt;
* [[Pastebin]] &#039;&#039;(Pastebin software application)&#039;&#039;&lt;br /&gt;
* [[Setting up Transmission (bittorrent) with Clutch WebUI]]&lt;br /&gt;
&lt;br /&gt;
* [[Patchwork]] &#039;&#039;(Patch review management system)&#039;&#039;&lt;br /&gt;
* [[Redmine]] &#039;&#039;(Project management system)&#039;&#039;&lt;br /&gt;
* [[Request-Tracker]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[OsTicket]] &#039;&#039;(Ticket system)&#039;&#039;&lt;br /&gt;
* [[Setting up trac wiki|Trac]] &#039;&#039;(Enhanced wiki and issue tracking system for software development projects)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[Alpine_newbie_developer: gitea|Setting up Git management web frontend gitea]]&lt;br /&gt;
* [[Cgit]]&lt;br /&gt;
** [[Setting up a git repository server with gitolite and cgit]] &amp;lt;!-- doesn&#039;t exist yet --&amp;gt;&lt;br /&gt;
* [[Roundcube]] &#039;&#039;(Webmail system)&#039;&#039;&lt;br /&gt;
* [[Glpi]] &#039;&#039;(Manage inventory of technical resources)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[How to setup a Alpine Linux mirror]]&lt;br /&gt;
* [[Cups]]&lt;br /&gt;
* [[NgIRCd]] &#039;&#039;(Server for Internet Relay Chat/IRC)&#039;&#039;&lt;br /&gt;
* [[How To Setup Your Own IRC Network]] &#039;&#039;(Using {{Pkg|charybdis}} and {{Pkg|atheme-iris}})&#039;&#039;&lt;br /&gt;
* [[OpenVCP]] &#039;&#039;(VServer Control Panel)&#039;&#039;&lt;br /&gt;
* [[Mahara]] &#039;&#039;(E-portfolio and social networking system)&#039;&#039;&lt;br /&gt;
* [[Chrony and GPSD | Using chrony, gpsd, and a garmin LVC 18 as a Stratum 1 NTP source ]]&lt;br /&gt;
* [[Sending SMS using gnokii]]&lt;br /&gt;
* [[IPTV How To|Internet Protocol television (IPTV)]]&lt;br /&gt;
* [[UniFi_Controller]]&lt;br /&gt;
* [[DNSCrypt-Proxy]] &#039;&#039;Encrypt and authenticate DNS calls from your system&#039;&#039;&lt;br /&gt;
* [[Odoo]]&lt;br /&gt;
&lt;br /&gt;
=== Monitoring ===&lt;br /&gt;
* Setting up [[collectd]]&lt;br /&gt;
* [[Traffic monitoring]] &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting up traffic monitoring using rrdtool (and snmp)]] &amp;lt;!-- Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting up monitoring using rrdtool (and rrdcollect)]]&lt;br /&gt;
* [[Cacti: traffic analysis and monitoring network]] &#039;&#039;(Front-end for rrdtool networking monitor)&#039;&#039;&lt;br /&gt;
* [[LTTng]] &#039;&#039;(Kernel and userspace tracing)&#039;&#039;&lt;br /&gt;
* [[Setting up Zabbix|Zabbix]] &#039;&#039;(Monitor and track the status of network services and hardware)&#039;&#039;&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039; &amp;lt;!-- draft, solution, Networking and Monitoring and Server --&amp;gt;&lt;br /&gt;
** [[Setting up NRPE daemon]] &#039;&#039;(Performs remote Nagios checks)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Setting up Smokeping|Smokeping]] &#039;&#039;(Network latency monitoring)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
** [[Setting up MRTG and Smokeping to Monitor Bandwidth Usage and Network Latency]]&lt;br /&gt;
* [[Setting Up Fprobe And Ntop|Ntop]] &#039;&#039;(NetFlow collection and analysis using a remote fprobe instance)&#039;&#039; &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Cvechecker]] &#039;&#039;(Compare installed packages for Common Vulnerabilities Exposure)&#039;&#039; &amp;lt;!-- Monitoring and Security --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[IP Accounting]] &amp;lt;!-- Networking and Monitoring --&amp;gt;&lt;br /&gt;
* [[Obtaining user information via SNMP]] &#039;&#039;(Using squark-auth-snmp as a Squid authentication helper)&#039;&#039; &amp;lt;!-- Networking and Server, &amp;lt;== Using squark-auth-snmp --&amp;gt;&lt;br /&gt;
* [[SqStat]] &#039;&#039;(Script to look at active squid users connections)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[Piwik]] &#039;&#039;(A real time web analytics software program)&#039;&#039;&lt;br /&gt;
* [[Awstats]] &#039;&#039;(Free log file analyzer)&#039;&#039;&lt;br /&gt;
* [[Intrusion Detection using Snort]]&lt;br /&gt;
** [[Intrusion Detection using Snort, Sguil, Barnyard and more]]&lt;br /&gt;
* [[Dglog]] &#039;&#039;(Log analyzer for the web content filter DansGuardian)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [[Webmin]] &#039;&#039;(A web-based interface for Linux system)&#039;&#039;&lt;br /&gt;
* [[PhpPgAdmin]] &#039;&#039;(Web-based administration tool for PostgreSQL)&#039;&#039;&lt;br /&gt;
* [[PhpMyAdmin]] &#039;&#039;(Web-based administration tool for MYSQL)&#039;&#039;&lt;br /&gt;
* [[PhpSysInfo]] &#039;&#039;(A simple application that displays information about the host it&#039;s running on)&#039;&#039;&lt;br /&gt;
* [[Linfo]]&lt;br /&gt;
&lt;br /&gt;
* [[Setting up lm_sensors]]&lt;br /&gt;
&lt;br /&gt;
* [[ZoneMinder video camera security and surveillance]]&lt;br /&gt;
&lt;br /&gt;
== Misc ==&lt;br /&gt;
&lt;br /&gt;
* [[:Category:Shell]]&lt;br /&gt;
* [[:Category:Programming]]&lt;br /&gt;
* [[Running glibc programs]]&lt;br /&gt;
* [[:Category:Drivers]]&lt;br /&gt;
* [[:Category:Multimedia]]&lt;br /&gt;
* [[Kernel Modesetting]]&lt;br /&gt;
* [[CPU frequency scaling]]&lt;br /&gt;
&lt;br /&gt;
== Complete Solutions ==&lt;br /&gt;
* [[DIY Fully working Alpine Linux for Allwinner and Other ARM SOCs]]&lt;br /&gt;
* [[Replacing non-Alpine Linux with Alpine remotely]]&lt;br /&gt;
* [[High performance SCST iSCSI Target on Linux software Raid]]&lt;br /&gt;
* [[Fault Tolerant Routing with Alpine Linux]]&lt;br /&gt;
* [[Experiences with OpenVPN-client on ALIX.2D3]]&lt;br /&gt;
* [[Building a cloud with Alpine Linux]]&lt;br /&gt;
&lt;br /&gt;
* [[ISP Mail Server HowTo]] &#039;&#039;(Postfix+PostfixAdmin+DoveCot+Roundcube+ClamAV+Spamd - A full-serivce ISP mail server)&#039;&#039;&lt;br /&gt;
** [[ISP Mail Server Upgrade 2.x]]&lt;br /&gt;
** [[ISP Mail Server 2.x HowTo]] &#039;&#039;(Beta, please test)&#039;&#039;&lt;br /&gt;
* [[High Availability High Performance Web Cache]] &#039;&#039;(uCarp + HAProxy for High Availability Services such as Squid web proxy)&#039;&#039;&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039; &amp;lt;!-- draft --&amp;gt;&lt;br /&gt;
* [[Streaming Security Camera Video with VLC]]&lt;br /&gt;
* [[Dynamic Multipoint VPN (DMVPN)]] combined with [[Small_Office_Services]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
This does not attempt to be complete. Is it useful to have these listed here? I find them more accessible if grouped with their topics; also, an up-to-date list of all Draft or Obsolete pages can be found at [[Project:Wiki maintenance]].&lt;br /&gt;
&lt;br /&gt;
== Drafts ==&lt;br /&gt;
Currently unfinished/works-in-progress.&lt;br /&gt;
* [[Using Racoon for Remote Sites]]&lt;br /&gt;
* [[Setting up Transparent Squid Proxy]] &#039;&#039;(Covers Squid proxy and URL Filtering system)&#039;&#039;&lt;br /&gt;
** [[Obtaining user information via SNMP]] &#039;&#039;(Using the Squark Squid authentication helper)&#039;&#039; [!-- no longer a draft --]&lt;br /&gt;
* [[Setting up Streaming an Asterisk Channel]]&lt;br /&gt;
* [[Setting up A Network Monitoring and Inventory System]] &#039;&#039;(Nagios + OpenAudit and related components)&#039;&#039;&lt;br /&gt;
* [[Intrusion Detection using Snort]] &#039;&#039;(Installing and configuring Snort and related applications on Alpine 2.0.x)&#039;&#039;&lt;br /&gt;
* [[IP Accounting]] &#039;&#039;(Installing and configuring pmacct for IP Accounting, Netflow/sFlow collector)&#039;&#039;&lt;br /&gt;
* [[Disk Replication with DRBD]]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Newbie]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18439</id>
		<title>Udhcpc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18439"/>
		<updated>2021-01-02T21:43:19Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Expand|Please help us expand this article by contributing.}}&lt;br /&gt;
&lt;br /&gt;
You may want to customize the behavior of the default DHCP client (udhcpc from busybox), which is called by /sbin/ifup by having &amp;quot;dhcp&amp;quot; in /etc/network/interfaces.&lt;br /&gt;
&lt;br /&gt;
The default behavior is driven by the script /usr/share/udhcpc/default.script  &lt;br /&gt;
&lt;br /&gt;
Entries in /etc/network/interfaces for dhcp interfaces will drive the udhcpc command line. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname myhostname&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Will set these parameters on the command line:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;-i eth0 -x hostname:myhostname&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname will send the DHCP option to the server to tell the server the name of this client.  &lt;br /&gt;
&lt;br /&gt;
The documentation resides [https://udhcp.busybox.net/README.udhcpc Here]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Its default configuration may be overwritten by /etc/udhcpc/udhcpc.conf&lt;br /&gt;
&lt;br /&gt;
Authorized key:value pairs are:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;15&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! key&lt;br /&gt;
| default value&lt;br /&gt;
| possible values&lt;br /&gt;
|-&lt;br /&gt;
| NO_GATEWAY&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_METRIC&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;metric value&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_PEER_DNS&lt;br /&gt;
| yes&lt;br /&gt;
| &amp;lt;anything but yes&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| RESOLV_CONF&lt;br /&gt;
| /etc/resolv.conf&lt;br /&gt;
| no ; NO ; -&lt;br /&gt;
|-&lt;br /&gt;
| NO_DNS&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example /etc/udhcpc/udhcpc.conf:&lt;br /&gt;
&lt;br /&gt;
 RESOLV_CONF=&amp;quot;no&amp;quot; # Prevents overwriting of /etc/resolv.conf&lt;br /&gt;
&lt;br /&gt;
Custom scripts can be added as /etc/udhcpc/pre-* and /etc/udhcpc/post-* to be run before/after deconfig/renew/bound DHCP events - they must be marked as &#039;&#039;&#039;executable&#039;&#039;&#039; by root, e.g. chmod 744&lt;br /&gt;
&lt;br /&gt;
As an example, /etc/udhcpc/post-bound/mtu could contain, to change the interface MTU from the default (1500) to 1492, which is useful if [https://en.wikipedia.org/wiki/Maximum_transmission_unit on ADSL] (which uses 8 bytes):&lt;br /&gt;
&lt;br /&gt;
 r=$(/sbin/ip route | grep ^default | head -n 1)&lt;br /&gt;
 # Needs iproute2 package, rather than busybox&#039;s &amp;quot;ip&amp;quot;, to change mtu&lt;br /&gt;
 /sbin/ip route replace $r mtu 1492&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;b&amp;gt;hack alert&amp;lt;/b&amp;gt;&lt;br /&gt;
I needed to restart my firewall (which replaces the iptables script from Alpine) when the client binds to a new IP, so I added the following line in the function bound(), right after &#039;resolvconf&#039;:&amp;lt;br&amp;gt;&lt;br /&gt;
/etc/init.d/iptables reload&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
The reload drops all firewall rules, re-acquires the Internal and external IPs, and re-writes the rules. I&#039;m sure there is a better way.&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Embedded Systems]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18438</id>
		<title>Udhcpc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18438"/>
		<updated>2021-01-02T21:35:30Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Expand|Please help us expand this article by contributing.}}&lt;br /&gt;
&lt;br /&gt;
You may want to customize the behavior of the default DHCP client (udhcpc from busybox), which is called by /sbin/ifup by having &amp;quot;dhcp&amp;quot; in /etc/network/interfaces.&lt;br /&gt;
&lt;br /&gt;
The default behavior is driven by the script /usr/share/udhcpc/default.script  &lt;br /&gt;
&lt;br /&gt;
Entries in /etc/network/interfaces for dhcp interfaces will drive the udhcpc command line. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname myhostname&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Will set these parameters on the command line:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;-i eth0 -x hostname:myhostname&amp;lt;/b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname will send the DHCP option to the server to tell the server the name of this client.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Its default configuration may be overwritten by /etc/udhcpc/udhcpc.conf&lt;br /&gt;
&lt;br /&gt;
Authorized key:value pairs are:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;15&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! key&lt;br /&gt;
| default value&lt;br /&gt;
| possible values&lt;br /&gt;
|-&lt;br /&gt;
| NO_GATEWAY&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_METRIC&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;metric value&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_PEER_DNS&lt;br /&gt;
| yes&lt;br /&gt;
| &amp;lt;anything but yes&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| RESOLV_CONF&lt;br /&gt;
| /etc/resolv.conf&lt;br /&gt;
| no ; NO ; -&lt;br /&gt;
|-&lt;br /&gt;
| NO_DNS&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example /etc/udhcpc/udhcpc.conf:&lt;br /&gt;
&lt;br /&gt;
 RESOLV_CONF=&amp;quot;no&amp;quot; # Prevents overwriting of /etc/resolv.conf&lt;br /&gt;
&lt;br /&gt;
Custom scripts can be added as /etc/udhcpc/pre-* and /etc/udhcpc/post-* to be run before/after deconfig/renew/bound DHCP events - they must be marked as &#039;&#039;&#039;executable&#039;&#039;&#039; by root, e.g. chmod 744&lt;br /&gt;
&lt;br /&gt;
As an example, /etc/udhcpc/post-bound/mtu could contain, to change the interface MTU from the default (1500) to 1492, which is useful if [https://en.wikipedia.org/wiki/Maximum_transmission_unit on ADSL] (which uses 8 bytes):&lt;br /&gt;
&lt;br /&gt;
 r=$(/sbin/ip route | grep ^default | head -n 1)&lt;br /&gt;
 # Needs iproute2 package, rather than busybox&#039;s &amp;quot;ip&amp;quot;, to change mtu&lt;br /&gt;
 /sbin/ip route replace $r mtu 1492&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Embedded Systems]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18437</id>
		<title>Udhcpc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18437"/>
		<updated>2021-01-02T21:35:18Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Expand|Please help us expand this article by contributing.}}&lt;br /&gt;
&lt;br /&gt;
You may want to customize the behavior of the default DHCP client (udhcpc from busybox), which is called by /sbin/ifup by having &amp;quot;dhcp&amp;quot; in /etc/network/interfaces.&lt;br /&gt;
&lt;br /&gt;
The default behavior is driven by the script /usr/share/udhcpc/default.script  &lt;br /&gt;
&lt;br /&gt;
Entries in /etc/network/interfaces for dhcp interfaces will drive the udhcpc command line. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname myhostname&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Will set these parameters on the command line:&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;-i eth0 -x hostname:myhostname&amp;lt;b&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The hostname will send the DHCP option to the server to tell the server the name of this client.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Its default configuration may be overwritten by /etc/udhcpc/udhcpc.conf&lt;br /&gt;
&lt;br /&gt;
Authorized key:value pairs are:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;15&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! key&lt;br /&gt;
| default value&lt;br /&gt;
| possible values&lt;br /&gt;
|-&lt;br /&gt;
| NO_GATEWAY&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_METRIC&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;metric value&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_PEER_DNS&lt;br /&gt;
| yes&lt;br /&gt;
| &amp;lt;anything but yes&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| RESOLV_CONF&lt;br /&gt;
| /etc/resolv.conf&lt;br /&gt;
| no ; NO ; -&lt;br /&gt;
|-&lt;br /&gt;
| NO_DNS&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example /etc/udhcpc/udhcpc.conf:&lt;br /&gt;
&lt;br /&gt;
 RESOLV_CONF=&amp;quot;no&amp;quot; # Prevents overwriting of /etc/resolv.conf&lt;br /&gt;
&lt;br /&gt;
Custom scripts can be added as /etc/udhcpc/pre-* and /etc/udhcpc/post-* to be run before/after deconfig/renew/bound DHCP events - they must be marked as &#039;&#039;&#039;executable&#039;&#039;&#039; by root, e.g. chmod 744&lt;br /&gt;
&lt;br /&gt;
As an example, /etc/udhcpc/post-bound/mtu could contain, to change the interface MTU from the default (1500) to 1492, which is useful if [https://en.wikipedia.org/wiki/Maximum_transmission_unit on ADSL] (which uses 8 bytes):&lt;br /&gt;
&lt;br /&gt;
 r=$(/sbin/ip route | grep ^default | head -n 1)&lt;br /&gt;
 # Needs iproute2 package, rather than busybox&#039;s &amp;quot;ip&amp;quot;, to change mtu&lt;br /&gt;
 /sbin/ip route replace $r mtu 1492&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Embedded Systems]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18436</id>
		<title>Udhcpc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18436"/>
		<updated>2021-01-02T21:34:45Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Expand|Please help us expand this article by contributing.}}&lt;br /&gt;
&lt;br /&gt;
You may want to customize the behavior of the default DHCP client (udhcpc from busybox), which is called by /sbin/ifup by having &amp;quot;dhcp&amp;quot; in /etc/network/interfaces.&lt;br /&gt;
&lt;br /&gt;
The default behavior is driven by the script /usr/share/udhcpc/default.script  &lt;br /&gt;
&lt;br /&gt;
Entries in /etc/network/interfaces for dhcp interfaces will drive the udhcpc command line. For example:&amp;lt;br&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;pre&amp;gt;  &lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname myhostname&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Will set these parameters on the command line:  &lt;br /&gt;
-i eth0 -x hostname:myhostname  &lt;br /&gt;
&lt;br /&gt;
The hostname will send the DHCP option to the server to tell the server the name of this client.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Its default configuration may be overwritten by /etc/udhcpc/udhcpc.conf&lt;br /&gt;
&lt;br /&gt;
Authorized key:value pairs are:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;15&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! key&lt;br /&gt;
| default value&lt;br /&gt;
| possible values&lt;br /&gt;
|-&lt;br /&gt;
| NO_GATEWAY&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_METRIC&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;metric value&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_PEER_DNS&lt;br /&gt;
| yes&lt;br /&gt;
| &amp;lt;anything but yes&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| RESOLV_CONF&lt;br /&gt;
| /etc/resolv.conf&lt;br /&gt;
| no ; NO ; -&lt;br /&gt;
|-&lt;br /&gt;
| NO_DNS&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example /etc/udhcpc/udhcpc.conf:&lt;br /&gt;
&lt;br /&gt;
 RESOLV_CONF=&amp;quot;no&amp;quot; # Prevents overwriting of /etc/resolv.conf&lt;br /&gt;
&lt;br /&gt;
Custom scripts can be added as /etc/udhcpc/pre-* and /etc/udhcpc/post-* to be run before/after deconfig/renew/bound DHCP events - they must be marked as &#039;&#039;&#039;executable&#039;&#039;&#039; by root, e.g. chmod 744&lt;br /&gt;
&lt;br /&gt;
As an example, /etc/udhcpc/post-bound/mtu could contain, to change the interface MTU from the default (1500) to 1492, which is useful if [https://en.wikipedia.org/wiki/Maximum_transmission_unit on ADSL] (which uses 8 bytes):&lt;br /&gt;
&lt;br /&gt;
 r=$(/sbin/ip route | grep ^default | head -n 1)&lt;br /&gt;
 # Needs iproute2 package, rather than busybox&#039;s &amp;quot;ip&amp;quot;, to change mtu&lt;br /&gt;
 /sbin/ip route replace $r mtu 1492&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Embedded Systems]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18435</id>
		<title>Udhcpc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18435"/>
		<updated>2021-01-02T21:33:06Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Expand|Please help us expand this article by contributing.}}&lt;br /&gt;
&lt;br /&gt;
You may want to customize the behavior of the default DHCP client (udhcpc from busybox), which is called by /sbin/ifup by having &amp;quot;dhcp&amp;quot; in /etc/network/interfaces.&lt;br /&gt;
&lt;br /&gt;
The default behavior is driven by the script /usr/share/udhcpc/default.script  &lt;br /&gt;
&lt;br /&gt;
Entries in /etc/network/interfaces for dhcp interfaces will drive the udhcpc command line. For example:  &lt;br /&gt;
  &lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname myhostname&lt;br /&gt;
  &lt;br /&gt;
Will set these parameters on the command line:  &lt;br /&gt;
-i eth0 -x hostname:myhostname  &lt;br /&gt;
&lt;br /&gt;
The hostname will send the DHCP option to the server to tell the server the name of this client.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Its default configuration may be overwritten by /etc/udhcpc/udhcpc.conf&lt;br /&gt;
&lt;br /&gt;
Authorized key:value pairs are:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;15&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! key&lt;br /&gt;
| default value&lt;br /&gt;
| possible values&lt;br /&gt;
|-&lt;br /&gt;
| NO_GATEWAY&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_METRIC&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;metric value&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_PEER_DNS&lt;br /&gt;
| yes&lt;br /&gt;
| &amp;lt;anything but yes&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| RESOLV_CONF&lt;br /&gt;
| /etc/resolv.conf&lt;br /&gt;
| no ; NO ; -&lt;br /&gt;
|-&lt;br /&gt;
| NO_DNS&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example /etc/udhcpc/udhcpc.conf:&lt;br /&gt;
&lt;br /&gt;
 RESOLV_CONF=&amp;quot;no&amp;quot; # Prevents overwriting of /etc/resolv.conf&lt;br /&gt;
&lt;br /&gt;
Custom scripts can be added as /etc/udhcpc/pre-* and /etc/udhcpc/post-* to be run before/after deconfig/renew/bound DHCP events - they must be marked as &#039;&#039;&#039;executable&#039;&#039;&#039; by root, e.g. chmod 744&lt;br /&gt;
&lt;br /&gt;
As an example, /etc/udhcpc/post-bound/mtu could contain, to change the interface MTU from the default (1500) to 1492, which is useful if [https://en.wikipedia.org/wiki/Maximum_transmission_unit on ADSL] (which uses 8 bytes):&lt;br /&gt;
&lt;br /&gt;
 r=$(/sbin/ip route | grep ^default | head -n 1)&lt;br /&gt;
 # Needs iproute2 package, rather than busybox&#039;s &amp;quot;ip&amp;quot;, to change mtu&lt;br /&gt;
 /sbin/ip route replace $r mtu 1492&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Embedded Systems]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18434</id>
		<title>Udhcpc</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=Udhcpc&amp;diff=18434"/>
		<updated>2021-01-02T21:31:20Z</updated>

		<summary type="html">&lt;p&gt;Rickyrockrat: Added options from interfaces file.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Expand|Please help us expand this article by contributing.}}&lt;br /&gt;
&lt;br /&gt;
You may want to customize the behavior of the default DHCP client (udhcpc from busybox), which is called by /sbin/ifup by having &amp;quot;dhcp&amp;quot; in /etc/network/interfaces.&lt;br /&gt;
&lt;br /&gt;
The default behavior is driven by the script /usr/share/udhcpc/default.script  &lt;br /&gt;
&lt;br /&gt;
Entries in /etc/network/interfaces for dhcp interfaces will drive the udhcpc command line. For example:  &lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
auto eth0&lt;br /&gt;
iface eth0 inet dhcp&lt;br /&gt;
        hostname myhostname&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Will set these parameters on the command line:  &lt;br /&gt;
-i eth0 -x hostname:myhostname  &lt;br /&gt;
&lt;br /&gt;
The hostname will send the DHCP option to the server to tell the server the name of this client.  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Its default configuration may be overwritten by /etc/udhcpc/udhcpc.conf&lt;br /&gt;
&lt;br /&gt;
Authorized key:value pairs are:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;15&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! key&lt;br /&gt;
| default value&lt;br /&gt;
| possible values&lt;br /&gt;
|-&lt;br /&gt;
| NO_GATEWAY&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_METRIC&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;metric value&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| IF_PEER_DNS&lt;br /&gt;
| yes&lt;br /&gt;
| &amp;lt;anything but yes&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| RESOLV_CONF&lt;br /&gt;
| /etc/resolv.conf&lt;br /&gt;
| no ; NO ; -&lt;br /&gt;
|-&lt;br /&gt;
| NO_DNS&lt;br /&gt;
| -&lt;br /&gt;
| &amp;lt;list of iface names&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Example /etc/udhcpc/udhcpc.conf:&lt;br /&gt;
&lt;br /&gt;
 RESOLV_CONF=&amp;quot;no&amp;quot; # Prevents overwriting of /etc/resolv.conf&lt;br /&gt;
&lt;br /&gt;
Custom scripts can be added as /etc/udhcpc/pre-* and /etc/udhcpc/post-* to be run before/after deconfig/renew/bound DHCP events - they must be marked as &#039;&#039;&#039;executable&#039;&#039;&#039; by root, e.g. chmod 744&lt;br /&gt;
&lt;br /&gt;
As an example, /etc/udhcpc/post-bound/mtu could contain, to change the interface MTU from the default (1500) to 1492, which is useful if [https://en.wikipedia.org/wiki/Maximum_transmission_unit on ADSL] (which uses 8 bytes):&lt;br /&gt;
&lt;br /&gt;
 r=$(/sbin/ip route | grep ^default | head -n 1)&lt;br /&gt;
 # Needs iproute2 package, rather than busybox&#039;s &amp;quot;ip&amp;quot;, to change mtu&lt;br /&gt;
 /sbin/ip route replace $r mtu 1492&lt;br /&gt;
&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Embedded Systems]]&lt;/div&gt;</summary>
		<author><name>Rickyrockrat</name></author>
	</entry>
</feed>