{"id":19159290,"url":"https://github.com/tiliavir/raspi-web-server","last_synced_at":"2026-06-16T12:32:11.399Z","repository":{"id":88645777,"uuid":"443753576","full_name":"Tiliavir/raspi-web-server","owner":"Tiliavir","description":"Raspberry 4 model B - Web Server","archived":false,"fork":false,"pushed_at":"2022-01-02T20:49:42.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-22T22:25:37.948Z","etag":null,"topics":["hardened","raspberry-pi","webserver"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Tiliavir.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-01-02T11:53:29.000Z","updated_at":"2022-01-02T20:49:45.000Z","dependencies_parsed_at":null,"dependency_job_id":"3b4591c6-b29c-4ed9-bd16-6cbe1c38a517","html_url":"https://github.com/Tiliavir/raspi-web-server","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Tiliavir/raspi-web-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tiliavir%2Fraspi-web-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tiliavir%2Fraspi-web-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tiliavir%2Fraspi-web-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tiliavir%2Fraspi-web-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Tiliavir","download_url":"https://codeload.github.com/Tiliavir/raspi-web-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Tiliavir%2Fraspi-web-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34406820,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-16T02:00:06.860Z","response_time":126,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["hardened","raspberry-pi","webserver"],"created_at":"2024-11-09T08:48:21.784Z","updated_at":"2026-06-16T12:32:11.394Z","avatar_url":"https://github.com/Tiliavir.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Raspberry 4 model B - Web Server\n\nThis is the documentation of setting up my Raspberry Pi model B as a web server for static websites - and this in a\nclean and secure way.\n\n## Software\n\n- [aarch64 alpine linux](https://alpinelinux.org/downloads/)\n- lighttpd\n- vsftpd\n\nFind some explanation why I decided to take this in favor of others in the following sub chapters.\n\n### Which Alpine version should I use?\n\nAccording to the [Alpine wiki page for Raspberry Pi](https://wiki.alpinelinux.org/wiki/Raspberry_Pi) I decided to go\nwith `aarch64`:\n\n\u003e You should be safe using the armhf build on all versions of Raspberry Pi (including Pi Zero and Compute Modules);\n\u003e but it may perform less optimally on recent versions of Raspberry Pi. The armv7 build is compatible with Raspberry\n\u003e Pi 2 Model B. The aarch64 build should be compatible with Raspberry Pi 2 Model v1.2, Raspberry Pi 3 and Compute\n\u003e Module 3, and Raspberry Pi 4 model B.\n\n### Lighttpd vs nginx\n\nI decided to go with lighttpd since I only wanted to have a web server serving static files and it should have a minimal\nfootprint.\n\n## Installation\n\n### Prepare your SD card\n\n**This will erase data on the SD card!** That said, be sure that your SD card is empty or the data is no longer relevant\nfor you!\n\nYou can use `fdisk` to perform the following - I was too lazy and simply used Ubuntu's disk tool.\n\n- Add a FAT32 system partition\n- Add a FAT32 data partition\n\n### Alpine Linux\n\n#### Prepare the bootable media\n\nPlugin SD card to your machine. Check, where your SD card ended up on your system using `fdisk` or the disk tool. For me\nit is `/dev/sda/` mounted on `/media/\u003cuser\u003e/system`.\n\nMount the micro SD card on your machine and initialize the MBR to make it bootable:\n\n```bash\n$ sudo apt-get install mbr\n$ sudo install-mbr /dev/sda\n```\n\nAfter that, mount the device and the downloaded alpine archive. Open a terminal and point it to the mounted archive\n\n```bash\n$ cd $alpine-archive-dir\n$ cp -a .alpine-release * /media/\u003cuser\u003e/system/\n```\n\nSafely eject the SD card.\n\n#### Actually install Alpine\n\nNext put the SD card into the Raspberry Pi, wire it and boot it up. Then make the system persistent using:\n\n```bash\n$ setup-alpine\n```\n\nThis requires some configuration - do as pleased, I took defaults where possible. Finally reboot the system:\n\n```bash\n$ reboot\n```\n\n#### Configuration\n\nAdd a `usercfg.txt` file to `/boot/` - this will enable sound, minimize gpu memory and remove a black border around the\nscreen:\n\n```\nenable_uart=1\ngpu_mem=32\ndisable_overscan=1\n```\n\nAnd perform following step to adjust the welcome text:\n\n```bash\n$ echo \"Welcome to Raspi Web Server\" \u003e /etc/motd\n```\n\nTo install e.g. vsftpd you have to enable community packages in `/etc/apk/repositories` - simply uncomment that line and\nrun:\n\n```bash\n$ apk update\n$ apk upgrade\n```\n\n#### Configure chrony\n\n```bash\n$ vi /etc/chrony/chrony.conf\n```\n\nAdd the following line at the bottom of the file.\n\n```bash\nmakestep 60 10\n```\n\nCheck the date, restart the service, and check the (now hopefully corrected) date again.\n\n```bash\n$ date\n$ rc-service chronyd restart\n$ date\n```\n\n#### There is no `shutdown`?\n\nSimply use `poweroff` or `halt` to shot down and `reboot` to reboot - don't ask :-D\n\n#### Sources\n\n- https://wiki.alpinelinux.org/wiki/Raspberry_Pi_4_-_Persistent_system_acting_as_a_NAS_and_Time_Machine\n- https://wiki.alpinelinux.org/wiki/Raspberry_Pi\n- https://wiki.alpinelinux.org/wiki/Create_a_Bootable_Device#Format_USB_stick\n\n### lighttpd\n\n#### Installation\n\n```bash\n$ apk add lighttpd\n$ rc-update add lighttpd default \n```\n\n#### Configuration\n\nOpen `/etc/lighttpd/lighttpd.conf` and set\n\n- `var.basedir= \"/var/www\"`\n- `server.document-root = var.basedir + \"/html\"`\n- `server.indexfiles = (\"index.html\", \"index.htm\")`\n- `server.follow-symlink = \"disable\"`\n\nRun `rc-service lighttpd restart` to see if the config can be processed and the server is still starting.\n\n#### Sources\n\nhttps://www.cyberciti.biz/tips/installing-and-configuring-lighttpd-webserver-howto.html\n\n### vsftpd\n\n#### Installation\n\nTo install vsftpd you have to enable community packages in `/etc/apk/repositories` - simply uncomment that line.\n\n```bash\n$ apk add vsftpd\n$ rc-update add vsftpd default\n```\n\n#### Configuration\n\nAdd a file `/etc/vsftpd/vsftpd.userlist` containing users that are allowed to access the ftp server using a client.\nE.g. `ftpuser`.\n\nCreate this user using:\n\n```bash\n$ addgroup ftpusers\n$ adduser ftpuser -G ftpusers -h /var/www/html -s /sbin/nologin\n$ chmod a-w /var/www/html\n```\n\nEdit `/etc/vsftpd/vsftpd.conf` and set\n\n- `anonymous_enable=NO`\n- `local_enable=YES`\n- `write_enable=YES`\n- `local_umast=022`\n- `ftpd_banner=Welcome to Raspi FTP`\n- `nopriv_user=ftpuser`\n- `chroot_local_user=YES`\n- `pasv_enable=YES`\n- `pasv_min_port=10090`\n- `pasv_max_port=10100`\n\n#### Sources\n\nhttps://www.layerstack.com/resources/tutorials/How-to-set-up-configure-secure-vsFTPd-on-Linux-Cloud-Servers\n\n## Hardening\n\nSet a secure password for root:\n\n```bash\n$ passwd\n```\n\nSetup a basic firewall:\n\n```bash\n$ apk add ufw\n$ rc-update add ufw default\n$ ufw allow 20\n$ ufw limit 20/tcp\n$ ufw allow 21\n$ ufw limit 21/tcp\n$ ufw allow in 10090:10100/tcp\n$ ufw allow 80\n$ ufw allow 443\n```\n\nTODO\n- https://gist.github.com/jumanjiman/f9d3db977846c163df12\n\n## Automate all that?\n\nTODO\n- adjust initial image\n- first boot script\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiliavir%2Fraspi-web-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftiliavir%2Fraspi-web-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftiliavir%2Fraspi-web-server/lists"}