A personal journal.

lighttpd + php-fpm didalam Sebuah Paket Docker Image berbasis Alpine dengan s6-overlay

Published on: 23/08/2023 • Updated on: 14/05/2025 • 4 min read

Berkali-kali gagal dan akhirnya berhasil (sebenarnya sudah pernah berhasil, tapi tidak saya dokumentasikan dan saya harus mengulang lagi). Catatan ini perlu disimpan supaya tidak lupa!

s6-overlay

Bisa dibuka dari https://github.com/just-containers/s6-overlay. Intinya, kita bisa mengontrol proses/layanan di dalam sebuah docker image. Padahal, tujuan docker adalah sebuah image untuk sebuah proses, tetapi masalahnya ada pada sebuah paket aplikasi yang menggunakan beberapa proses, dan ini adalah hal yang agak merepotkan di dalam sebuah docker.

Biasanya, banyak orang menggunakan init atau supervisord, namun s6-overlay ini lebih ringan dan ramah memori.

Penggunaannya sebenarnya cukup mudah, tapi ya kalau mau mencoba dan membaca dengan teliti. Di sini saya akan coba menjelaskannya dengan bahasa yang mudah dimengerti.

Instalasi s6-overlay

Tambahkan baris berikut di Dockerfile Anda, dan akhiri dengan ENTRYPOINT ["/init"]. Untuk versi dari s6-overlay, Anda bisa mengambilnya dari repo GitHub-nya, dan pastikan untuk arsitektur di mana tertulis x86_64 harus diganti dengan arsitektur yang sesuai.

FROM alpine:latest

# s6-overlay
ARG S6_OVERLAY_VERSION=3.1.5.0

ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-noarch.tar.xz
ADD https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-x86_64.tar.xz /tmp
RUN tar -C / -Jxpf /tmp/s6-overlay-x86_64.tar.xz

# isi dockernya

ENTRYPOINT ["/init"]

Instalasi s6-overlay

Instalasi lighttpd dan php-fpm

RUN apk --update add --no-cache \
    lighttpd \
    php81 \
    php81-fpm \
    php81-intl \
    php81-mbstring \
    php81-opcache \
    php81-pecl-memcached \
    php81-simplexml \
    php81-xml \
    php81-zip \
    php81-zlib

Contoh instalasi paket lighttpd dan php-fpm

Mari kita tinggalkan perdebatan kenapa --update dan --no-cache karena pada intinya kita masih ingin supaya paket program yang ada di dalam docker saya nanti terbaru dan tentunya tidak terlalu banyak memakan penyimpanan.

Untuk paket aplikasi php-fpm, Anda bisa mengaturnya sendiri, karena kadang sebuah aplikasi membutuhkan paket aplikasi yang lebih.

Sebagai tambahan, karena saya menggunakan PHP 8.1, folder dan nama paket programnya juga sebenarnya menggunakan penamaan php81. Agar lebih bersih dan enak dipakai, kita tambahkan baris berikut.

# cleanup php
RUN mv /etc/php81 /etc/php && ln -s /etc/php /etc/php81 \
  && mv /etc/init.d/php-fpm81 /etc/init.d/php-fpm && ln -s /etc/init.d/php-fpm /etc/init.d/php-fpm81 \
  && mv /etc/logrotate.d/php-fpm81 /etc/logrotate.d/php-fpm && ln -s /etc/logrotate.d/php-fpm /etc/logrotate.d/php-fpm81 \
  && mv /var/log/php81 /var/log/php && ln -s /var/log/php /var/log/php81 \
  && ln -s /usr/sbin/php-fpm81 /usr/sbin/php-fpm

Menata ulang php8.1

Kita juga perlu mengatur user untuk lighttpd, karena pada dasarnya mereka menggunakan user dan group nobody. Saya sendiri kurang tahu kenapa saya gagal untuk mengikuti anjuran ini, pasti permission denied. Jadi sebagai alternatif, saya menambahkan user dan group www-data dan mengubah kepemilikan folder /var/www.

RUN adduser www-data -G www-data -H -s /bin/false -D && \
    chown -R www-data /var/www

Menambahkan user www-data dan mengubah kepemilikan /var/www

Konfigurasi lighttpd untuk menggunakan php-fpm

Hal yang paling mudah adalah dengan membuat folder baru, misalnya rootfs. Didalam folder tersebut buat juga folder /etc/lighttpd, kemudian buat 1 file bernama lighttpd.conf. Ubah isinya sebagai berikut:

server.document-root = "/var/www/"

server.modules = ("mod_fastcgi")

server.username = "www-data"
server.groupname = "www-data"

server.indexfiles = ("index.php")

fastcgi.server = (
  ".php" => (
    (
      "socket" => "/var/run/php-fpm.sock",
      "broken-scriptfilename" => "enable"
    )
  )
)

contoh konfigurasi lighttpd.conf

Penjelasan:

  • Menggunakan /var/www sebagai root document
  • Menggunakan port 80, meskipun ini docker dan kita bisa remap dengan mudah, tapi kamu bisa remap langsung disini.
  • Mengaktifkan mod_fastcgi agar kita bisa menggunakan php-fpm
  • Mengatur user dan group yang boleh mengakses root document
  • Server dari fastcgi kita, perhatikan dimana kita meletakkan socketnya.

Konfigurasi pool php-fpm

Sama seperti lighttpd, buat folder di dalam rootfs, lebih tepatnya buat folder /etc/php/php-fpm.d/ dan buat satu file bernama www.conf. Ubah isinya seperti berikut:

pid = /var/run/php-fpm.pid
process_control_timeout = 10s
daemonize = no

[www]
user = www-data
group = www-data

listen = /var/run/php-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

pm = dynamic
pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

www.conf

Penjelasan:

  • pid untuk menjelaskan bahwa php-fpm sudah berjalan, dan tidak menimbulkan eror already running
  • Mengatur user dan group yang boleh mengakses pool ini
  • Mengatur listen sock untuk php-fpm, dan tentunya kita mengatur siapa yang berhak melakukannya.
  • Untuk process manager, skip, bisa dibaca di tempat lain / lain kali.

Konfigurasi s6-overlay service

Masuklah kita di menu utama, mengatur service. Masih di rootfs, buat folder /etc/s6-overlay/s6-rc.d/. Di dalam folder tersebut setidaknya kita akan membuat beberapa folder sesuai proses yang kita perlukan.

Sesuai judul, kita mau menjalankan lighttpd dan php-fpm, maka kurang lebih begini strukturnya.

/s6-rc.d
  |__ /lighttpd
        |__ run
        |__ type
        |__ /dependencies.d
              |__ php-fpm
  |__ /php-fpm
        |__ run
        |__ type
  |__ /user
        |__ /contents.d
            |__ lighttpd
            |__ php-fpm

Struktur folder pada s6-rc.d

Penjelasan:

  • Folder /user/contents.d/ berisikan file kosong bernamakan service apa yang akan dijalankan oleh s6-overlay. Penamaan filenya sesuai dengan folder service yang akan dijalankan.
  • Didalam setiap folder service, minimal ada 2 file, yaitu run dan type.
  • Contoh untuk run dari lighttpd adalah sebagai berikut:
#!/command/execlineb -P

lighttpd -Df "/etc/lighttpd/lighttpd.conf"
  • Dikarenakan lighttpd selalu berjalan di belakang, maka untuk file type kita isikan longrun. Namun jika kamu ingin menjalankan sesuatu yang hanya berjalan 1 kali, maka type-nya silahkan diatur menjadi oneshot.`
  • Folder dependencies.d berisi file kosong bernama service lain, yang mana s6-overlay akan memastikan bahwa service tersebut sudah berjalan dan ready sebelum menjalankan lighttpd. Di sini saya masukkan php-fpm, karena jika php-fpm belum siap, maka akan ada masalah lain.
  • Begitu juga dengan PHP-FPM, setidaknya isinya tidak jauh berbeda.

Sekian. Dari sini, lighttpd dan php-fpm sudah hidup berdampingan di dalam sebuah docker image. Semoga bermanfaat!