2
0
mirror of https://github.com/frappe/frappe_docker.git synced 2025-04-05 08:51:50 +00:00

Merge pull request #84 from revant/master

feat: docker production images
This commit is contained in:
Chinmay Pai 2020-03-02 21:17:14 +05:30 committed by GitHub
commit 6a8eb99331
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
40 changed files with 1924 additions and 65 deletions

6
.gitignore vendored
View File

@ -1 +1,7 @@
*.code-workspace *.code-workspace
# Environment Variables
.env
# mounted volume
sites

View File

@ -1,30 +1,192 @@
sudo: required
dist: xenial dist: xenial
env:
- DOCKER_COMPOSE_VERSION: 1.23.1
services: services:
- docker - docker
before_install: before_install:
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - - if [[ "$BUILD" -ne "development" ]]; then
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin;
- sudo apt-get update sudo apt-get update && sudo apt-get -y install git;
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce fi
- sudo rm /usr/local/bin/docker-compose - if [[ $BUILD == "development" ]];then
- curl -L https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-`uname -s`-`uname -m` > docker-compose sudo apt-get update && sudo apt-get -y install docker-compose;
- chmod +x docker-compose fi
- sudo mv docker-compose /usr/local/bin
install: install:
- chmod ugo+x ./dbench - if [[ $BUILD == "development" ]];then
- chmod ugo+x ./test.sh chmod ugo+x ./dbench;
- ./dbench setup docker chmod ugo+x ./test.sh;
- ./dbench init frappe-bench ./dbench setup docker;
- ./dbench new-site site1.local ./dbench init frappe-bench;
- ./dbench setup hosts ./dbench new-site site1.local;
./dbench setup hosts;
fi
after_success:
- docker --version
matrix:
include:
- name: "Test Frappe / ERPNext development"
env: BUILD=development
script: script:
- ./test.sh - ./test.sh
- ./dbench setup docker stop - ./dbench setup docker stop
- name: "Build Frappe python environment (edge)"
if: branch = develop AND type != pull_request
script:
- docker build -t frappe-worker -f build/frappe-worker/Dockerfile .
- docker tag frappe-worker frappe/frappe-worker:edge
- docker tag frappe-worker frappe/frappe-worker:develop
- docker push frappe/frappe-worker:edge
- name: "Build Frappe nginx + static assets (edge)"
if: branch = develop AND type != pull_request
script:
- docker build -t frappe-assets -f build/frappe-assets/Dockerfile .
- docker tag frappe-assets frappe/frappe-assets:edge
- docker tag frappe-assets frappe/frappe-assets:develop
- docker push frappe/frappe-assets:edge
- name: "Build ERPNext python environment (edge)"
if: branch = develop AND type != pull_request
script:
- docker build -t erpnext-worker -f build/erpnext-worker/Dockerfile .
- docker tag erpnext-worker frappe/erpnext-worker:edge
- docker tag erpnext-worker frappe/erpnext-worker:develop
- docker push frappe/erpnext-worker:edge
- name: "Build ERPNext nginx + static assets (edge)"
if: branch = develop AND type != pull_request
script:
- docker build -t erpnext-assets -f build/erpnext-assets/Dockerfile .
- docker tag erpnext-assets frappe/erpnext-assets:edge
- docker tag erpnext-assets frappe/erpnext-assets:develop
- docker push frappe/erpnext-assets:edge
- name: "Build Frappe socketio service (edge)"
if: branch = develop AND type != pull_request
script:
- docker build -t frappe-socketio -f build/frappe-socketio/Dockerfile .
- docker tag frappe-socketio frappe/frappe-socketio:edge
- docker tag frappe-socketio frappe/frappe-socketio:develop
- docker push frappe/frappe-socketio:edge
- name: "Build Frappe python environment (v12)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/frappe --branch version-12
- cd frappe
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v12*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/frappe-worker:$VERSION -f build/frappe-worker/v12.Dockerfile .
- docker tag frappe/frappe-worker:$VERSION frappe/frappe-worker:version-12
- docker tag frappe/frappe-worker:$VERSION frappe/frappe-worker:v12
- docker tag frappe/frappe-worker:$VERSION frappe/frappe-worker:$VERSION
- docker push frappe/frappe-worker:$VERSION
- name: "Build Frappe nginx + static assets (v12)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/frappe --branch version-12
- cd frappe
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v12*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/frappe-assets:$VERSION -f build/frappe-assets/v12.Dockerfile .
- docker tag frappe/frappe-assets:$VERSION frappe/frappe-assets:version-12
- docker tag frappe/frappe-assets:$VERSION frappe/frappe-assets:v12
- docker push frappe/frappe-assets:$VERSION
- name: "Build ERPNext python environment (v12)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/erpnext --branch version-12
- cd erpnext
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v12*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/erpnext-worker:$VERSION -f build/erpnext-worker/v12.Dockerfile .
- docker tag frappe/erpnext-worker:$VERSION frappe/erpnext-worker:version-12
- docker tag frappe/erpnext-worker:$VERSION frappe/erpnext-worker:v12
- docker push frappe/erpnext-worker:$VERSION
- name: "Build ERPNext nginx + static assets (v12)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/erpnext --branch version-12
- cd erpnext
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v12*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/erpnext-assets:$VERSION -f build/erpnext-assets/v12.Dockerfile .
- docker tag frappe/erpnext-assets:$VERSION frappe/erpnext-assets:version-12
- docker tag frappe/erpnext-assets:$VERSION frappe/erpnext-assets:v12
- docker push frappe/erpnext-assets:$VERSION
- name: "Build Frappe socketio service (v12)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/frappe --branch version-12
- cd frappe
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v12*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/frappe-socketio:$VERSION -f build/frappe-socketio/v12.Dockerfile .
- docker tag frappe/frappe-socketio:$VERSION frappe/frappe-socketio:version-12
- docker tag frappe/frappe-socketio:$VERSION frappe/frappe-socketio:v12
- docker push frappe/frappe-socketio:$VERSION
- name: "Build Frappe python environment (v11)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/frappe --branch version-11
- cd frappe
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v11*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/frappe-worker:$VERSION -f build/frappe-worker/v11.Dockerfile .
- docker tag frappe/frappe-worker:$VERSION frappe/frappe-worker:version-11
- docker tag frappe/frappe-worker:$VERSION frappe/frappe-worker:v11
- docker push frappe/frappe-worker:$VERSION
- name: "Build Frappe nginx + static assets (v11)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/frappe --branch version-11
- cd frappe
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v11*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/frappe-assets:$VERSION -f build/frappe-assets/v11.Dockerfile .
- docker tag frappe/frappe-assets:$VERSION frappe/frappe-assets:version-11
- docker tag frappe/frappe-assets:$VERSION frappe/frappe-assets:v11
- docker push frappe/frappe-assets:$VERSION
- name: "Build ERPNext python environment (v11)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/erpnext --branch version-11
- cd erpnext
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v11*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/erpnext-worker:$VERSION -f build/erpnext-worker/v11.Dockerfile .
- docker tag frappe/erpnext-worker:$VERSION frappe/erpnext-worker:version-11
- docker tag frappe/erpnext-worker:$VERSION frappe/erpnext-worker:v11
- docker push frappe/erpnext-worker:$VERSION
- name: "Build ERPNext nginx + static assets (v11)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/erpnext --branch version-11
- cd erpnext
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v11*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/erpnext-assets:$VERSION -f build/erpnext-assets/v11.Dockerfile .
- docker tag frappe/erpnext-assets:$VERSION frappe/erpnext-assets:version-11
- docker tag frappe/erpnext-assets:$VERSION frappe/erpnext-assets:v11
- docker push frappe/erpnext-assets:$VERSION
- name: "Build Frappe socketio service (v11)"
if: branch = master AND type != pull_request
script:
- git clone https://github.com/frappe/frappe --branch version-11
- cd frappe
- git fetch --tags
- export VERSION=$(git tag --list --sort=-version:refname "v11*" | sed -n 1p | sed -e 's#.*@\(\)#\1#')
- cd ..
- docker build -t frappe/frappe-socketio:$VERSION -f build/frappe-socketio/v11.Dockerfile .
- docker tag frappe/frappe-socketio:$VERSION frappe/frappe-socketio:version-11
- docker tag frappe/frappe-socketio:$VERSION frappe/frappe-socketio:v11
- docker push frappe/frappe-socketio:$VERSION

241
README.md
View File

@ -1,73 +1,232 @@
# Frappe on Docker ### Getting Started
[![Build Status](https://travis-ci.com/frappe/frappe_docker.svg)](https://travis-ci.com/frappe/frappe_docker) The templates in this repository will help deploy Frappe/ERPNext docker in a production environment.
This is a repo designed to aide setting up frappe/ERPNext on docker. This docker installation takes care of the following:
## Getting Started * Setting up the desired version of Frappe/ERPNext.
* Setting up all the system requirements: eg. MariaDB, Node, Redis.
* [OPTIONAL] Configuring networking for remote access and setting up LetsEncrypt
These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. ### Installation Process
Unfortunately, this container is not currently suited for a production environment (but we're working towards that goal!). #### Setting up Pre-requisites
### Build the container and initialize the bench This repository requires Docker and Git to be setup on the instance to be used.
**Note:** These instructions assume you have both [Docker](https://docs.docker.com/engine/installation) and [Docker Compose](https://docs.docker.com/compose/install/) installed on your system. #### Setup Letsencrypt Nginx Proxy Companion
1. Clone this repo and change your working directory to it: This is an optional first step. This step is only required if you want to have SSL setup on your docker instance.
```bash This step also assumes that the DNS is preconfigured since it automatically handles setup and renewal of SSL certificates.
For more details, see: https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion
To setup the proxy companion, run the following steps:
```sh
cd $HOME
git clone https://github.com/evertramos/docker-compose-letsencrypt-nginx-proxy-companion.git
cd docker-compose-letsencrypt-nginx-proxy-companion
cp .env.sample .env
./start.sh
```
#### Setting up Frappe/ERPNext Docker
Clone this repository somewhere in your system:
```sh
git clone https://github.com/frappe/frappe_docker.git git clone https://github.com/frappe/frappe_docker.git
cd frappe_docker/ cd frappe_docker
``` ```
2. Build and start the container, and initialize the bench: Copy the example docker environment file to `.env`:
```bash ```
./dbench setup docker cp installation/env-example installation/.env
./dbench init
``` ```
**Note:** This will take a while, as docker will now build the container. Make a directory for sites:
3. Add a new site and start Frappe: ```sh
mkdir installation/sites
```bash
./dbench new-site site1.local
./dbench setup hosts
./dbench start
``` ```
4. Use Frappe: #### Setup Environment Variables
Open your browser to `localhost:8000/login`. Then log in using the username `Administrator` and the password `admin`.
### Basic Usage of `./dbench` Docker allows passing an environment file to aide in setting up containers, which is used by this repository to pass secret and variable data.
**IMPORTANT: Always make sure that your current directory is the root directory of the repo (i.e. `frappe_docker/`)** To get started, copy the existing `env-example` file to `.env` inside the `installation` directory. By default, the file will contain the following variables:
- `./dbench`: Launches you into an interactive shell in the container as the user `frappe`. - `VERSION=edge`
- In this case, `edge` corresponds to `develop`. To setup any other version, you may use the branch name or version specific tags. (eg. version-12, v11.1.15, v11)
- `MYSQL_ROOT_PASSWORD=admin`
- Bootstraps a MariaDB container with this value set as the root password. If a managed MariaDB instance is to be used, there is no need to set the password here.
- `MARIADB_HOST=mariadb`
- Sets the hostname to `mariadb`. This is required if the database is managed with the containerized MariaDB instance.
- In case of a separately managed database setup, set the value to the database's hostname/IP/domain.
- `SITES=site1.domain.com,site2.domain.com`
- List of sites that are part of the deployment "bench". Each site is separated by a comma(,).
- If LetsEncrypt is being setup, make sure that the DNS for all the site domains are pointing to the current instance.
- `LETSENCRYPT_EMAIL=your.email@your.domain.com`
- Email for LetsEncrypt expiry notification. This is only required if you are setting up the nginx proxy companion.
- `./dbench setup docker [ stop | down ]`: Starts and builds the docker containers using `docker-compose up -d`. #### Start Frappe/ERPNext Services
- `stop`: Stops the containers with `docker-compose stop`.
- `down`: Deletes the containers and the corresponding volumes with `docker-compose down`.
- `./dbench setup hosts`: Adds all sites to the containers hosts file. To start the Frappe/ERPNext services, run the following command:
**Note:** Run this after you've added a new site to avoid errors.
- `./dbench -c frappe | root <command to run>`: Runs a command in the container, as the selected user. ```sh
docker-compose \
--project-name <project-name> \
-f installation/docker-compose-common.yml \
-f installation/docker-compose-erpnext.yml \
-f installation/docker-compose-networks.yml \
--project-directory installation up -d
```
- `./dbench -h`: Shows this help message. Make sure to replace `<project-name>` with any desired name you wish to set for the project.
- `./dbench <bench command>`: Runs a command in bench (i.e. Running `./dbench new-site site1.local`, will run `bench new-site site1.local` in the container). Note: use `docker-compose-frappe.yml` in case you need bench with just frappe installed.
## For More Info #### Setup New Sites
For more info on building this docker container refer to this [Wiki](https://github.com/frappe/frappe_docker/wiki/Hitchhiker's-guide-to-building-this-frappe_docker-image) Note:
## Contributing - Wait for the mariadb service to start before trying to create a new site.
- If new site creation fails, retry after the mariadb container is up and running.
- If you're using a managed database instance, make sure that the database is running before setting up a new site.
- Use `.env` file or environment variables instead of passing secrets as command arguments.
Feel free to contribute to this project and make it better. ```sh
# Create ERPNext site
docker exec -it \
-e "SITE_NAME=$SITE_NAME" \
-e "DB_ROOT_USER=$DB_ROOT_USER" \
-e "MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" \
-e "ADMIN_PASSWORD=$ADMIN_PASSWORD" \
-e "INSTALL_ERPNEXT=1" \
<project-name>_erpnext-python_1 docker-entrypoint.sh new
```
## License Environment Variables needed:
This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details - `SITE_NAME`: name of the new site to create.
- `DB_ROOT_USER`: MariaDB Root user. The user that can create databases.
- `MYSQL_ROOT_PASSWORD`: In case of mariadb docker container use the one set in `MYSQL_ROOT_PASSWORD` in previous steps. In case of managed database use appropriate password.
- `ADMIN_PASSWORD`: set the administrator password for new site.
- `INSTALL_ERPNEXT=1`: available only in erpnext-worker and erpnext containers. Installs ERPNext on this new site.
- `FORCE=1`: is optional variable which force installs the same site.
#### Backup Sites
Environment Variables
- `SITES` is list of sites separated by (:) colon to migrate. e.g. `SITES=site1.domain.com` or `SITES=site1.domain.com:site2.domain.com` By default all sites in bench will be backed up.
- `WITH_FILES` if set to 1, it will backup user uploaded files for the sites.
```sh
docker exec -it \
-e "SITES=site1.domain.com:site2.domain.com" \
-e "WITH_FILES=1" \
<project-name>_erpnext-python_1 docker-entrypoint.sh backup
```
Backup will be available in the `sites` mounted volume.
#### Updating and Migrating Sites
Switch to the root of the `frappe_docker` directory before running the following commands:
```sh
# Update environment variable VERSION
nano .env
# Pull new images
docker-compose \
-f installation/docker-compose-common.yml \
-f installation/docker-compose-erpnext.yml \
pull
# Restart containers
docker-compose \
--project-name <project-name> \
-f installation/docker-compose-common.yml \
-f installation/docker-compose-erpnext.yml \
-f installation/docker-compose-networks.yml \
--project-directory installation up -d
docker exec -it \
-e "MAINTENANCE_MODE=1" \
<project-name>_erpnext-python_1 docker-entrypoint.sh migrate
```
### Troubleshoot
1. Remove containers and volumes, and clear redis cache:
This can be used when existing images are upgraded and migration fails.
```
# change to repo root
cd $HOME/frappe_docker
# Stop all bench containers
docker-compose \
--project-name <project-name> \
-f installation/docker-compose-common.yml \
-f installation/docker-compose-erpnext.yml \
-f installation/docker-compose-networks.yml \
--project-directory installation stop
# Remove redis containers
docker-compose \
--project-name <project-name> \
-f installation/docker-compose-common.yml \
-f installation/docker-compose-erpnext.yml \
-f installation/docker-compose-networks.yml \
--project-directory installation rm redis-cache redis-queue redis-socketio
# Clean redis volumes
docker volume rm \
<project-name>_redis-cache-vol \
<project-name>_redis-queue-vol \
<project-name>_redis-socketio-vol
# Restart project
docker-compose \
--project-name <project-name> \
-f installation/docker-compose-common.yml \
-f installation/docker-compose-erpnext.yml \
-f installation/docker-compose-networks.yml \
--project-directory installation up -d
```
2. Clear redis cache using `docker exec` command:
In case of following error during container restarts:
```
frappe-worker-short_1 | Traceback (most recent call last):
frappe-worker-short_1 | File "/home/frappe/frappe-bench/commands/worker.py", line 5, in <module>
frappe-worker-short_1 | start_worker(queue, False)
frappe-worker-short_1 | File "/home/frappe/frappe-bench/apps/frappe/frappe/utils/background_jobs.py", line 147, in start_worker
frappe-worker-short_1 | Worker(queues, name=get_worker_name(queue)).work(logging_level = logging_level)
frappe-worker-short_1 | File "/home/frappe/frappe-bench/env/lib/python3.7/site-packages/rq/worker.py", line 474, in work
frappe-worker-short_1 | self.register_birth()
frappe-worker-short_1 | File "/home/frappe/frappe-bench/env/lib/python3.7/site-packages/rq/worker.py", line 261, in register_birth
frappe-worker-short_1 | raise ValueError(msg.format(self.name))
frappe-worker-short_1 | ValueError: There exists an active worker named '8dfe5c234085.10.short' already
```
Use commands :
```sh
# Clear the cache which is causing problem.
docker exec -it <project-name>_redis-cache_1 redis-cli FLUSHALL
docker exec -it <project-name>_redis-queue_1 redis-cli FLUSHALL
docker exec -it <project-name>_redis-socketio_1 redis-cli FLUSHALL
```
Note: Environment variables from `.env` file located at current working directory will be used.

View File

@ -0,0 +1,7 @@
import frappe
from frappe.utils.scheduler import start_scheduler
print("Starting background scheduler . . .")
start_scheduler()
exit(0)

View File

@ -0,0 +1,29 @@
import os, frappe, compileall, re
from frappe.utils.backups import scheduled_backup
from frappe.utils import now
from frappe.utils import get_sites
def backup(sites, with_files=False):
for site in sites:
frappe.init(site)
frappe.connect()
odb = scheduled_backup(
ignore_files=not with_files,
backup_path_db=None,
backup_path_files=None,
backup_path_private_files=None,
force=True
)
print("database backup taken -", odb.backup_path_db, "- on", now())
if with_files:
print("files backup taken -", odb.backup_path_files, "- on", now())
print("private files backup taken -", odb.backup_path_private_files, "- on", now())
frappe.destroy()
installed_sites = ":".join(get_sites())
sites = os.environ.get("SITES", installed_sites).split(":")
with_files=True if os.environ.get("WITH_FILES") else False
backup(sites, with_files)
exit(0)

View File

@ -0,0 +1,67 @@
import socket, os, json, time
from six.moves.urllib.parse import urlparse
def is_open(ip, port, timeout=30):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(timeout)
try:
s.connect((ip, int(port)))
s.shutdown(socket.SHUT_RDWR)
return True
except:
return False
finally:
s.close()
def check_host(ip, port, retry=10, delay=3):
ipup = False
for i in range(retry):
print("Attempt {i} to connect to {ip}:{port}".format(ip=ip,port=port,i=i+1))
if is_open(ip, port):
ipup = True
break
else:
time.sleep(delay)
return ipup
# Check connection to servers
config = None
try:
with open('common_site_config.json') as config_file:
config = json.load(config_file)
except FileNotFoundError:
raise FileNotFoundError("common_site_config.json missing")
except:
raise ValueError("common_site_config.json is not valid")
# Check mariadb
check_mariadb = False
check_mariadb = check_host(config.get('db_host', 'mariadb'), 3306)
if not check_mariadb:
raise ConnectionError("Connection to mariadb timed out")
# Check redis queue
check_redis_queue = False
redis_queue_url = urlparse(config.get("redis_queue","redis://redis:6379")).netloc
redis_queue, redis_queue_port = redis_queue_url.split(":")
check_redis_queue = check_host(redis_queue, redis_queue_port)
if not check_redis_queue:
raise ConnectionError("Connection to redis queue timed out")
# Check redis cache
check_redis_cache = False
redis_cache_url = urlparse(config.get("redis_cache","redis://redis:6379")).netloc
redis_cache, redis_cache_port = redis_cache_url.split(":")
check_redis_cache = check_host(redis_cache, redis_cache_port)
if not check_redis_cache:
raise ConnectionError("Connection to redis cache timed out")
# Check redis socketio
check_redis_socketio = False
redis_socketio_url = urlparse(config.get("redis_socketio","redis://redis:6379")).netloc
redis_socketio, redis_socketio_port = redis_socketio_url.split(":")
check_redis_socketio = check_host(redis_socketio, redis_socketio_port)
if not check_redis_socketio:
raise ConnectionError("Connection to redis socketio timed out")
print('Connections OK')

View File

@ -0,0 +1,25 @@
import sys
import frappe
import IPython
from frappe.utils import get_sites
def console(site):
"Start ipython console for a site"
if site not in get_sites():
print("Site {0} does not exist on the current bench".format(site))
return
frappe.init(site=site)
frappe.connect()
frappe.local.lang = frappe.db.get_default("lang")
all_apps = frappe.get_installed_apps()
for app in all_apps:
locals()[app] = __import__(app)
print("Apps in this namespace:\n{}".format(", ".join(all_apps)))
IPython.embed(display_banner="", header="")
site = sys.argv[-1]
console(site)

View File

@ -0,0 +1,4 @@
import frappe
from frappe.utils.doctor import doctor
doctor()

View File

@ -0,0 +1,47 @@
import os, frappe, compileall, re, json
from frappe.migrate import migrate
from frappe.utils import get_sites
def get_config():
config = None
with open('common_site_config.json') as config_file:
config = json.load(config_file)
return config
def save_config(config):
with open('common_site_config.json', 'w') as f:
return json.dump(config, f, indent=1, sort_keys=True)
def set_maintenance_mode(enable=True):
conf = get_config()
if enable:
conf.update({ "maintenance_mode": 1, "pause_scheduler": 1 })
save_config(conf)
if not enable:
conf.update({ "maintenance_mode": 0, "pause_scheduler": 0 })
save_config(conf)
installed_sites = ":".join(get_sites())
sites = os.environ.get("SITES", installed_sites).split(":")
maintenance_mode = True if os.environ.get("MAINTENANCE_MODE") else False
if maintenance_mode:
set_maintenance_mode(True)
for site in sites:
print('Migrating', site)
frappe.init(site=site)
frappe.connect()
try:
migrate()
finally:
frappe.destroy()
if maintenance_mode:
set_maintenance_mode(False)
exit(0)

View File

@ -0,0 +1,67 @@
import os, frappe, json
from frappe.commands.site import _new_site
site_name = os.environ.get("SITE_NAME", 'site1.localhost')
mariadb_root_username = os.environ.get("DB_ROOT_USER", 'root')
mariadb_root_password = os.environ.get("MYSQL_ROOT_PASSWORD", 'admin')
force = True if os.environ.get("FORCE", None) else False
install_apps = ['erpnext'] if os.environ.get("INSTALL_ERPNEXT", None) else False
frappe.init(site_name, new_site=True)
_new_site(
None,
site_name,
mariadb_root_username=mariadb_root_username,
mariadb_root_password=mariadb_root_password,
admin_password=os.environ.get("ADMIN_PASSWORD", 'admin'),
verbose=True,
install_apps=install_apps,
source_sql=None,
force=force,
reinstall=False,
)
config = None
with open('common_site_config.json') as config_file:
config = json.load(config_file)
site_config = None
with open('{site_name}/site_config.json'.format(site_name=site_name)) as site_config_file:
site_config = json.load(site_config_file)
# update User's host to '%' required to connect from any container
command = 'mysql -h{db_host} -u{mariadb_root_username} -p{mariadb_root_password} -e '.format(
db_host=config.get('db_host'),
mariadb_root_username=mariadb_root_username,
mariadb_root_password=mariadb_root_password
)
command += "\"UPDATE mysql.user SET Host = '%' where User = '{db_name}'; FLUSH PRIVILEGES;\"".format(
db_name=site_config.get('db_name')
)
os.system(command)
# Set db password
command = 'mysql -h{db_host} -u{mariadb_root_username} -p{mariadb_root_password} -e '.format(
db_host=config.get('db_host'),
mariadb_root_username=mariadb_root_username,
mariadb_root_password=mariadb_root_password
)
command += "\"SET PASSWORD FOR '{db_name}'@'%' = PASSWORD('{db_password}'); FLUSH PRIVILEGES;\"".format(
db_name=site_config.get('db_name'),
db_password=site_config.get('db_password')
)
os.system(command)
# Grant permission to database
command = 'mysql -h{db_host} -u{mariadb_root_username} -p{mariadb_root_password} -e '.format(
db_host=config.get('db_host'),
mariadb_root_username=mariadb_root_username,
mariadb_root_password=mariadb_root_password
)
command += "\"GRANT ALL PRIVILEGES ON \`{db_name}\`.* TO '{db_name}'@'%'; FLUSH PRIVILEGES;\"".format(
db_name=site_config.get('db_name')
)
os.system(command)
exit(0)

View File

@ -0,0 +1,7 @@
import os, frappe
from frappe.utils.background_jobs import start_worker
queue = os.environ.get("WORKER_TYPE", "default")
start_worker(queue, False)
exit(0)

View File

@ -0,0 +1,7 @@
{
"db_host": "${MARIADB_HOST}",
"redis_cache": "redis://${REDIS_CACHE}",
"redis_queue": "redis://${REDIS_QUEUE}",
"redis_socketio": "redis://${REDIS_SOCKETIO}",
"socketio_port": ${SOCKETIO_PORT}
}

View File

@ -0,0 +1,90 @@
upstream frappe-server {
server ${FRAPPE_PY}:${FRAPPE_PY_PORT} fail_timeout=0;
}
upstream socketio-server {
server ${FRAPPE_SOCKETIO}:${SOCKETIO_PORT} fail_timeout=0;
}
server {
listen 80;
server_name $http_host;
root /var/www/html;
location /assets {
try_files $uri =404;
}
location ~ ^/protected/(.*) {
internal;
try_files /sites/$http_host/$1 =404;
}
location /socket.io {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Frappe-Site-Name $http_host;
proxy_set_header Origin $scheme://$http_host;
proxy_set_header Host $host;
proxy_pass http://socketio-server;
}
location / {
try_files /sites/$http_host/public/$uri @webserver;
}
location @webserver {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Frappe-Site-Name $http_host;
proxy_set_header Host $host;
proxy_set_header X-Use-X-Accel-Redirect True;
proxy_read_timeout 120;
proxy_redirect off;
proxy_pass http://frappe-server;
}
# error pages
error_page 502 /502.html;
location /502.html {
root /var/www/templates;
internal;
}
# optimizations
sendfile on;
keepalive_timeout 15;
client_max_body_size 50m;
client_body_buffer_size 16K;
client_header_buffer_size 1k;
# enable gzip compresion
# based on https://mattstauffer.co/blog/enabling-gzip-on-nginx-servers-including-laravel-forge
gzip on;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/font-woff
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
# text/html is always compressed by HttpGzipModule
}

View File

@ -0,0 +1,178 @@
#!/bin/bash
function configureEnv() {
if [ ! -f /home/frappe/frappe-bench/sites/common_site_config.json ]; then
if [[ -z "$MARIADB_HOST" ]]; then
echo "MARIADB_HOST is not set"
exit 1
fi
if [[ -z "$REDIS_CACHE" ]]; then
echo "REDIS_CACHE is not set"
exit 1
fi
if [[ -z "$REDIS_QUEUE" ]]; then
echo "REDIS_QUEUE is not set"
exit 1
fi
if [[ -z "$REDIS_SOCKETIO" ]]; then
echo "REDIS_SOCKETIO is not set"
exit 1
fi
if [[ -z "$SOCKETIO_PORT" ]]; then
echo "SOCKETIO_PORT is not set"
exit 1
fi
envsubst '${MARIADB_HOST}
${REDIS_CACHE}
${REDIS_QUEUE}
${REDIS_SOCKETIO}
${SOCKETIO_PORT}' < /opt/frappe/common_site_config.json.template > /home/frappe/frappe-bench/sites/common_site_config.json
fi
}
function checkConnection() {
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& python /home/frappe/frappe-bench/commands/check_connection.py"
}
function checkConfigExists() {
COUNTER=0
while [[ ! -e /home/frappe/frappe-bench/sites/common_site_config.json ]] && [[ $COUNTER -le 30 ]] ; do
sleep 1
(( COUNTER=COUNTER+1 ))
echo "config file not created, retry $COUNTER"
done
if [[ ! -e /home/frappe/frappe-bench/sites/common_site_config.json ]]; then
echo "timeout: config file not created"
exit 1
fi
}
if [[ ! -e /home/frappe/frappe-bench/sites/apps.txt ]]; then
find /home/frappe/frappe-bench/apps -mindepth 1 -maxdepth 1 -type d -printf '%f\n' | sort -r > /home/frappe/frappe-bench/sites/apps.txt
fi
# Allow user process to create files in logs directory
chown -R frappe:frappe /home/frappe/frappe-bench/logs
if [ "$1" = 'start' ]; then
configureEnv
checkConnection
chown frappe:frappe /home/frappe/frappe-bench/sites/common_site_config.json
if [[ -z "$WORKERS" ]]; then
export WORKERS=2
fi
if [[ -z "$FRAPPE_PORT" ]]; then
export FRAPPE_PORT=8000
fi
if [[ -z "$RUN_AS_ROOT" ]]; then
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& gunicorn -b 0.0.0.0:$FRAPPE_PORT \
--worker-tmp-dir /dev/shm \
--threads=4 \
--workers $WORKERS \
--worker-class=gthread \
--log-file=- \
-t 120 frappe.app:application --preload"
else
. /home/frappe/frappe-bench/env/bin/activate
gunicorn -b 0.0.0.0:$FRAPPE_PORT \
--worker-tmp-dir /dev/shm \
--threads=4 \
--workers $WORKERS \
--worker-class=gthread \
--log-file=- \
-t 120 frappe.app:application --preload
fi
elif [ "$1" = 'worker' ]; then
checkConfigExists
checkConnection
# default WORKER_TYPE=default
if [[ -z "$RUN_AS_ROOT" ]]; then
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& python /home/frappe/frappe-bench/commands/worker.py"
else
. /home/frappe/frappe-bench/env/bin/activate
python /home/frappe/frappe-bench/commands/worker.py
fi
elif [ "$1" = 'schedule' ]; then
checkConfigExists
checkConnection
if [[ -z "$RUN_AS_ROOT" ]]; then
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& python /home/frappe/frappe-bench/commands/background.py"
else
. /home/frappe/frappe-bench/env/bin/activate
python /home/frappe/frappe-bench/commands/background.py
fi
elif [ "$1" = 'new' ]; then
if [[ -z "$RUN_AS_ROOT" ]]; then
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& python /home/frappe/frappe-bench/commands/new.py"
exit
else
. /home/frappe/frappe-bench/env/bin/activate
python /home/frappe/frappe-bench/commands/new.py
fi
elif [ "$1" = 'migrate' ]; then
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& python /home/frappe/frappe-bench/commands/migrate.py"
exit
elif [ "$1" = 'doctor' ]; then
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& python /home/frappe/frappe-bench/commands/doctor.py"
exit
elif [ "$1" = 'backup' ]; then
if [[ -z "$RUN_AS_ROOT" ]]; then
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& python /home/frappe/frappe-bench/commands/backup.py"
exit
else
. /home/frappe/frappe-bench/env/bin/activate
python /home/frappe/frappe-bench/commands/backup.py
fi
elif [ "$1" = 'console' ]; then
if [[ -z "$2" ]]; then
echo "Need to specify a sitename with the command:"
echo "console <sitename>"
exit 1
fi
if [[ -z "$RUN_AS_ROOT" ]]; then
su frappe -c ". /home/frappe/frappe-bench/env/bin/activate \
&& python /home/frappe/frappe-bench/commands/console.py $2"
exit
else
. /home/frappe/frappe-bench/env/bin/activate
python /home/frappe/frappe-bench/commands/console.py "$2"
fi
else
exec su frappe -c "$@"
fi

View File

@ -0,0 +1,40 @@
FROM bitnami/node:12-prod
WORKDIR /home/frappe/frappe-bench
RUN mkdir -p /home/frappe/frappe-bench/sites \
&& echo "frappe\nerpnext" > /home/frappe/frappe-bench/sites/apps.txt
RUN install_packages git python2
RUN mkdir -p apps sites/assets \
&& cd apps \
&& git clone --depth 1 https://github.com/frappe/frappe \
&& git clone --depth 1 https://github.com/frappe/erpnext
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& yarn \
&& yarn run production \
&& rm -fr node_modules \
&& yarn install --production=true
RUN git clone --depth 1 https://github.com/frappe/bench /tmp/bench \
&& mkdir -p /var/www/error_pages \
&& cp -r /tmp/bench/bench/config/templates/502.html /var/www/error_pages
RUN cp -R /home/frappe/frappe-bench/apps/frappe/frappe/public/* /home/frappe/frappe-bench/sites/assets/frappe \
&& cp -R /home/frappe/frappe-bench/apps/frappe/node_modules /home/frappe/frappe-bench/sites/assets/frappe/ \
&& mkdir -p /home/frappe/frappe-bench/sites/assets/erpnext \
&& cp -R /home/frappe/frappe-bench/apps/erpnext/erpnext/public/* /home/frappe/frappe-bench/sites/assets/erpnext
FROM nginx:latest
COPY --from=0 /home/frappe/frappe-bench/sites /var/www/html/
COPY --from=0 /var/www/error_pages /var/www/
COPY build/common/nginx-default.conf.template /etc/nginx/conf.d/default.conf.template
COPY build/erpnext-assets/docker-entrypoint.sh /
RUN apt-get update && apt-get install -y rsync && apt-get clean
VOLUME [ "/assets" ]
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,40 @@
#!/bin/bash
## Thanks
# https://serverfault.com/a/919212
##
set -e
rsync -a --delete /var/www/html/assets/js /assets
rsync -a --delete /var/www/html/assets/css /assets
rsync -a --delete /var/www/html/assets/frappe /assets
rsync -a --delete /var/www/html/assets/erpnext /assets
chmod -R 755 /assets
if [[ -z "$FRAPPE_PY" ]]; then
export FRAPPE_PY=0.0.0.0
fi
if [[ -z "$FRAPPE_PY_PORT" ]]; then
export FRAPPE_PY_PORT=8000
fi
if [[ -z "$FRAPPE_SOCKETIO" ]]; then
export FRAPPE_SOCKETIO=0.0.0.0
fi
if [[ -z "$SOCKETIO_PORT" ]]; then
export SOCKETIO_PORT=9000
fi
envsubst '${API_HOST}
${API_PORT}
${FRAPPE_PY}
${FRAPPE_PY_PORT}
${FRAPPE_SOCKETIO}
${SOCKETIO_PORT}' \
< /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
exec "$@"

View File

@ -0,0 +1,40 @@
FROM bitnami/node:10-prod
WORKDIR /home/frappe/frappe-bench
RUN mkdir -p /home/frappe/frappe-bench/sites \
&& echo "frappe\nerpnext" > /home/frappe/frappe-bench/sites/apps.txt
RUN install_packages git python2
RUN mkdir -p apps sites/assets \
&& cd apps \
&& git clone --depth 1 https://github.com/frappe/frappe --branch version-11 \
&& git clone --depth 1 https://github.com/frappe/erpnext --branch version-11
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& yarn \
&& yarn run production \
&& rm -fr node_modules \
&& yarn install --production=true
RUN git clone --depth 1 https://github.com/frappe/bench /tmp/bench \
&& mkdir -p /var/www/error_pages \
&& cp -r /tmp/bench/bench/config/templates/502.html /var/www/error_pages
RUN cp -R /home/frappe/frappe-bench/apps/frappe/frappe/public/* /home/frappe/frappe-bench/sites/assets/frappe \
&& cp -R /home/frappe/frappe-bench/apps/frappe/node_modules /home/frappe/frappe-bench/sites/assets/frappe/ \
&& mkdir -p /home/frappe/frappe-bench/sites/assets/erpnext \
&& cp -R /home/frappe/frappe-bench/apps/erpnext/erpnext/public/* /home/frappe/frappe-bench/sites/assets/erpnext
FROM nginx:latest
COPY --from=0 /home/frappe/frappe-bench/sites /var/www/html/
COPY --from=0 /var/www/error_pages /var/www/
COPY build/common/nginx-default.conf.template /etc/nginx/conf.d/default.conf.template
COPY build/erpnext-assets/docker-entrypoint.sh /
RUN apt-get update && apt-get install -y rsync && apt-get clean
VOLUME [ "/assets" ]
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,40 @@
FROM bitnami/node:12-prod
WORKDIR /home/frappe/frappe-bench
RUN mkdir -p /home/frappe/frappe-bench/sites \
&& echo "frappe\nerpnext" > /home/frappe/frappe-bench/sites/apps.txt
RUN install_packages git python2
RUN mkdir -p apps sites/assets \
&& cd apps \
&& git clone --depth 1 https://github.com/frappe/frappe --branch version-12 \
&& git clone --depth 1 https://github.com/frappe/erpnext --branch version-12
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& yarn \
&& yarn run production \
&& rm -fr node_modules \
&& yarn install --production=true
RUN git clone --depth 1 https://github.com/frappe/bench /tmp/bench \
&& mkdir -p /var/www/error_pages \
&& cp -r /tmp/bench/bench/config/templates/502.html /var/www/error_pages
RUN cp -R /home/frappe/frappe-bench/apps/frappe/frappe/public/* /home/frappe/frappe-bench/sites/assets/frappe \
&& cp -R /home/frappe/frappe-bench/apps/frappe/node_modules /home/frappe/frappe-bench/sites/assets/frappe/ \
&& mkdir -p /home/frappe/frappe-bench/sites/assets/erpnext \
&& cp -R /home/frappe/frappe-bench/apps/erpnext/erpnext/public/* /home/frappe/frappe-bench/sites/assets/erpnext
FROM nginx:latest
COPY --from=0 /home/frappe/frappe-bench/sites /var/www/html/
COPY --from=0 /var/www/error_pages /var/www/
COPY build/erpnext-assets/nginx-default.conf.template /etc/nginx/conf.d/default.conf.template
COPY build/common/docker-entrypoint.sh /
RUN apt-get update && apt-get install -y rsync && apt-get clean
VOLUME [ "/assets" ]
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,44 @@
FROM bitnami/python:latest-prod
RUN useradd -ms /bin/bash frappe
WORKDIR /home/frappe/frappe-bench
RUN install_packages \
git \
wkhtmltopdf \
mariadb-client \
gettext-base \
wget \
# for PDF
libssl-dev \
fonts-cantarell \
xfonts-75dpi \
xfonts-base \
# For psycopg2
libpq-dev \
build-essential
# Install wkhtmltox correctly
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN dpkg -i wkhtmltox_0.12.5-1.stretch_amd64.deb && rm wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN mkdir -p apps logs commands
RUN virtualenv env \
&& . env/bin/activate \
&& cd apps \
&& git clone --depth 1 -o upstream https://github.com/frappe/frappe \
&& git clone --depth 1 -o upstream https://github.com/frappe/erpnext \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/erpnext
COPY build/common/commands/* /home/frappe/frappe-bench/commands/
COPY build/common/common_site_config.json.template /opt/frappe/common_site_config.json.template
# Setup docker-entrypoint
COPY build/common/worker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,41 @@
FROM bitnami/python:latest-prod
RUN useradd -ms /bin/bash frappe
WORKDIR /home/frappe/frappe-bench
RUN install_packages \
git \
wkhtmltopdf \
mariadb-client \
gettext-base \
wget \
# for PDF
libssl-dev \
fonts-cantarell \
xfonts-75dpi \
xfonts-base
# Install wkhtmltox correctly
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN dpkg -i wkhtmltox_0.12.5-1.stretch_amd64.deb && rm wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN mkdir -p apps logs commands
RUN virtualenv env \
&& . env/bin/activate \
&& cd apps \
&& git clone --depth 1 -o upstream https://github.com/frappe/frappe --branch version-11 \
&& git clone --depth 1 -o upstream https://github.com/frappe/erpnext --branch version-11 \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/erpnext
COPY build/common/commands/* /home/frappe/frappe-bench/commands/
COPY build/common/common_site_config.json.template /opt/frappe/common_site_config.json.template
# Setup docker-entrypoint
COPY build/common/worker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,44 @@
FROM bitnami/python:latest-prod
RUN useradd -ms /bin/bash frappe
WORKDIR /home/frappe/frappe-bench
RUN install_packages \
git \
wkhtmltopdf \
mariadb-client \
gettext-base \
wget \
# for PDF
libssl-dev \
fonts-cantarell \
xfonts-75dpi \
xfonts-base \
# For psycopg2
libpq-dev \
build-essential
# Install wkhtmltox correctly
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN dpkg -i wkhtmltox_0.12.5-1.stretch_amd64.deb && rm wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN mkdir -p apps logs commands
RUN virtualenv env \
&& . env/bin/activate \
&& cd apps \
&& git clone --depth 1 -o upstream https://github.com/frappe/frappe --branch version-12 \
&& git clone --depth 1 -o upstream https://github.com/frappe/erpnext --branch version-12 \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/erpnext
COPY build/common/commands/* /home/frappe/frappe-bench/commands/
COPY build/common/common_site_config.json.template /opt/frappe/common_site_config.json.template
# Setup docker-entrypoint
COPY build/common/worker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,37 @@
FROM bitnami/node:12-prod
WORKDIR /home/frappe/frappe-bench
RUN mkdir -p /home/frappe/frappe-bench/sites \
&& echo "frappe" > /home/frappe/frappe-bench/sites/apps.txt
RUN install_packages git
RUN mkdir -p apps sites/assets \
&& cd apps \
&& git clone --depth 1 https://github.com/frappe/frappe
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& yarn \
&& yarn run production \
&& rm -fr node_modules \
&& yarn install --production=true
RUN git clone --depth 1 https://github.com/frappe/bench /tmp/bench \
&& mkdir -p /var/www/error_pages \
&& cp -r /tmp/bench/bench/config/templates /var/www/error_pages
RUN cp -R /home/frappe/frappe-bench/apps/frappe/frappe/public/* /home/frappe/frappe-bench/sites/assets/frappe \
&& cp -R /home/frappe/frappe-bench/apps/frappe/node_modules /home/frappe/frappe-bench/sites/assets/frappe/
FROM nginx:latest
COPY --from=0 /home/frappe/frappe-bench/sites /var/www/html/
COPY --from=0 /var/www/error_pages /var/www/
COPY build/common/nginx-default.conf.template /etc/nginx/conf.d/default.conf.template
COPY build/frappe-assets/docker-entrypoint.sh /
RUN apt-get update && apt-get install -y rsync && apt-get clean
VOLUME [ "/assets" ]
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,39 @@
#!/bin/bash
## Thanks
# https://serverfault.com/a/919212
##
set -e
rsync -a --delete /var/www/html/assets/js /assets
rsync -a --delete /var/www/html/assets/css /assets
rsync -a --delete /var/www/html/assets/frappe /assets
chmod -R 755 /assets
if [[ -z "$FRAPPE_PY" ]]; then
export FRAPPE_PY=0.0.0.0
fi
if [[ -z "$FRAPPE_PY_PORT" ]]; then
export FRAPPE_PY_PORT=8000
fi
if [[ -z "$FRAPPE_SOCKETIO" ]]; then
export FRAPPE_SOCKETIO=0.0.0.0
fi
if [[ -z "$SOCKETIO_PORT" ]]; then
export SOCKETIO_PORT=9000
fi
envsubst '${API_HOST}
${API_PORT}
${FRAPPE_PY}
${FRAPPE_PY_PORT}
${FRAPPE_SOCKETIO}
${SOCKETIO_PORT}' \
< /etc/nginx/conf.d/default.conf.template > /etc/nginx/conf.d/default.conf
exec "$@"

View File

@ -0,0 +1,37 @@
FROM bitnami/node:10-prod
WORKDIR /home/frappe/frappe-bench
RUN mkdir -p /home/frappe/frappe-bench/sites \
&& echo "frappe" > /home/frappe/frappe-bench/sites/apps.txt
RUN install_packages git
RUN mkdir -p apps sites/assets \
&& cd apps \
&& git clone --depth 1 https://github.com/frappe/frappe --branch version-11
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& yarn \
&& yarn run production \
&& rm -fr node_modules \
&& yarn install --production=true
RUN git clone --depth 1 https://github.com/frappe/bench /tmp/bench \
&& mkdir -p /var/www/error_pages \
&& cp -r /tmp/bench/bench/config/templates /var/www/error_pages
RUN cp -R /home/frappe/frappe-bench/apps/frappe/frappe/public/* /home/frappe/frappe-bench/sites/assets/frappe \
&& cp -R /home/frappe/frappe-bench/apps/frappe/node_modules /home/frappe/frappe-bench/sites/assets/frappe/
FROM nginx:latest
COPY --from=0 /home/frappe/frappe-bench/sites /var/www/html/
COPY --from=0 /var/www/error_pages /var/www/
COPY build/common/nginx-default.conf.template /etc/nginx/conf.d/default.conf.template
COPY build/frappe-assets/docker-entrypoint.sh /
RUN apt-get update && apt-get install -y rsync && apt-get clean
VOLUME [ "/assets" ]
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,37 @@
FROM bitnami/node:12-prod
WORKDIR /home/frappe/frappe-bench
RUN mkdir -p /home/frappe/frappe-bench/sites \
&& echo "frappe" > /home/frappe/frappe-bench/sites/apps.txt
RUN install_packages git
RUN mkdir -p apps sites/assets \
&& cd apps \
&& git clone --depth 1 https://github.com/frappe/frappe --branch version-12
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& yarn \
&& yarn run production \
&& rm -fr node_modules \
&& yarn install --production=true
RUN git clone --depth 1 https://github.com/frappe/bench /tmp/bench \
&& mkdir -p /var/www/error_pages \
&& cp -r /tmp/bench/bench/config/templates /var/www/error_pages
RUN cp -R /home/frappe/frappe-bench/apps/frappe/frappe/public/* /home/frappe/frappe-bench/sites/assets/frappe \
&& cp -R /home/frappe/frappe-bench/apps/frappe/node_modules /home/frappe/frappe-bench/sites/assets/frappe/
FROM nginx:latest
COPY --from=0 /home/frappe/frappe-bench/sites /var/www/html/
COPY --from=0 /var/www/error_pages /var/www/
COPY build/common/nginx-default.conf.template /etc/nginx/conf.d/default.conf.template
COPY build/frappe-assets/docker-entrypoint.sh /
RUN apt-get update && apt-get install -y rsync && apt-get clean
VOLUME [ "/assets" ]
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"]

View File

@ -0,0 +1,34 @@
FROM node:slim
# Install needed packages
RUN apt-get update && apt-get install -y curl && apt-get clean
RUN useradd -ms /bin/bash frappe
# Make bench directories
RUN mkdir -p /home/frappe/frappe-bench/sites /home/frappe/frappe-bench/apps/frappe
COPY build/frappe-socketio/package.json /home/frappe/frappe-bench/apps/frappe
# get socketio
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& curl https://raw.githubusercontent.com/frappe/frappe/develop/socketio.js \
--output /home/frappe/frappe-bench/apps/frappe/socketio.js \
&& curl https://raw.githubusercontent.com/frappe/frappe/develop/node_utils.js \
--output /home/frappe/frappe-bench/apps/frappe/node_utils.js
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& npm install --only=production
COPY build/frappe-socketio/health.js /home/frappe/frappe-bench/apps/frappe/health.js
RUN chown -R frappe:frappe /home/frappe
# Setup docker-entrypoint
COPY build/frappe-socketio/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,29 @@
#!/bin/bash
function checkConfigExists() {
COUNTER=0
while [[ ! -e /home/frappe/frappe-bench/sites/common_site_config.json ]] && [[ $COUNTER -le 30 ]] ; do
sleep 1
let COUNTER=COUNTER+1
echo "config file not created, retry $COUNTER"
done
if [[ ! -e /home/frappe/frappe-bench/sites/common_site_config.json ]]; then
echo "timeout: config file not created"
exit 1
fi
}
if [ "$1" = 'start' ]; then
checkConfigExists
su frappe -c "node /home/frappe/frappe-bench/apps/frappe/socketio.js"
elif [ "$1" = 'doctor' ]; then
su frappe -c "node /home/frappe/frappe-bench/apps/frappe/health.js"
else
exec su frappe -c "$@"
fi

View File

@ -0,0 +1,19 @@
var net = require('net');
var { get_conf } = require('./node_utils');
var conf = get_conf();
var server = ['localhost', conf.socketio_port || 9000];
var sock = new net.Socket();
sock.setTimeout(2500);
sock.on('connect', function() {
console.info(server[0]+':'+server[1]+' is up.');
sock.destroy();
process.exit();
}).on('error', function(e) {
console.error(server[0]+':'+server[1]+' is down: ' + e.message);
process.exit(1);
}).on('timeout', function(e) {
console.error(server[0]+':'+server[1]+' is down: timeout');
process.exit(1);
}).connect(server[1], server[0]);

View File

@ -0,0 +1,17 @@
{
"name": "frappe-socketio",
"version": "1.0.0",
"description": "Frappe SocketIO Server",
"main": "socketio.js",
"scripts": {
"start": "node socketio.js"
},
"author": "Revant Nandgaonkar",
"license": "MIT",
"dependencies": {
"express": "^4.17.1",
"redis": "^2.8.0",
"socket.io": "^2.3.0",
"superagent": "^5.1.0"
}
}

View File

@ -0,0 +1,34 @@
FROM node:slim
# Install needed packages
RUN apt-get update && apt-get install -y curl && apt-get clean
RUN useradd -ms /bin/bash frappe
# Make bench directories
RUN mkdir -p /home/frappe/frappe-bench/sites /home/frappe/frappe-bench/apps/frappe
COPY build/frappe-socketio/package.json /home/frappe/frappe-bench/apps/frappe
# get socketio
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& curl https://raw.githubusercontent.com/frappe/frappe/version-11/socketio.js \
--output /home/frappe/frappe-bench/apps/frappe/socketio.js \
&& curl https://raw.githubusercontent.com/frappe/frappe/version-11/node_utils.js \
--output /home/frappe/frappe-bench/apps/frappe/node_utils.js
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& npm install --only=production
COPY build/frappe-socketio/health.js /home/frappe/frappe-bench/apps/frappe/health.js
RUN chown -R frappe:frappe /home/frappe
# Setup docker-entrypoint
COPY build/frappe-socketio/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,34 @@
FROM node:slim
# Install needed packages
RUN apt-get update && apt-get install -y curl && apt-get clean
RUN useradd -ms /bin/bash frappe
# Make bench directories
RUN mkdir -p /home/frappe/frappe-bench/sites /home/frappe/frappe-bench/apps/frappe
COPY build/frappe-socketio/package.json /home/frappe/frappe-bench/apps/frappe
# get socketio
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& curl https://raw.githubusercontent.com/frappe/frappe/version-12/socketio.js \
--output /home/frappe/frappe-bench/apps/frappe/socketio.js \
&& curl https://raw.githubusercontent.com/frappe/frappe/version-12/node_utils.js \
--output /home/frappe/frappe-bench/apps/frappe/node_utils.js
RUN cd /home/frappe/frappe-bench/apps/frappe \
&& npm install --only=production
COPY build/frappe-socketio/health.js /home/frappe/frappe-bench/apps/frappe/health.js
RUN chown -R frappe:frappe /home/frappe
# Setup docker-entrypoint
COPY build/frappe-socketio/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,42 @@
FROM bitnami/python:latest-prod
RUN useradd -ms /bin/bash frappe
WORKDIR /home/frappe/frappe-bench
RUN install_packages \
git \
wkhtmltopdf \
mariadb-client \
gettext-base \
wget \
# for PDF
libssl-dev \
fonts-cantarell \
xfonts-75dpi \
xfonts-base \
# For psycopg2
libpq-dev \
build-essential
# Install wkhtmltox correctly
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN dpkg -i wkhtmltox_0.12.5-1.stretch_amd64.deb && rm wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN mkdir -p apps logs commands
RUN virtualenv env \
&& . env/bin/activate \
&& cd apps \
&& git clone --depth 1 -o upstream https://github.com/frappe/frappe \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe
COPY build/common/commands/* /home/frappe/frappe-bench/commands/
COPY build/common/common_site_config.json.template /opt/frappe/common_site_config.json.template
# Setup docker-entrypoint
COPY build/common/worker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,39 @@
FROM bitnami/python:latest-prod
RUN useradd -ms /bin/bash frappe
WORKDIR /home/frappe/frappe-bench
RUN install_packages \
git \
wkhtmltopdf \
mariadb-client \
gettext-base \
wget \
# for PDF
libssl-dev \
fonts-cantarell \
xfonts-75dpi \
xfonts-base
# Install wkhtmltox correctly
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN dpkg -i wkhtmltox_0.12.5-1.stretch_amd64.deb && rm wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN mkdir -p apps logs commands
RUN virtualenv env \
&& . env/bin/activate \
&& cd apps \
&& git clone --depth 1 -o upstream https://github.com/frappe/frappe --branch version-11 \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe
COPY build/common/commands/* /home/frappe/frappe-bench/commands/
COPY build/common/common_site_config.json.template /opt/frappe/common_site_config.json.template
# Setup docker-entrypoint
COPY build/common/worker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,42 @@
FROM bitnami/python:latest-prod
RUN useradd -ms /bin/bash frappe
WORKDIR /home/frappe/frappe-bench
RUN install_packages \
git \
wkhtmltopdf \
mariadb-client \
gettext-base \
wget \
# for PDF
libssl-dev \
fonts-cantarell \
xfonts-75dpi \
xfonts-base \
# For psycopg2
libpq-dev \
build-essential
# Install wkhtmltox correctly
RUN wget https://github.com/wkhtmltopdf/wkhtmltopdf/releases/download/0.12.5/wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN dpkg -i wkhtmltox_0.12.5-1.stretch_amd64.deb && rm wkhtmltox_0.12.5-1.stretch_amd64.deb
RUN mkdir -p apps logs commands
RUN virtualenv env \
&& . env/bin/activate \
&& cd apps \
&& git clone --depth 1 -o upstream https://github.com/frappe/frappe --branch version-12 \
&& pip3 install --no-cache-dir -e /home/frappe/frappe-bench/apps/frappe
COPY build/common/commands/* /home/frappe/frappe-bench/commands/
COPY build/common/common_site_config.json.template /opt/frappe/common_site_config.json.template
# Setup docker-entrypoint
COPY build/common/worker/docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
RUN ln -s /usr/local/bin/docker-entrypoint.sh / # backwards compat
WORKDIR /home/frappe/frappe-bench/sites
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["start"]

View File

@ -0,0 +1,35 @@
version: '3'
services:
redis-cache:
image: redis:latest
restart: on-failure
volumes:
- redis-cache-vol:/data
redis-queue:
image: redis:latest
restart: on-failure
volumes:
- redis-queue-vol:/data
redis-socketio:
image: redis:latest
restart: on-failure
volumes:
- redis-socketio-vol:/data
mariadb:
image: mariadb:10.3
restart: on-failure
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
volumes:
- ./frappe-mariadb.cnf:/etc/mysql/conf.d/frappe.cnf
- mariadb-vol:/var/lib/mysql
volumes:
mariadb-vol:
redis-cache-vol:
redis-queue-vol:
redis-socketio-vol:

View File

@ -0,0 +1,111 @@
version: '3'
services:
erpnext-assets:
image: frappe/erpnext-assets:${VERSION}
restart: on-failure
environment:
- FRAPPE_PY=erpnext-python
- FRAPPE_PY_PORT=8000
- FRAPPE_SOCKETIO=frappe-socketio
- SOCKETIO_PORT=9000
- LETSENCRYPT_HOST=${SITES}
- VIRTUAL_HOST=${SITES}
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
depends_on:
- erpnext-python
- frappe-socketio
- frappe-worker-default
- frappe-worker-long
- frappe-worker-short
links:
- erpnext-python
- frappe-socketio
- frappe-worker-default
- frappe-worker-long
- frappe-worker-short
volumes:
- ./sites:/var/www/html/sites:rw
- assets-vol:/assets:rw
erpnext-python:
image: frappe/erpnext-worker:${VERSION}
restart: on-failure
environment:
- MARIADB_HOST=${MARIADB_HOST}
- REDIS_CACHE=redis-cache:6379
- REDIS_QUEUE=redis-queue:6379
- REDIS_SOCKETIO=redis-socketio:6379
- SOCKETIO_PORT=9000
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
- assets-vol:/home/frappe/frappe-bench/sites/assets:rw
frappe-socketio:
image: frappe/frappe-socketio:${VERSION}
restart: on-failure
depends_on:
- redis-socketio
links:
- redis-socketio
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
frappe-worker-default:
image: frappe/erpnext-worker:${VERSION}
restart: on-failure
command: worker
depends_on:
- redis-queue
- redis-cache
links:
- redis-queue
- redis-cache
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
frappe-worker-short:
image: frappe/erpnext-worker:${VERSION}
restart: on-failure
command: worker
environment:
- WORKER_TYPE=short
depends_on:
- redis-queue
- redis-cache
links:
- redis-queue
- redis-cache
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
frappe-worker-long:
image: frappe/erpnext-worker:${VERSION}
restart: on-failure
command: worker
environment:
- WORKER_TYPE=long
depends_on:
- redis-queue
- redis-cache
links:
- redis-queue
- redis-cache
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
frappe-schedule:
image: frappe/erpnext-worker:${VERSION}
restart: on-failure
command: schedule
depends_on:
- redis-queue
- redis-cache
links:
- redis-queue
- redis-cache
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
volumes:
assets-vol:

View File

@ -0,0 +1,111 @@
version: '3'
services:
frappe-assets:
image: frappe/frappe-assets:${VERSION}
restart: on-failure
environment:
- FRAPPE_PY=frappe-python
- FRAPPE_PY_PORT=8000
- FRAPPE_SOCKETIO=frappe-socketio
- SOCKETIO_PORT=9000
- LETSENCRYPT_HOST=${SITES}
- VIRTUAL_HOST=${SITES}
- LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}
depends_on:
- frappe-python
- frappe-socketio
- frappe-worker-default
- frappe-worker-long
- frappe-worker-short
links:
- frappe-python
- frappe-socketio
- frappe-worker-default
- frappe-worker-long
- frappe-worker-short
volumes:
- ./sites:/var/www/html/sites:rw
- assets-vol:/assets:rw
frappe-python:
image: frappe/frappe-worker:${VERSION}
restart: on-failure
environment:
- MARIADB_HOST=${MARIADB_HOST}
- REDIS_CACHE=redis-cache:6379
- REDIS_QUEUE=redis-queue:6379
- REDIS_SOCKETIO=redis-socketio:6379
- SOCKETIO_PORT=9000
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
- assets-vol:/home/frappe/frappe-bench/sites/assets:rw
frappe-socketio:
image: frappe/frappe-socketio:${VERSION}
restart: on-failure
depends_on:
- redis-socketio
links:
- redis-socketio
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
frappe-worker-default:
image: frappe/frappe-worker:${VERSION}
restart: on-failure
command: worker
depends_on:
- redis-queue
- redis-cache
links:
- redis-queue
- redis-cache
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
frappe-worker-short:
image: frappe/frappe-worker:${VERSION}
restart: on-failure
command: worker
environment:
- WORKER_TYPE=short
depends_on:
- redis-queue
- redis-cache
links:
- redis-queue
- redis-cache
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
frappe-worker-long:
image: frappe/frappe-worker:${VERSION}
restart: on-failure
command: worker
environment:
- WORKER_TYPE=long
depends_on:
- redis-queue
- redis-cache
links:
- redis-queue
- redis-cache
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
frappe-schedule:
image: frappe/frappe-worker:${VERSION}
restart: on-failure
command: schedule
depends_on:
- redis-queue
- redis-cache
links:
- redis-queue
- redis-cache
volumes:
- ./sites:/home/frappe/frappe-bench/sites:rw
volumes:
assets-vol:

View File

@ -0,0 +1,6 @@
version: '3'
networks:
default:
external:
name: webproxy

5
installation/env-example Normal file
View File

@ -0,0 +1,5 @@
VERSION=edge
MARIADB_HOST=mariadb
MYSQL_ROOT_PASSWORD=admin
SITES=your.domain.com
LETSENCRYPT_EMAIL=your.email@your.domain.com

View File

@ -0,0 +1,7 @@
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
[mysql]
default-character-set = utf8mb4