diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..388526b --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +### Defensive settings for make: +# https://tech.davis-hansson.com/p/make/ +SHELL:=bash +.ONESHELL: +.SHELLFLAGS:=-xeu -o pipefail -O inherit_errexit -c +.SILENT: +.DELETE_ON_ERROR: +MAKEFLAGS+=--warn-undefined-variables +MAKEFLAGS+=--no-builtin-rules + +CURRENT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) + + +# We like colors +# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects +RED=`tput setaf 1` +GREEN=`tput setaf 2` +RESET=`tput sgr0` +YELLOW=`tput setaf 3` + +.PHONY: build-images +build-images: ## Build docker images + @echo "Build" + $(MAKE) -C "./backend/" build-image + $(MAKE) -C "./frontend/" build-image + +.PHONY: release-images +release-images: build-images ## Build docker images + @echo "Release" + $(MAKE) -C "./backend/" release-image + $(MAKE) -C "./frontend/" release-image + +.PHONY: start-images +start-images: ## Start docker compose + @echo "Build" + @docker-compose -f dockerfiles/local-dev.yml up --build diff --git a/README.md b/README.md new file mode 100644 index 0000000..05621e1 --- /dev/null +++ b/README.md @@ -0,0 +1,58 @@ +# Plone Deployment Training Example Repo + +## Initial Setup + +* Fork this repo into your Github account +* `git clone git@github.com:MYUSER/training-deploy-project.git` +* Open in your favorite text editor. ie: `cd training-deploy-project && code ./` +* Find all occurences of **DOCKER_HUB_USER_CHANGE_ME** and replace it with your Docker Hub user name + +## Setup backend + +Create a Python virtual environment, install Plone 6.0.0a1 and one addon. + +```shell +cd backend +make setup +``` + +Run the Plone Backend instance +```shell +make start +``` + +In a browser, go to [http://localhost:8080/@@plone-addsite?site_id=Plone&advanced=1](http://localhost:8080/@@plone-addsite?site_id=Plone&advanced=1 and create a new site: + +![Plone site creation](./docs/plone-setup.png "Plone site creation") + +Stop the process + +## Setup a new frontend project + +On the root of this project + +```shell +npm init yo @plone/volto +``` + +Answer the questions: +``` +Project name (e.g. my-volto-project) frontend +Would you like to add addons? True +Addon name, plus extra loaders, like: volto-addon:loadExtra,loadAnotherExtra volto-slate:asDefault +Would you like to add another addon? false +``` + +Edit ```frontend/package.json``` and change ```"@plone/volto": "13.15.1",``` to ```"@plone/volto": "14.0.0-alpha.23",``` + +And run ```cd frontend && yarn``` + +Start it with + +```yarn start``` + +## Running everything with docker + +```shell +make start-images +``` diff --git a/ansible/.gitignore b/ansible/.gitignore new file mode 100644 index 0000000..af6d6ab --- /dev/null +++ b/ansible/.gitignore @@ -0,0 +1,7 @@ +.vagrant +.vagrant_private_key +bin +include +lib +lib64 +pyvenv.cfg diff --git a/ansible/Makefile b/ansible/Makefile new file mode 100644 index 0000000..82a97fe --- /dev/null +++ b/ansible/Makefile @@ -0,0 +1,70 @@ +### Defensive settings for make: +# https://tech.davis-hansson.com/p/make/ +SHELL:=bash +.ONESHELL: +.SHELLFLAGS:=-xeu -o pipefail -O inherit_errexit -c +.SILENT: +.DELETE_ON_ERROR: +MAKEFLAGS+=--warn-undefined-variables +MAKEFLAGS+=--no-builtin-rules + + +# We like colors +# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects +RED=`tput setaf 1` +GREEN=`tput setaf 2` +RESET=`tput sgr0` +YELLOW=`tput setaf 3` + +.PHONY: all +all: build + +# Add the following 'help' target to your Makefile +# And add help text after each target name starting with '\#\#' +.PHONY: help +help: ## This help message + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: clean +clean: ## remove all build, test, coverage and Python artifacts + rm -Rf bin lib lib64 include pyvenv.cfg + +bin/pip: + @echo "$(GREEN)==> Setup Virtual Env$(RESET)" + python3 -m venv . + bin/pip install -U pip + +bin/ansible: bin/pip + @echo "$(GREEN)==> Setup Ansible $(RESET)" + bin/pip install -r requirements.txt --upgrade + +.PHONY: setup +setup: bin/ansible ## Create VirtualEnv and install Ansible via Pip + @echo "$(GREEN)==> Ansible available at ./bin/ansible $(RESET)" + +.PHONY: vagrant-provision +vagrant-destroy: bin/ansible ## Provision Vagrant box + @echo "$(GREEN)==> Provision Vagrant box $(RESET)" + sudo vagrant destroy + sudo rm .vagrant_private_key .vagrant + +.PHONY: vagrant-provision +vagrant-provision: bin/ansible ## Provision Vagrant box + @echo "$(GREEN)==> Provision Vagrant box $(RESET)" + sudo vagrant up + sudo cp .vagrant/machines/default/virtualbox/private_key .vagrant_private_key + USER=`whoami` sudo chown ${USER}: .vagrant_private_key + ssh-keygen -f ~/.ssh/known_hosts -R "[127.0.0.1]:2222" + +.PHONY: playbook-setup +playbook-setup: bin/ansible ## Run playbook + @echo "$(GREEN)==> Apply playbook $(RESET)" + ./bin/ansible-playbook -i hosts playbook-setup.yml + +.PHONY: compose-pull +compose-pull: ## Run Compose pull + docker-compose --context vagrant --project-directory project pull + +.PHONY: compose-up +compose-up: ## Run Compose up + docker-compose --context vagrant --project-directory project up -d diff --git a/ansible/README.md b/ansible/README.md new file mode 100644 index 0000000..7237833 --- /dev/null +++ b/ansible/README.md @@ -0,0 +1,70 @@ +# Ansible deployment + +## Setup + +Install Python 3 virtual environment and Ansible + +```shell +cd ansible +make clean +make setup +``` + +## Provision a local Vagrant box + +```shell +make vagrant-provision +``` + +This may take a while to download the Ubuntu 20.04 Vagrant image. + +To check if the vagrant box is up and running: + +```shell +sudo vagrant status +``` + +## Configure the server + +Now we run an Ansible playbook (`playbook-setup.yml`) that will: + +* Install base packages +* Create a user plone +* Configure nginx webserver to listen on port 80 (`files/nginx/default`) +* Copy the docker-compose.yml configuration to the server + +First, you need to edit the file `playbook-setup.yml` and replace the line: +``` + - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDJIwjHxRAM1a8zc1kuTJ0GyzvloaBTz/fO7bGoNOlxY2lnUDop+q3CbHF28IkmVQCk28I+MXCnUXG6ARZgnBcb4LDey9WPVsiy3NRCXOmaZK6NKmKUejdA5Y4ZTHbs6rdIInDLWaFxzoxg5p/LaXUaTrKra2SpGc3kv7xKiZKXyTznFjFSv/u6Wm/vvZopWM6m4k8Z00fTUtxQO0eWKArStF99YFszUDU2w2jhL7n8irLow0UqjNjp0MvkPiic2SueoylQRIlD57XzveMBpGynYdsZWKDa3Czzo5ykHPLYrOByioKKjnpwgruXnXkkN4ov8sK+LqqAXaicxed6ohbOh68IWVB8nssb+RbISmzzpIXUwd1qkAyeiSjt5b9MFcIT56zeRb5B+aWZbYffc+pKy8kAjrYHCWEFl6O3N+M/bI9jgtXcZ9L6FSBN5vWjgRQPn7UwiMXIUssm0lU5AgCxs7q7S0xACj0xVFk5NeUM9vcCzXkY9vAjJmE1hzBWeOVhhQqLKmkbi/scr5hW2rrNwnuPBpyHUu2wTIyGHbnZ9CCwU3u21XDyvvO9ufxDjIH3v2EwEPqpbejKRM8QUH6YuH2goy89yQQijsC0YUE8AlJpbs9ctxSyzsJ6Z3ZwHJA681Ei15omhab2iwmT4KcS+3mC5pSCsFQgA4OsJKy5OQ== ericof@gmail.com" +``` +With your ssh public key (probably available in `~/.ssh/id_rsa.pub`) + +Then we run the playbook: + +```shell +make playbook-setup +``` + +You can test if the `plone` user setup is correct: + +```shell +ssh plone@127.0.0.1 -p 2222 +``` + +## Create a new Docker context + +```shell +docker context create vagrant --description "Plone Deployment training" --docker "host=ssh://plone@127.0.0.1:2222" +``` + +## Pull Docker images + +```shell +make compose-pull +``` + +## Start all services + +```shell +make compose-up +``` diff --git a/ansible/Vagrantfile b/ansible/Vagrantfile new file mode 100644 index 0000000..efbb604 --- /dev/null +++ b/ansible/Vagrantfile @@ -0,0 +1,13 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure(2) do |config| + config.vm.box = "ubuntu/focal64" + config.vm.network "forwarded_port", guest: 80, host: 80 + config.vm.network "forwarded_port", guest: 3000, host: 3000 + config.vm.network "forwarded_port", guest: 8080, host: 8080 + config.vm.provider "virtualbox" do |vb| + vb.memory = 2048 + vb.cpus = 1 + end +end diff --git a/ansible/docker-compose.yml b/ansible/docker-compose.yml new file mode 100644 index 0000000..613f97d --- /dev/null +++ b/ansible/docker-compose.yml @@ -0,0 +1,38 @@ +version: "3" +services: + + frontend: + image: plone/plone-frontend:14.0.0-alpha-node14 + environment: + RAZZLE_INTERNAL_API_PATH: http://backend:8080/Plone + RAZZLE_DEV_PROXY_API_PATH: http://backend:8080/Plone + restart: always + ports: + - "3000:3000" + depends_on: + - backend + + backend: + image: plone/plone-backend:6.0-dev-python39 + environment: + RELSTORAGE_DSN: "dbname='plone' user='plone' host='db' password='plone'" + restart: always + ports: + - "8080:8080" + depends_on: + - db + + db: + image: postgres + environment: + POSTGRES_USER: plone + POSTGRES_PASSWORD: plone + POSTGRES_DB: plone + restart: always + volumes: + - data:/var/lib/postgresql/data + ports: + - "5432:5432" + +volumes: + data: {} diff --git a/ansible/files/nginx/default b/ansible/files/nginx/default new file mode 100644 index 0000000..5210b89 --- /dev/null +++ b/ansible/files/nginx/default @@ -0,0 +1,44 @@ +upstream backend { + server localhost:8080; +} +upstream frontend { + server localhost:3000; +} + + +server { + listen 80; + server_name localhost + vagrant; + + location ~ /\+\+api\+\+($|/.*) { + rewrite ^/\+\+api\+\+($|/.*) /VirtualHostBase/http/$server_name/Plone/++api++/VirtualHostRoot/$1 break; + proxy_pass http://backend; + } + + location ~ / { + location ~* \.(js|jsx|css|less|swf|eot|ttf|otf|woff|woff2)$ { + add_header Cache-Control "public"; + expires +1y; + proxy_pass http://frontend; + } + location ~* static.*\.(ico|jpg|jpeg|png|gif|svg)$ { + add_header Cache-Control "public"; + expires +1y; + proxy_pass http://frontend; + } + + location ~ /(@@download|@@images|@@ical_view) { + rewrite ^(.*) /VirtualHostBase/http/$server_name/Plone/VirtualHostRoot$1 break; + proxy_pass http://backend; + break; + } + + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_redirect http:// https://; + proxy_pass http://frontend; + } +} \ No newline at end of file diff --git a/ansible/hosts b/ansible/hosts new file mode 100644 index 0000000..1d01f15 --- /dev/null +++ b/ansible/hosts @@ -0,0 +1,5 @@ +# Define all machines and then group them +vagrant ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222 ansible_user=vagrant ansible_ssh_private_key_file=./.vagrant_private_key + +[all] +vagrant \ No newline at end of file diff --git a/ansible/playbook-setup.yml b/ansible/playbook-setup.yml new file mode 100644 index 0000000..20a2e90 --- /dev/null +++ b/ansible/playbook-setup.yml @@ -0,0 +1,66 @@ +- hosts: "all" + gather_facts: True + become: yes + + tasks: + - name: Install Packages + ansible.builtin.apt: + name: + - nginx + - docker.io + - python3-pip + state: present + update_cache: yes + + - name: Install Docker Python Packages + ansible.builtin.pip: + name: + - docker + - docker-compose + state: present + + - name: Create user plone + ansible.builtin.user: + name: plone + comment: Plone User + groups: + - docker + shell: '/bin/bash' + remove: yes + append: yes + state: present + + - name: Set SSH Key for plone + ansible.builtin.authorized_key: + user: plone + key: "{{ item }}" + state: present + with_items: + - "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDJIwjHxRAM1a8zc1kuTJ0GyzvloaBTz/fO7bGoNOlxY2lnUDop+q3CbHF28IkmVQCk28I+MXCnUXG6ARZgnBcb4LDey9WPVsiy3NRCXOmaZK6NKmKUejdA5Y4ZTHbs6rdIInDLWaFxzoxg5p/LaXUaTrKra2SpGc3kv7xKiZKXyTznFjFSv/u6Wm/vvZopWM6m4k8Z00fTUtxQO0eWKArStF99YFszUDU2w2jhL7n8irLow0UqjNjp0MvkPiic2SueoylQRIlD57XzveMBpGynYdsZWKDa3Czzo5ykHPLYrOByioKKjnpwgruXnXkkN4ov8sK+LqqAXaicxed6ohbOh68IWVB8nssb+RbISmzzpIXUwd1qkAyeiSjt5b9MFcIT56zeRb5B+aWZbYffc+pKy8kAjrYHCWEFl6O3N+M/bI9jgtXcZ9L6FSBN5vWjgRQPn7UwiMXIUssm0lU5AgCxs7q7S0xACj0xVFk5NeUM9vcCzXkY9vAjJmE1hzBWeOVhhQqLKmkbi/scr5hW2rrNwnuPBpyHUu2wTIyGHbnZ9CCwU3u21XDyvvO9ufxDjIH3v2EwEPqpbejKRM8QUH6YuH2goy89yQQijsC0YUE8AlJpbs9ctxSyzsJ6Z3ZwHJA681Ei15omhab2iwmT4KcS+3mC5pSCsFQgA4OsJKy5OQ== ericof@gmail.com" + + - name: Create Project directory + ansible.builtin.file: + dest: /home/plone/project/ + state: directory + owner: plone + group: plone + mode: 0750 + + - name: Copy configuration + ansible.builtin.copy: + src: ./docker-compose.yml + dest: /home/plone/project/docker-compose.yml + owner: plone + group: plone + mode: 0640 + + - name: Copy configuration + ansible.builtin.copy: + src: files/nginx/default + dest: /etc/nginx/sites-enabled/default + mode: '0644' + + - name: restart nginx + service: + name: nginx + state: reloaded \ No newline at end of file diff --git a/ansible/requirements.txt b/ansible/requirements.txt new file mode 100644 index 0000000..c26ac75 --- /dev/null +++ b/ansible/requirements.txt @@ -0,0 +1,2 @@ +wheel +ansible diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..e8d08f8 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,6 @@ +* +!requirements.txt +!requirements/ +!skel +!src +!scripts diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..b5eef27 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,40 @@ +.coverage +*.egg-info +*.log +*.mo +*.py? +*.swp +# dirs +bin/ +buildout-cache/ +data/*.json +develop-eggs/ +eggs/ +etc/ +htmlcov/ +include/ +lib/ +lib64/ +local/ +node_modules/ +parts/ +src/ploneconf.core/setuphandlers/data/*.json +dist/* +test.plone_addon/ +var/ +# files +.installed.cfg +.mr.developer.cfg +lib64 +log.html +output.xml +pip-selfcheck.json +report.html +.vscode/ +.tox/ +reports/ +venv/ +# excludes +live.cfg +inituser +pip-wheel-metadata diff --git a/backend/.gitkeep b/backend/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..0a35967 --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,5 @@ +FROM plone/plone-backend:6.0.0a1 + +# Add local code +COPY . ./ +RUN ./bin/pip install -r requirements.txt --use-deprecated legacy-resolver diff --git a/backend/Makefile b/backend/Makefile new file mode 100644 index 0000000..aaad42c --- /dev/null +++ b/backend/Makefile @@ -0,0 +1,81 @@ +### Defensive settings for make: +# https://tech.davis-hansson.com/p/make/ +SHELL:=bash +.ONESHELL: +.SHELLFLAGS:=-xeu -o pipefail -O inherit_errexit -c +.SILENT: +.DELETE_ON_ERROR: +MAKEFLAGS+=--warn-undefined-variables +MAKEFLAGS+=--no-builtin-rules + +# We like colors +# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects +RED=`tput setaf 1` +GREEN=`tput setaf 2` +RESET=`tput sgr0` +YELLOW=`tput setaf 3` + +DOCKER_HUB_USER=DOCKER_HUB_USER_CHANGE_ME +IMAGE_NAME=${DOCKER_HUB_USER}/project-backend:latest + + +# Add the following 'help' target to your Makefile +# And add help text after each target name starting with '\#\#' +.PHONY: help +help: ## This help message + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: clean +clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts + +.PHONY: clean-build +clean-build: ## remove build artifacts + rm -fr build/ + rm -fr dist/ + rm -fr .eggs/ + find . -name '*.egg-info' -exec rm -fr {} + + find . -name '*.egg' -exec rm -f {} + + +.PHONY: clean-pyc +clean-pyc: ## remove Python file artifacts + find . -name '*.pyc' -exec rm -f {} + + find . -name '*.pyo' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + + find . -name '__pycache__' -exec rm -fr {} + + +.PHONY: clean-test +clean-test: ## remove test and coverage artifacts + rm -f .coverage + rm -fr htmlcov/ + +bin/pip: + @echo "$(GREEN)==> Setup Virtual Env$(RESET)" + python3 -m venv . + bin/pip install -U "pip" + +bin/mkwsgiinstance: bin/pip + @echo "$(GREEN)==> Install Plone and create instance$(RESET)" + bin/pip install --use-deprecated=legacy-resolver -r requirements/plone.txt + bin/mkwsgiinstance -s skel -d . -u admin:admin + +.PHONY: build +build: bin/mkwsgiinstance ## Create virtualenv and run buildout + @echo "$(GREEN)==> Setup Build$(RESET)" + bin/pip install --use-deprecated=legacy-resolver -r requirements.txt + +.PHONY: build +build-dev: bin/mkwsgiinstance ## Create virtualenv and run buildout + @echo "$(GREEN)==> Setup Build$(RESET)" + bin/pip install --use-deprecated=legacy-resolver -r requirements/dev.txt + +.PHONY: start +start: ## Start a Plone instance on localhost:8080 + PYTHONWARNINGS=ignore ./bin/runwsgi etc/zope.ini + +.PHONY: build-image +build-image: ## Build Docker Image + @docker build . -t $(IMAGE_NAME) -f Dockerfile + +.PHONY: release-image +release-image: ## Release Docker Image + @docker push $(IMAGE_NAME) diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..e37fcaf --- /dev/null +++ b/backend/README.md @@ -0,0 +1,13 @@ +# Plone Backend + +## Local Setup + +```shell +make setup +``` + +## Start Plone + +```shell +make start +``` diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 0000000..3794b28 --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1 @@ +pas.plugins.authomatic>=1.0b2 \ No newline at end of file diff --git a/backend/requirements/dev.txt b/backend/requirements/dev.txt new file mode 100644 index 0000000..d1f70df --- /dev/null +++ b/backend/requirements/dev.txt @@ -0,0 +1,3 @@ +-r unreleased.txt +black +isort diff --git a/backend/requirements/plone.txt b/backend/requirements/plone.txt new file mode 100644 index 0000000..fac775a --- /dev/null +++ b/backend/requirements/plone.txt @@ -0,0 +1,3 @@ +-c https://dist.plone.org/release/6.0.0a1/constraints.txt +Plone +plone.volto diff --git a/backend/requirements/unreleased.txt b/backend/requirements/unreleased.txt new file mode 100644 index 0000000..e69de29 diff --git a/dockerfiles/frontend-backend-postgres.yml b/dockerfiles/frontend-backend-postgres.yml new file mode 100644 index 0000000..153a56d --- /dev/null +++ b/dockerfiles/frontend-backend-postgres.yml @@ -0,0 +1,38 @@ +version: "3" +services: + + frontend: + image: DOCKER_HUB_USER_CHANGE_ME/project-frontend:latest + environment: + RAZZLE_INTERNAL_API_PATH: http://backend:8080/Plone + RAZZLE_DEV_PROXY_API_PATH: http://backend:8080/Plone + restart: always + ports: + - "3000:3000" + depends_on: + - backend + + backend: + image: DOCKER_HUB_USER_CHANGE_ME/project-backend:latest + environment: + RELSTORAGE_DSN: "dbname='plone' user='plone' host='db' password='plone'" + restart: always + ports: + - "8080:8080" + depends_on: + - db + + db: + image: postgres + environment: + POSTGRES_USER: plone + POSTGRES_PASSWORD: plone + POSTGRES_DB: plone + restart: always + volumes: + - data:/var/lib/postgresql/data + ports: + - "5432:5432" + +volumes: + data: {} diff --git a/dockerfiles/frontend-backend-zeo.yml b/dockerfiles/frontend-backend-zeo.yml new file mode 100644 index 0000000..2f58afa --- /dev/null +++ b/dockerfiles/frontend-backend-zeo.yml @@ -0,0 +1,34 @@ +version: "3" +services: + + frontend: + image: DOCKER_HUB_USER_CHANGE_ME/project-frontend:latest + environment: + RAZZLE_INTERNAL_API_PATH: http://backend:8080/Plone + RAZZLE_DEV_PROXY_API_PATH: http://backend:8080/Plone + restart: always + ports: + - "3000:3000" + depends_on: + - backend + + backend: + image: DOCKER_HUB_USER_CHANGE_ME/project-backend:latest + environment: + ZEO_ADDRESS: zeo:8100 + restart: always + ports: + - "8080:8080" + depends_on: + - db + + db: + image: plone/plone-zeo:latest + restart: always + volumes: + - data:/data + ports: + - "8100:8100" + +volumes: + data: {} diff --git a/dockerfiles/frontend-backend.yml b/dockerfiles/frontend-backend.yml new file mode 100644 index 0000000..2c5ed81 --- /dev/null +++ b/dockerfiles/frontend-backend.yml @@ -0,0 +1,24 @@ +version: "3" +services: + + frontend: + image: DOCKER_HUB_USER_CHANGE_ME/project-frontend:latest + environment: + RAZZLE_INTERNAL_API_PATH: http://backend:8080/Plone + RAZZLE_DEV_PROXY_API_PATH: http://backend:8080/Plone + restart: always + ports: + - "3000:3000" + depends_on: + - backend + + backend: + image: DOCKER_HUB_USER_CHANGE_ME/project-backend:latest + restart: always + ports: + - "8080:8080" + volumes: + - data:/data + +volumes: + data: {} diff --git a/dockerfiles/local-dev.yml b/dockerfiles/local-dev.yml new file mode 100644 index 0000000..5f38f2d --- /dev/null +++ b/dockerfiles/local-dev.yml @@ -0,0 +1,26 @@ +version: "3" +services: + + frontend: + build: + context: ../frontend + environment: + RAZZLE_INTERNAL_API_PATH: http://backend:8080/Plone + RAZZLE_DEV_PROXY_API_PATH: http://backend:8080/Plone + restart: always + ports: + - "3000:3000" + depends_on: + - backend + + backend: + build: + context: ../backend + restart: always + ports: + - "8080:8080" + volumes: + - data:/data + +volumes: + data: {} diff --git a/docs/plone-setup.png b/docs/plone-setup.png new file mode 100644 index 0000000..7dd62b9 Binary files /dev/null and b/docs/plone-setup.png differ diff --git a/frontend/.gitkeep b/frontend/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/frontend/Dockerfile b/frontend/Dockerfile new file mode 100644 index 0000000..6716d6e --- /dev/null +++ b/frontend/Dockerfile @@ -0,0 +1,39 @@ +FROM node:14-slim as base +FROM base as builder + +# Create app directory +WORKDIR /usr/src/app + +RUN apt-get update \ + && buildDeps="python3 build-essential" \ + && apt-get install -y --no-install-recommends $buildDeps\ + && rm -rf /var/lib/apt/lists/* + +# Install app dependencies +# A wildcard is used to ensure both package.json AND package-lock.json are copied +# where available (npm@5+) +COPY package.json yarn.lock ./ +RUN yarn install --prod + +# Bundle app source +COPY . . + +RUN yarn build + +FROM base + +LABEL maintainer="Plone Community" \ + org.label-schema.name="plone" \ + org.label-schema.description="Plone 6 frontend site." \ + org.label-schema.vendor="Plone Community" \ + org.label-schema.docker.cmd="docker run -d -p 3000:3000 plone/project:latest" + +WORKDIR /usr/src + +COPY --from=builder /usr/src/app . + +WORKDIR /usr/src/app + +EXPOSE 3000 + +CMD ["yarn", "start:prod"] diff --git a/frontend/Makefile b/frontend/Makefile new file mode 100644 index 0000000..5a346b2 --- /dev/null +++ b/frontend/Makefile @@ -0,0 +1,34 @@ +### Defensive settings for make: +# https://tech.davis-hansson.com/p/make/ +SHELL:=bash +.ONESHELL: +.SHELLFLAGS:=-xeu -o pipefail -O inherit_errexit -c +.SILENT: +.DELETE_ON_ERROR: +MAKEFLAGS+=--warn-undefined-variables +MAKEFLAGS+=--no-builtin-rules + +# We like colors +# From: https://coderwall.com/p/izxssa/colored-makefile-for-golang-projects +RED=`tput setaf 1` +GREEN=`tput setaf 2` +RESET=`tput sgr0` +YELLOW=`tput setaf 3` + +DOCKER_HUB_USER=DOCKER_HUB_USER_CHANGE_ME +IMAGE_NAME=${DOCKER_HUB_USER}/project-frontend:latest + + +# Add the following 'help' target to your Makefile +# And add help text after each target name starting with '\#\#' +.PHONY: help +help: ## This help message + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +.PHONY: build-image +build-image: ## Build Docker Image + @docker build . -t $(IMAGE_NAME) -f Dockerfile + +.PHONY: release-image +release-image: ## Release Docker Image + @docker push $(IMAGE_NAME)