Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#7 - add dev environment #21

Merged
merged 2 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
APP_NAME=lmt
ENVIRONMENT=dev

SMTP_HOST=
SMTP_PORT=
SMTP_USERNAME=
SMTP_PASSWORD=
EXTERNAL_WEBSERVER_PORT=8051
EXTERNAL_MAILPIT_DASHBOARD_PORT=8052

EMAIL_FROM=
REGISTRATION_NOTIFICATION_EMAIL=
SMTP_HOST=lmt-dev-mailpit-container
SMTP_PORT=1025
SMTP_USERNAME=null
SMTP_PASSWORD=null

EMAIL_FROM="sample@example.com"
REGISTRATION_NOTIFICATION_EMAIL="hello@example.com"

SOPS_AGE_PROD_SECRET_KEY=
47 changes: 47 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
include .env

SHELL := /bin/bash

DOCKER_COMPOSE_FILE = docker-compose.yml
DOCKER_COMPOSE_APP_CONTAINER = app

CURRENT_USER_ID = $(shell id --user)
CURRENT_USER_GROUP_ID = $(shell id --group)
CURRENT_DIR = $(shell pwd)
PHP_SERVICE_NAME=app

build:
docker compose build --pull

run:
docker compose up -d

stop:
docker compose stop

restart: stop run

shell:
@docker compose exec --user ${CURRENT_USER_ID} ${PHP_SERVICE_NAME} bash

encrypt-prod-secrets:
@$(MAKE) encrypt-secrets SECRETS_ENV=prod

decrypt-prod-secrets:
@$(MAKE) decrypt-secrets SECRETS_ENV=prod AGE_SECRET_KEY=${SOPS_AGE_PROD_SECRET_KEY}

decrypt-secrets:
@docker compose --file ${DOCKER_COMPOSE_FILE} exec --user "${CURRENT_USER_ID}:${CURRENT_USER_GROUP_ID}" --env SOPS_AGE_KEY=${AGE_SECRET_KEY} ${DOCKER_COMPOSE_APP_CONTAINER} \
bash -c "echo 'Decrypting ${SECRETS_ENV} secrets' \
&& cd ./environment/prod/deployment/${SECRETS_ENV} \
&& sops --decrypt --input-type=dotenv --output-type=dotenv --output .env.${SECRETS_ENV}.secrets.decrypted .env.${SECRETS_ENV}.secrets \
&& echo 'Done'"

encrypt-secrets:
@docker compose --file ${DOCKER_COMPOSE_FILE} exec --user "${CURRENT_USER_ID}:${CURRENT_USER_GROUP_ID}" ${DOCKER_COMPOSE_APP_CONTAINER} \
bash -c "echo 'Encrypting ${SECRETS_ENV} secrets' \
&& cd ./environment/prod/deployment/${SECRETS_ENV} \
&& sops --encrypt --input-type=dotenv --output-type=dotenv --output .env.${SECRETS_ENV}.secrets .env.${SECRETS_ENV}.secrets.decrypted \
&& echo 'Done'"

.PHONY: build run stop restart shell
64 changes: 64 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
networks:
lmt-dev:
driver: bridge
traefik-proxy-blumilk-local:
external: true

services:
app:
build:
context: ./environment/dev/app
dockerfile: Dockerfile
args:
- USER_ID=${DOCKER_HOST_USER_ID:-1000}
labels:
- "traefik.enable=true"
- "traefik.blumilk.environment=true"
# HTTP
- "traefik.http.routers.lmt-http-router.rule=Host(`lmt.blumilk.localhost`)"
- "traefik.http.routers.lmt-http-router.entrypoints=web"
# HTTP to HTTPS redirect
# - "traefik.http.routers.lmt-http-router.middlewares=https-redirect@file"
# HTTPS
- "traefik.http.routers.lmt-https-router.rule=Host(`lmt.blumilk.localhost`)"
- "traefik.http.routers.lmt-https-router.entrypoints=websecure"
- "traefik.http.routers.lmt-https-router.tls=true"
container_name: lmt-dev-app-container
working_dir: /application
volumes:
- ./environment/dev/app/nginx.conf:/etc/nginx/nginx.conf:ro
- ./environment/dev/app/php.ini:/usr/local/etc/php/conf.d/zzz-overrides.ini:ro
- ./environment/dev/app/php-fpm.conf:/usr/local/etc/php-fpm.d/zzz-overrides.conf:ro
- ./environment/dev/app/supervisord.conf:/etc/supervisor/custom-supervisord.conf:ro
- .:/application
ports:
- ${DOCKER_APP_HOST_PORT:-8051}:80
networks:
- lmt-dev
- traefik-proxy-blumilk-local
restart: unless-stopped

mailpit:
image: axllent/mailpit:v1.14.4
container_name: lmt-dev-mailpit-container
ports:
- ${EXTERNAL_MAILPIT_DASHBOARD_PORT:-8052}:8025
- ${EXTERNAL_MAILPIT_SMTP_PORT:-8053}:1025
networks:
- lmt-dev
- traefik-proxy-blumilk-local
labels:
- "traefik.enable=true"
- "traefik.blumilk.environment=true"
# HTTP
- "traefik.http.routers.lmt-mailpit-http-router.rule=Host(`lmt-mailpit.blumilk.localhost`)"
- "traefik.http.routers.lmt-mailpit-http-router.entrypoints=web"
# HTTP to HTTPS redirect
# - "traefik.http.routers.lmt-mailpit-http-router.middlewares=https-redirect@file"
# HTTPS
- "traefik.http.routers.lmt-mailpit-https-router.rule=Host(`lmt-mailpit.blumilk.localhost`)"
- "traefik.http.routers.lmt-mailpit-https-router.entrypoints=websecure"
- "traefik.http.routers.lmt-mailpit-https-router.tls=true"
# LOADBALANCER MAILHOG PORT
- "traefik.http.services.lmt-mailpit.loadbalancer.server.port=8025"
restart: unless-stopped
72 changes: 72 additions & 0 deletions environment/dev/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# https://hub.docker.com/_/alpine
FROM alpine:3.19.0 as secops-tools

# https://github.com/FiloSottile/age/releases
ARG AGE_VERSION="1.1.1"

# https://github.com/getsops/sops/releases
ARG SOPS_VERSION="3.8.1"

RUN wget --output-document age.tar.gz "https://github.com/FiloSottile/age/releases/download/v${AGE_VERSION}/age-v${AGE_VERSION}-linux-amd64.tar.gz" \
&& tar --extract --file age.tar.gz \
&& mv age/age /usr/local/bin \
&& mv age/age-keygen /usr/local/bin \
&& wget --output-document /usr/local/bin/sops "https://github.com/getsops/sops/releases/download/v${SOPS_VERSION}/sops-v${SOPS_VERSION}.linux.amd64" \
&& chmod +x /usr/local/bin/sops

FROM composer/composer:2.7.2-bin as composer-bin

FROM node:21.7.1-bookworm-slim as node

FROM php:8.3.3-fpm-bookworm

COPY --from=composer-bin ./composer /usr/bin/composer
COPY --from=secops-tools /usr/local/bin/age /usr/local/bin/age
COPY --from=secops-tools /usr/local/bin/age-keygen /usr/local/bin/age-keygen
COPY --from=secops-tools /usr/local/bin/sops /usr/local/bin/sops


ARG USER_NAME=host-user
ARG USER_ID=1000
ARG PHP_FPM_GROUP=www-data

RUN adduser \
--disabled-password \
--uid ${USER_ID} \
${USER_NAME} \
&& usermod \
--append \
--groups \
${PHP_FPM_GROUP} \
${USER_NAME}

#Add node and npm
COPY --from=node --chown=${USER_NAME}:root /usr/local/lib/node_modules /usr/local/lib/node_modules
COPY --from=node --chown=${USER_NAME}:root /usr/local/bin/node /usr/local/bin/node
RUN ln --symbolic /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm \
&& chown --no-dereference ${USER_NAME}:root /usr/local/bin/npm \
&& ln --symbolic /usr/local/lib/node_modules/npm/bin/npx-cli.js /usr/local/bin/npx \
&& chown --no-dereference ${USER_NAME}:root /usr/local/bin/npx

# Use the default development configuration
RUN mv "${PHP_INI_DIR}/php.ini-development" "${PHP_INI_DIR}/php.ini"

# For other versions check: http://nginx.org/packages/mainline/debian/pool/nginx/n/nginx/
ARG NGINX_VERSION="1.25.4-1~bookworm"

RUN apt-get update \
&& apt-get install --assume-yes gpg \
&& curl https://nginx.org/keys/nginx_signing.key | gpg --dearmour --output /etc/apt/trusted.gpg.d/apt.nginx.org.gpg > /dev/null \
&& echo "deb https://nginx.org/packages/mainline/debian bookworm nginx" | tee /etc/apt/sources.list.d/nginx.list \
&& apt-get update && apt-get install --assume-yes \
nginx=${NGINX_VERSION} \
7zip \
libzip-dev \
supervisor \
cron

COPY ./entrypoint.sh /entrypoint.sh

WORKDIR /application

ENTRYPOINT ["/entrypoint.sh"]
12 changes: 12 additions & 0 deletions environment/dev/app/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash

# -e is for "automatic error detection", tell shell to abort any time an error occurred
set -e

# bash is not responding to the sigterm and container always have 10 second timeout (when stop/restart)
# exec is related with
# https://docs.docker.com/compose/faq/#why-do-my-services-take-10-seconds-to-recreate-or-stop
# https://github.com/moby/moby/issues/3766
# https://unix.stackexchange.com/a/196053

exec supervisord --configuration /etc/supervisor/custom-supervisord.conf
45 changes: 45 additions & 0 deletions environment/dev/app/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
daemon off;

user nginx;
worker_processes auto;

error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;

server {
listen 80 default;
server_name lmt-nginx;

access_log /dev/stdout;
error_log /dev/stderr;

root /application/public;
index index.html;

location / {
try_files $uri $uri/ =404;
}

location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
}
8 changes: 8 additions & 0 deletions environment/dev/app/php-fpm.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[global]
daemonize = no

[www]
listen = /run/php-fpm.sock
listen.owner = nginx

user = host-user
2 changes: 2 additions & 0 deletions environment/dev/app/php.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[PHP]
memory_limit = 256M
22 changes: 22 additions & 0 deletions environment/dev/app/supervisord.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
; For more information on the config file, please see:
; http://supervisord.org/configuration.html

[supervisord]
logfile = /var/log/supervisor/supervisord.log
pidfile = /var/run/supervisord.pid
user = root
nodaemon = true

[program:nginx]
command = nginx
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0

[program:php-fpm]
command = php-fpm
stdout_logfile = /dev/stdout
stdout_logfile_maxbytes = 0
stderr_logfile = /dev/stderr
stderr_logfile_maxbytes = 0
25 changes: 20 additions & 5 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@

![./screenshot.png](./screenshot.png)

### Installation
### To run in docker environment:
Copy `.env.example` to `.env` and set your environment variables

Install PHP dependencies
cp .env.example .env

composer install
- build APP containers:

Copy `.env.example` to `.env` and set your environment variables
make build

cp .env.example .env
- run containers:

make run

- enter the APP container with `make shell`, then install php and node dependencies

composer install
npm install

- The website should be available at `localhost:8051` and `lmt.blumilk.localhost` if we use a Blumilk local traefik proxy

| service | container name | default external port |
|-------------------|---------------------------|-----------------------|
| app | lmt-dev-app-container | 8051 |
| mailpit | lmt-dev-mailpit-container | 8052 |