Skip to content

Commit

Permalink
Merge branch 'main' into #2-switch-Tailwind
Browse files Browse the repository at this point in the history
  • Loading branch information
AleksandraKozubal authored Mar 14, 2024
2 parents 1371f4c + 3c56d35 commit b5b5886
Show file tree
Hide file tree
Showing 11 changed files with 306 additions and 37 deletions.
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=
24 changes: 24 additions & 0 deletions .github/workflows/deploy-to-prod-init.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Deploy to production

concurrency:
group: deploy-prod
cancel-in-progress: false

on:

workflow_dispatch:

jobs:
deploy:
environment: production
runs-on: ubuntu-22.04
name: Deploy to production
env:
DOCKER_REGISTRY: ghcr.io
DOCKER_REGISTRY_USER_NAME: blumilkbot
REPO_NAME: ${{ github.event.repository.name }}
REPO_OWNER: ${{ github.repository_owner }}
TARGET_DIR_ON_SERVER: /blumilk/production
steps:
- name: checkout
uses: actions/checkout@v4.1.1
45 changes: 41 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
NODE_SERVICE_NAME=node
.PHONY: build run node
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 --no-cache --pull
docker compose build --pull

run:
docker compose up -d

tailwind:
npx tailwindcss -i ./styles.css -o ./public/output.css

restart: stop run
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 tailwind stop restart shell
61 changes: 48 additions & 13 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,28 +1,63 @@
version: '3.8'
networks:
traefik-proxy-blumilk-local:
external: true
lmt-dev:
driver: bridge
traefik-proxy-blumilk-local:
external: true

services:
web:
image: nginx:1.25-alpine
container_name: lmt-dev-web
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/nginx/nginx.conf:/etc/nginx/conf.d/default.conf
- ./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:
- ${EXTERNAL_WEBSERVER_PORT:-8051}:80
- ${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"
- "traefik.http.routers.lmt-http-router.rule=Host(`lmt.blumilk.localhost`)"
- "traefik.http.routers.lmt-http-router.entrypoints=web"
- "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"
# 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
34 changes: 20 additions & 14 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,30 @@

![./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

Run container:
```
make run
```
composer install
npm install
- compile css:
make tailwind

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

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 |

0 comments on commit b5b5886

Please sign in to comment.