{"id":26028592,"url":"https://github.com/marcuszou/lemp-sqlite3","last_synced_at":"2025-03-06T17:18:47.629Z","repository":{"id":278958041,"uuid":"937243373","full_name":"marcuszou/lemp-sqlite3","owner":"marcuszou","description":"Guide to Dockerize Nginx-SQLite3-PHP","archived":false,"fork":false,"pushed_at":"2025-03-02T11:40:58.000Z","size":185,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-02T12:18:17.196Z","etag":null,"topics":["docker","nginx","php-fpm","sqlite3"],"latest_commit_sha":null,"homepage":"","language":"PHP","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/marcuszou.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2025-02-22T17:13:34.000Z","updated_at":"2025-03-02T11:41:02.000Z","dependencies_parsed_at":"2025-02-22T20:18:40.214Z","dependency_job_id":"4f6591bc-6ec9-4d48-a982-17102e1e9d65","html_url":"https://github.com/marcuszou/lemp-sqlite3","commit_stats":null,"previous_names":["marcuszou/lemp-sqlite3"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcuszou%2Flemp-sqlite3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcuszou%2Flemp-sqlite3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcuszou%2Flemp-sqlite3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/marcuszou%2Flemp-sqlite3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/marcuszou","download_url":"https://codeload.github.com/marcuszou/lemp-sqlite3/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":242250928,"owners_count":20096897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["docker","nginx","php-fpm","sqlite3"],"created_at":"2025-03-06T17:18:46.973Z","updated_at":"2025-03-06T17:18:47.615Z","avatar_url":"https://github.com/marcuszou.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Guide to Dockerize Nginx-SQLite3-PHP\n**This guide shows you how to dockerize your LESP (Linux, Nginx, SQLite3, PHP) stack easily and quickly.**\n\nby Marcus Zou | 20 Feb 2025 | 3 minutes Reading - 20 minutes Hands-on\n\n\n\n## Intro\n\nThe LEMP stack is an open-source solution used to develop web applications. It is an acronym representing Linux, Nginx, MySQL/MariaDB, and PHP. In addition, it is widely popular and well-supported among the Open Source community.\n\nHowever, installing and configuring all of these services takes time and skills. This is where Docker containers, specifically Docker Compose, come in. With its help, you can have your LEMP stack up and running in minutes and focus entirely on developing web apps without wasting time installing and configuring services.\n\n![LEMP Stack](assets/p1.png)\n\nBut sometimes your task is not that heavy-duty in terms of data loads, then a light-weight **SQLite3** may get the job done, instead of adopting MySQL/MariaDB.\n\nThis guide will show you how to quickly and easily integrate Nginx, SQLite3, and PHP using Docker Compose. \n\nWithout further ado, let’s work it out.\n\n#### # Tech Stack\n\n* __Linux__: Debian/Ubuntu is preferred\n* __Nginx__: The Frontend Web UI server\n* __SQLite3__: A single file based, light-weight database\n* __PHP__: 8.2-FPM\n\n#### # Prerequisites\n\n- Linux: Debian or Ubuntu preferred, WSL2 distro works well\n- Docker Engine/Desktop installed\n\n- Run the command below to ensure that Docker Compose is installed and functioning correctly.\n\n  ```shell\n  docker -- version\n  ## Docker version 27.5.1, build 9f9e405\n  docker compose version\n  ## Docker Compose version v2.32.4\n  ```\n\n  \n\n## Quick-Start\n\n1. Git clone my repo: https://github.com/marcuszou/lemp-typecho.git.\n\n   ```shell\n   git clone https://github.com/marcuszou/lemp-sqlite3.git\n   ```\n\n2. Fine tune the `docker-compose.yml` as needed.\n\n   ```shell\n   sudo chown -R $USER:$USER ./lemp-sqlite3\n   cd lemp-sqlite3\n   nano docker-compose.yml\n   ```\n\n3. Fire up the docker containers. \n\n   ```shell\n   docker compose up -d\n   ```\n\n   Docker will pull down the relevant images and start the containers, which will take some time.\n\n4. Access the website via http://localhost:8080 for the Web, \n\n5. Access the SQLite Browser at http://localhost:5800.\n\n\n\n## Details of the Guide\n\nI would like to throw in the final realization in one go.\n\n\n\n### 1- Folder Structure Design\n\nThe folder structure could be designed as below:\n\n```shell\n-- File: `README.md`\n-- File: `docker-compose.yml`\n-- Folder: `db/data/`\n-- Folder: `nginx/`\n-- Folder: `php/`\n-- Folder: `www/html`\n```\n\nCreate the folder structure and files.\n\n```shell\n## create project folder\nmkdir lemp-sqlite3\ncd lemp-sqlite3\n## generate sub-folders\nmkdir -p db/{data,dir} nginx/{conf,logs} php www/html\n## generate files\ntouch README.md LICENSE.md docker-compose.yml nginx/conf/default.conf \ntouch php/{Dockerfile,php.ini,php-log.conf} \ntouch www/html/index.php\n## display the folder/files structure\ntree\n```\n\nHere is the output of last command above: Exactly same as what we designed, fantastic, isn't it?\n\n```shell\n.\n├── README.md\n├── LICENSE.md\n├── docker-compose.yml\n├── db\n│   └── data\n├── nginx\n│   ├── conf\n│   │   └── default.conf\n│   └── logs\n├── php\n│   ├── Dockerfile\n│   ├── php-log.conf\n│   └── php.ini\n└── www\n    └── html\n        └── index.php\n```\n\n\n\n### 2- Create the Nginx + PHP Containers\n\nCreate and launch an Nginx container to host the PHP application in a PHP container.\n\n```shell\n## edit the docker-compose.yml file\nnano docker-compose.yml\n```\n\nHere is the full content of the `docker-compose.yml` file:\n\n```shell\n# Services\nservices:\n\n  # Nginx Service\n  nginx:\n    container_name: web\n    image: nginx:alpine\n    ports:\n      - 8080:80\n    restart: always\n    environment:\n      - TZ=America/Edmonton\n    links:\n      - php\n    volumes:\n      - ./www/html/:/var/www/html/\n      - ./nginx/conf/:/etc/nginx/conf.d/\n      - ./nginx/logs/:/var/log/nginx/\n    depends_on:\n      - php\n    networks:\n      - lemp-sqlite3-net\n\n  # PHP-FPM Service\n  php:\n    container_name: php8\n    build: php\n    expose:\n      - 9000\n    restart: always\n    environment:\n      - TZ=America/Edmonton\n    volumes:\n      - ./www/html/:/var/www/html/\n      # php-fpm config files are located at /usr/local/etc/php-fpm.d/ folder\n      - ./php/php-log.conf:/usr/local/etc/php-fpm.d/zz-log.conf\n      - ./php/php.ini:/usr/local/etc/php/conf.d/php.ini\n      - ./db/data/:/data/\n    networks:\n      - lemp-sqlite3-net\n\n# Networks\nnetworks:\n  lemp-sqlite3-net:\n```\n\nThe above file will \n\n- download the latest Nginx image, create an Nginx container (internal port 80), and expose it on port 8080.\n\n- mapping the local web root directory (`./www/html/`) to the standard web folder (`/var/www/html/`) in the container.\n- the Nginx container serves the web with config file: `nginx/default.conf`, mapping to `/etc/nginx/conf.d/default.conf`. \n- link the Nginx container to PHP container, \n\n- build a new PHP container (based on docker image: `php:8.2-pfm`), expose PHP-FPM on port 9000, as per a Dockerfile template at `./php/Dockerfile`.\n- map and mount the volume to the PHP container so that all contents at `./www/html` folder will be in sync with the container’s directory `/var/www/html/`.\n- another 2 typical config files (`php.ini`, `php-log.conf`) will be mapped as well.\n\n- the PHP-FPM container while install quite a bunch of PHP extensions to drive up SQLite3 database serving at port 9000. \n\n\n\n### 3- Configure the Nginx Container\n\n3.1 - Edit the Nginx default configuration file to run your PHP application:\n\n```\nnano nginx/conf/default.conf\n```\n\nAdd the following lines:\n\n```\nserver {\n\n    listen 80 default_server;\n    root /var/www/html;\n    index index.html index.php;\n\n    charset utf-8;\n    \n    # access_log off;\n    access_log /var/log/nginx/access.log main;\n    error_log /var/log/nginx/error.log error;\n\n    sendfile off;\n    client_max_body_size 100m;\n    \n    location = /favicon.ico { access_log off; log_not_found off; }\n    location = /robots.txt { access_log off; log_not_found off; }\n    \n    location / { try_files $uri $uri/ /index.php?$query_string; }\n    \n    location ~ .php$ {\n        fastcgi_split_path_info ^(.+.php)(/.+)$;\n        fastcgi_pass php:9000;\n        fastcgi_index index.php;\n        include fastcgi_params;\n        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;\n        fastcgi_intercept_errors off;\n        fastcgi_buffer_size 16k;\n        fastcgi_buffers 4 16k;\n    }\n\n    location ~ /.ht { deny all; }\n}\n```\n\nSave and close the file.\n\n\n\n### 4– Configure the PHP Container\n\n\n\n__4.1__ - First, we must modify the PHP image and install the PHP extensions for driving PHP to connect to the SQLite3 database. So, edit the `php/Dockerfile` to build a **custom PHP image** while installing the PHP extensions:\n\n```\nnano php/Dockerfile\n```\n\nAdd the following lines:\n\n```\nFROM php:8.2-fpm\n\n# Installing dependencies for the PHP modules\nRUN apt-get update\nRUN apt-get install -y curl unzip zip libbz2-dev libcurl3-dev libjpeg62-turbo-dev libpng-dev libonig-dev libssl-dev libsqlite3-dev libxml2-dev libzip-dev\n# libonig-dev is needed for oniguruma which is needed for php-mbstring\nRUN rm -rf /var/lib/apt/lists/*\n\n# Installing PHP modules: curl, mbstring, pdo, pdo_sqilte ...\nRUN docker-php-ext-install curl gd mbstring pdo pdo_sqlite xml zip\n\n# COMPOSER - the PHP dependency manager\nRUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer\n```\n\nSave and close the file. \n\n__4.2__ - Also configure the php-fpm by `nano php/php.ini`, which will be mapped in the `docker-compose.yml` later.\n\n```shell\ndate.timezone=UTC\ndisplay_errors=On\nlog_errors=On\nupload_max_filesize= 80M\npost_max_size= 80M\nmemory_limit = 256M\n```\n\n__4.3__ - And configure the logs by `nano php/php-log.conf`, which will also be mapped later.\n\n```shell\nphp_admin_flag[log_errors] = on\nphp_flag[display_errors] = on  ## turn it off after debugging\n```\n\n\n\n### 5-  SQLite3 Database Setup\n\n\n\nThe  beauty of adopting SQLite3 database is no complex settings at all, since the database will be created on the fly when launching the `index.php`. \n\nSo, edit the **`www/html/index.php`** file and make changes to test the database connection.\n\n```\nnano www/html/index.php\n```\n\nMake the following changes:\n\n```php+HTML\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n     \u003chead\u003e\n          \u003ctitle\u003eHello PHP8!\u003c/title\u003e\n     \u003c/head\u003e  \n\n     \u003cbody\u003e\n          \u003ch1\u003eHello, PHP8 + SQLite3!\u003c/h1\u003e\n          \u003c?php\n               $db = new SQLite3('/data/testing.sqlite', SQLITE3_OPEN_CREATE | SQLITE3_OPEN_READWRITE);\n               // Create a table.\n               $db-\u003equery(\n                    'CREATE TABLE IF NOT EXISTS \"users\" (\n                         \"id\" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n                         \"name\" VARCHAR\n                         )'\n                    );\n               // Insert some sample data.\n               $db-\u003equery('INSERT INTO \"users\" (\"name\") VALUES (\"Karl\")');\n               $db-\u003equery('INSERT INTO \"users\" (\"name\") VALUES (\"Linda\")');\n               $db-\u003equery('INSERT INTO \"users\" (\"name\") VALUES (\"John\")');\n\n               // Get the name of the tables in SQLite3 database\n               $tableQuery = $db-\u003equery(\"SELECT name FROM sqlite_master WHERE type='table';\");\n               while ($myTable = $tableQuery-\u003efetchArray(SQLITE3_ASSOC)) {\n                    echo \"Table: \" . $myTable['name'] . \"\u003cbr /\u003e\";\n               }\n               echo \"\u003cbr /\u003e\";\n               \n               \n               // Get a count of the number of users\n               $userCount = $db-\u003equerySingle('SELECT COUNT(DISTINCT \"id\") FROM \"users\"');\n               echo(\"User count: $userCount\\n\");\n               // Close the connection\n               $db-\u003eclose();\n          ?\u003e\n\n          \u003ch1\u003e \u003c?php echo 'Welcome to PHP ' . phpversion(); ?\u003e \u003c/h1\u003e\n          \u003cp\u003e \u003c?php phpinfo(); ?\u003e \u003c/p\u003e\n     \u003c/body\u003e\n\u003c/html\u003e\n```\n\nSave and close the file. \n\n\n\n### 6- Dry Run\n\n\n\nLaunch the containers with the following command:\n\n```\ndocker compose up -d\n```\n\nDue to the long time needed to build a custom PHP image and container, this part may take quite a time, so be patient.\n\nVerify all running containers with the following command:\n\n```\ndocker ps -a\n## There are 2 containers now.\n```\n\nYou should see the following output:\n\n\u003e CONTAINER ID   IMAGE                      COMMAND                       CREATED             STATUS             PORTS                              NAMES\n\u003e 381e168ff409   nginx:alpine             \"/docker-entrypoint.…\"    2 hours ago        Up 2 hours       0.0.0.0:8080-\u003e80/tcp     web\n\u003e 0382e88e22bf   lesp-typecho-php   \"docker-php-entrypoi…\"  2 hours ago        Up 2 hour s      9000/tcp                         php8\n\nAlso access **http://localhost:8080** to take a look. Obviously there are 3 users created in the table `users`.\n\n![Final-GUI](assets/p2.png)\n\n\n\n### 7- (Optionally) Grab SQLite Browser \n\nThe final touch-up is to hook up the [SQLite Browser](https://sqlitebrowser.org/). *DB Browser for SQLite* (DB4S) is a high quality, visual, [open source](https://github.com/sqlitebrowser/sqlitebrowser) tool designed for people who want to create, search, and edit [SQLite](https://www.sqlite.org/) or [SQLCipher](https://www.zetetic.net/sqlcipher/) database files. DB4S gives a familiar spreadsheet-like interface on the database in addition to providing a full SQL query facility. It works with Windows, macOS, and most versions of Linux and Unix. \n\nCurrently in the market, there are some open-source docker containers:\n\n- lscr.io/linuxserver/sqlitebrowser:latest - updating very often, reply on UID/GID of the host, VNC-based, big-sized: 1.5GB...\n- __evgeniydoctor/sqlitebrowser__:latest - updating not-so-often, simple-setup, small-sized: 366MB...\n\nSo the latter was selected.\n\nNothing special, just simply add a service named \"`sqlitebrowser`\" in the end of the `docker-compose.yml` file.\n\n```shell\n  ......\n\n  # SQLiteBrowser Service\n  sqlitebrowser:\n    container_name: sqlitebrowser\n    image: evgeniydoctor/sqlitebrowser:latest\n    ports:\n      - 5800:5800\n    restart: unless-stopped\n    environment:\n      - VNC_PASSWORD=vncP@ss2024\n      - KEEP_APP_RUNNING=1\n      - TZ=America/Edmonton\n    volumes:\n      - ./db/dir:/dbs/dir\n      - ./db/data:/dbs/data\n    depends_on: \n      - php\n    networks:\n      - lemp-sqlite3-net\n\n# Networks\nnetworks:\n  lemp-sqlite3-net:\n```\n\nThen fire up the dockers. And access __http://localhost:5800__ for the `SQLite Browser` site. Feel free to remove the password if needed.\n\n![DBMgr-login](assets/p3.png)\n\nAnd the Admin GUI:\n\n![DBMgr-GUI](assets/p4.png)\n\n\n\n## 8- local TLS/SSL\n\n* This docker configuration has not been security consolidated with ssl locally. Expose it to public networks at your own risk!\n* If you place the containers in the Cloud Service Providers (AWS, GCP, Azure, Digital Ocean, etc.) or your home NAS, the SSL question will be taken care by them automatically.\n* Refer to my writing-up at [local-SSL](./SSL-locally.md).\n\n\n\n### 9- Environment Restoration\n\n9.1 take down all containers\n\n```shell\n## To remove all comtainers created by this docker-compose.yml file, do:\ndocker compose down\n\n## Alternatively remove all containers created by any yml files, do:\ndocker stop $(docker ps -aq)\ndocker rm $(docker ps -aq)\n```\n\n9.2 remove newly-created image\n\n```shell\ndocker images\ndocker image rm lemp-sqlite3-php\ndocker image rm evgeniydoctor/sqlitebrowser\n```\n\n9.3 remove some left-over folders and files\n\n```shell\nsudo rm -rf db/data/*\nsudo rm -rf nginx/logs/*\n```\n\n\n\n## Outro\n\nIn the above guide, you learned how to deploy a PHP application with Nginx and SQLite3 using Docker and Docker Compose. You should now be able to host the PHP application in the production environment with Docker.\n\n\n\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcuszou%2Flemp-sqlite3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarcuszou%2Flemp-sqlite3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarcuszou%2Flemp-sqlite3/lists"}