Git Product home page Git Product logo

erpnext-docker-debian's Introduction

🐳 ERPNext on Docker

push-docker

This repository prioritizes stability, repeatability and simplicity, and is not designed as the ideal approach for a production environment.

Problem

  • ERPNext development progresses rapidly, with new updates released daily. Some of these updates may contain bugs.

  • ERPNext depends on numerous external components. During installation, these dependencies can sometimes cause issues, and without a pre-built image, it might be impossible to build or use older versions.

Solution

By using Docker, we can pre-build images and push them to Docker hub. This ensures that usable images are always available, and you can select the version that best suits your needs.

Usage

Trial Setup

This setup is designed for users who want to explore the system and is not suitable for production use.

docker pull pipech/erpnext-docker-debian:version-15-latest

docker run -d -p 8000:8000 -p 9000:9000 -p 3306:3306 pipech/erpnext-docker-debian:version-15-latest

The site should be available at http://localhost:8000 after 1-2 minutes.

Development Setup

This is a self-contained development setup. Developers can fully isolate their environment. The setup utilizes Visual Studio Code and its Dev Containers feature.

  1. Open Visual Studio Code.
  2. Open the Command Palette (View > Command Palette or Ctrl + Shift + P).
  3. Type: Open Folder in Container.
  4. Select the setup_development folder.

For every startup, run:

sudo service mariadb start
bench start

Production Setup

For best practices in a production environment, Official Frappe Docker.

User & Password

ERPNext | U: administrator    P: 12345
MariaDB | U: root             P: 12345

Build Process

For detailed information on the build process, please review the Dockerfile and .github/workflows/push-docker.yml.

In summary:

  • Starts with the frappe/bench image as the base.
  • Integrates all necessary production dependencies like MariaDB, Redis, etc.
  • Sets up new sites and verifies their functionality by checking for a response code of 200.
  • Upon successful verification, tags and pushes the images to Docker hub.

Images will be automatically generated every Sunday at 00:00.

Tag version semantic

15-F1.0_E2.0 represents:

  • Frappe version 15.1.0
  • ERPNext version 15.2.0

Contributing

We welcome pull requests for new features, bug fixes, enhancements to documentation (including typo corrections), and suggestions. Your contributions help improve the project!

License

This project is licensed under the MIT License.

erpnext-docker-debian's People

Contributors

dawoodjee avatar dependabot[bot] avatar dulhaver avatar hafeez3000 avatar jannikbecher avatar pipech avatar poommie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

erpnext-docker-debian's Issues

404 Not found

Hi,

I've tried two time to follow the production guide for Debian w/ Docker (superb guide btw) and it always returns a 404 on my host...

I'm trying it without ssl for the moment (because of ACME rate limit), I don't know if erpnext is not compatible with http?

I do use Traefik & Docker for my project, I don't understand what doesn't work.
Many thanks

conf/traefik-conf/traefik.toml

[entryPoints]
    [entryPoints.http]
    address = ":80"
#        [entryPoints.http.redirect]
#        entryPoint = "https"
#    [entryPoints.https]
#    address = ":443"
#        [entryPoints.https.tls]

#[acme]
#email = "[email protected]"
#storage = "/etc/traefik/acme/acme.json"
#entryPoint = "https"
#onHostRule = true
#    [acme.httpChallenge]
#    entryPoint = "http"

frappe.yml

image: pipech/erpnext-docker-debian:mas-py3-latest

- "traefik.frontend.rule=Host:erp.clinique-design.com"

env/frappe_app.env

benchNewSiteName=erp.clinique-design.com
NGINX_SERVER_NAME=erp.clinique-design.com

Production setup: SSL Cert issue

Wanted to thank you for your hard work on this repo :)

I'm currently facing an issue with production. The stack is running but HTTPS doesn't seem to be working correctly.
erp ssl

ID                  NAME                                  MODE                REPLICAS            IMAGE                                      PORTS
yqqavf9o8z7w        erpnext_db_stack_mariadb              replicated          1/1                 mariadb:10.3.9                             *:3307->3306/tcp
vms3zem1c9gp        erpnext_frappe_stack_frappe           replicated          1/1                 pipech/erpnext-docker-debian:11.1.39-py3
k9smk5pur2km        erpnext_frappe_stack_redis-cache      replicated          1/1                 redis:alpine
5g0kj93fp51x        erpnext_frappe_stack_redis-queue      replicated          1/1                 redis:alpine
vzw3kma5gfyh        erpnext_frappe_stack_redis-socketio   replicated          1/1                 redis:alpine
vljlt3o0b8d4        erpnext_proxy_stack_traefik           replicated          1/1                 traefik:latest                             *:80->80/tcp, *:443->443/tcp
lk6xizeuclqq        frappe_monitor_cadvisor               replicated          1/1                 google/cadvisor:v0.28.5
odbj8s9xyok4        frappe_monitor_grafana                replicated          1/1                 grafana/grafana:latest
v6meb5vkgxvn        frappe_monitor_prometheus             replicated          1/1                 prom/prometheus:latest

The same goes for grafana when launched.

Production Setup: DB access denied

Hi,

I followed the production setup guide and when executing . init.sh in the frappe container I get a python error with the last line being

pymysql.err.OperationalError: (1045, "Access denied for user 'root'@'10.0.1.16' (using password: YES)")

and I'm immediately kicked out of the container.

I hope it's not a mere noob issue. Tried to but couldn't find anything related in the closed issues.

Appreciate your help!

Warning : RequestsDependencyWarning: urllib3 (1.23) or chardet (3.0.4) doesn't match a supported version!

Got this warning when run something involve with bench command.
i.e.

Command >

  • bench new-app custom-app
  • bench update --patch

Error >

/home/frappe/bench/env/local/lib/python2.7/site-packages/requests/__init__.py:80: RequestsDependencyWarning: urllib3 (1.23) or chardet (3.0.4) doesn't match a supported version!
  RequestsDependencyWarning)

Command will still run with success.
There're no error cause by this warning, that I know of, of now.

Reference >

Known-Bug for Version >

  • v10.1.37

Use another port besides 80

Sorry, I don't see a conversation/discussion tab, how do I change the port? I tried editing the config.v2.json of the nginx container, but it gets recreated. I'm using stable.

OSError: [Errno 2] No such file or directory make_asset_dirs, os.symlink(source, target)

frappe@609ffc91c9aa:~/bench$ bench update --build                                                                                                 
Traceback (most recent call last):                                                                                                                
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main                                                                            
	"__main__", fname, loader, pkg_name)                                                                                                          
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code                                                                                       
	exec code in run_globals                                                                                                                      
  File "/home/frappe/bench/apps/frappe/frappe/utils/bench_helper.py", line 94, in <module>                                                        
	main()                                                                                                                                        
  File "/home/frappe/bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main                                                            
	click.Group(commands=commands)(prog_name='bench')                                                                                             
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 722, in __call__                                            
	return self.main(*args, **kwargs)                                                                                                             
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 697, in main                                                
	rv = self.invoke(ctx)                                                                                                                         
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke                                             
	return _process_result(sub_ctx.command.invoke(sub_ctx))                                                                                       
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke                                             
	return _process_result(sub_ctx.command.invoke(sub_ctx))                                                                                       
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 895, in invoke                                              
	return ctx.invoke(self.callback, **ctx.params)                                                                                                
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 535, in invoke                                              
	return callback(*args, **kwargs)                                                                                                              
  File "/home/frappe/bench/apps/frappe/frappe/commands/utils.py", line 20, in build                                                               
	frappe.build.bundle(no_compress, make_copy=make_copy, restore = restore, verbose=verbose)                                                     
  File "/home/frappe/bench/apps/frappe/frappe/build.py", line 34, in bundle                                                                       
	make_asset_dirs(make_copy=make_copy, restore=restore)                                                                                         
  File "/home/frappe/bench/apps/frappe/frappe/build.py", line 104, in make_asset_dirs                                                             
	os.symlink(source, target)                                                                                                                    
OSError: [Errno 2] No such file or directory                                                                                                      

Workaround, Check ./sites/assets

frappe@609ffc91c9aa:~/bench/sites/assets$ ls -al
total 32
drwxr-xr-x 2 root root 4096 Jun 18 17:16 .
drwxr-xr-x 2 root root 4096 Jun 18 03:13 ..
drwxr-xr-x 2 root root    0 May 30 16:41 css
lrwxrwxrwx 1 root root   46 Jun 18 17:16 erpnext -> /home/frappe/bench/apps/erpnext/erpnext/public
lrwxrwxrwx 1 root root   44 Jun 18 17:16 erpnext_docs -> /home/frappe/bench/apps/erpnext/erpnext/docs
lrwxrwxrwx 1 root root   44 Jun 18 17:16 frappe -> /home/frappe/bench/apps/frappe/frappe/public
lrwxrwxrwx 1 root root   42 Jun 18 17:16 frappe_docs -> /home/frappe/bench/apps/frappe/frappe/docs
drwxr-xr-x 2 root root    0 May 30 16:41 js

There should have all of above, if you get

frappe@609ffc91c9aa:~/bench/sites/assets$ ls -la
ls: cannot access 'frappe': No such file or directory
total 24
drwxr-xr-x 2 root root 4096 Jun 16 09:24 .
drwxr-xr-x 2 root root 4096 Jun 18 03:13 ..
drwxr-xr-x 2 root root    0 May 30 16:41 css
lrwxrwxrwx 1 root root   46 Jun 16 09:24 erpnext -> /home/frappe/bench/apps/erpnext/erpnext/public
lrwxrwxrwx 1 root root   44 Jun 16 09:24 erpnext_docs -> /home/frappe/bench/apps/erpnext/erpnext/docs
-????????? ? ?    ?       ?            ? frappe
lrwxrwxrwx 1 root root   42 Jun 16 09:24 frappe_docs -> /home/frappe/bench/apps/frappe/frappe/docs
drwxr-xr-x 2 root root    0 May 30 16:41 js

Try restart docker, after that
-????????? ? ? ? ? ? frappe this line should be gone
Then ran ln -s /home/frappe/bench/apps/frappe/frappe/public frappe

Installation Questions

Hi @pipech

How do I start a new setup? I tried stopping the containers using docker stop $(docker ps -a -q) but it appears they got restarted automatically

Thanks

Development Setup: DB access denied

Didn't change anything, just followed this tutorial steps and got
pymysql.err.OperationalError: (1045, "Access denied for user '1bd3e0294da19198'@'172.18.0.3' (using password: YES)")

Related to this issue, but no indication on how to solve it.
Tried to add anonymous user to DB in a DB docker suing https://github.com/pipech/erpnext-docker-debian/issues/47 but I'd be surprised if it worked as I can't see erpnext database in the list.

FYI: running docker on Windows 10, but that shouldn't have an impact here.

Issue with setup wizard - step5

I am using this image - pipech/erpnext-docker-debian:12.x.x-191015-py3
I am unable to proceed beyond step5. Any idea what could be wrong. I had chosen country to be South Africa. Thanks
image

Build Error: "gpg: cannot open '/dev/tty': No such device or address"

Build:
2018-11-16T00:27:38.530Z

[DEPRECATION WARNING]: Using tests as filters is deprecated. Instead of using
`result|version_compare` use `result is version_compare`. This feature will be
removed in version 2.9. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.

fatal: [localhost]: FAILED! => {
"changed": false,
"cmd": "/usr/bin/apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv F1656F24C74CD1D8",
"msg": "Error fetching key F1656F24C74CD1D8 from keyserver: hkp://keyserver.ubuntu.com:80",
"rc": 2,
"stderr": "Warning: apt-key output should not be parsed (stdout is not a terminal)\ngpg: cannot open '/dev/tty': No such device or address\n", 
"stderr_lines": [
"Warning: apt-key output should not be parsed (stdout is not a terminal)",
"gpg: cannot open '/dev/tty': No such device or address"
],
"stdout": "Executing: /tmp/apt-key-gpghome.i9UZx8v8na/gpg.1.sh --keyserver hkp://keyserver.ubuntu.com:80 --recv F1656F24C74CD1D8\n",
"stdout_lines": ["Executing: /tmp/apt-key-gpghome.i9UZx8v8na/gpg.1.sh --keyserver hkp://keyserver.ubuntu.com:80 --recv F1656F24C74CD1D8"]}
        to retry, use: --limit @/home/frappe/bench/playbooks/site.retry

PLAY RECAP *********************************************************************
localhost                  : ok=8    changed=4    unreachable=0    failed=1

VS code remote Development set fails

For some reason, development setup in VS code remote fails with following :
image

Step 8/8 : ENV DEV_SERVER=1 ---> Running in 63a8a4d13fe7 Removing intermediate container 63a8a4d13fe7 ---> 0ab4aab426da Successfully built 0ab4aab426da Successfully tagged devcontainer_frappe:latest WARNING: Image for service frappe was built because it did not already exist. To rebuild this image you must use docker-compose buildordocker-compose up --build. Creating devcontainer_frappe_1 ... done Attaching to devcontainer_frappe_1 frappe_1 | standard_init_linux.go:211: exec user process caused "no such file or directory" devcontainer_frappe_1 exited with code 1

I am using this image:
docker pull pipech/erpnext-docker-debian:mas-py3-latest

I verified that entrypoint.sh has EOL as LF.

development_setup - why so many ports?

just for my understanding:

ports:
 - "8000-8005:8000-8005" #webserver_port
 - "9000-9005:9000-9005" #socketio_port

why do you provide so many ports (6 for the webserver, 6 for socketio) and not just 1 (8000:8000, 9000:9000)?

On my first 2 instances (v11.1.9-py3, 10.1.81-py2) only the 8000 port serves the ERPNExt website anyway

REDIS error with Dev setup?

Using your instructions for Dev mode -- during the . init.sh step, I get this error. Any ideas?

version: '2'

services:
  frappe:
	image: pipech/erpnext-docker-debian:mas-py3-latest
	ports:
	  - "8000-8005:8000-8005" #webserver_port
	  - "9000-9005:9000-9005" #socketio_port
	  - "6787:6787" #file_watcher_port
	volumes:
	  # persisting data
	  - ./data/bench/apps:/home/frappe/bench/apps
	  # config
	  - ./conf/frappe-docker-conf/init.sh:/home/frappe/bench/init.sh
	  - ./conf/frappe-docker-conf/init.sql:/home/frappe/bench/init.sql
	stdin_open: true
	tty: true
	command: tail -f /dev/null

  mariadb:
	build: ./image/mariadb/.
	environment:
	  - MYSQL_USER=root
	  - MYSQL_ROOT_PASSWORD=mysql
	volumes:
	  # persisting data
	  - mariadb-data-volumes:/var/lib/mysql
	ports:
	  - "3306:3306"

volumes:
  mariadb-data-volumes:

++ bench update --patch --no-backup
Patching sites...
Migrating dev32.loc
Updating DocTypes for frappe        : [========================================]
Updating DocTypes for erpnext       : [========================================]
Traceback (most recent call last):
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 484, in connect
	sock = self._connect()
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 541, in _connect
	raise err
...skipping...
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 529, in _connect
	sock.connect(socket_address)
OSError: [Errno 99] Cannot assign requested address

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/client.py", line 667, in execute_command
	connection.send_command(*args)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 610, in send_command
	self.send_packed_command(self.pack_command(*args))
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 585, in send_packed_command
	self.connect()
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 489, in connect
	raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 99 connecting to localhost:13000. Cannot assign requested address.

frappe container won't start

Hi,

Am trying out your production deployment but the frappe container doesn't start, it just recreates itself indefinitely.

I ran a container based on pipech/erpnext-docker-debian:mas-py3-latest via "docker run" and executed the entrypoint_prd.sh script to see what's up, here is the output:
`frappe@7e3a43243e9c:~/production_config$ . entrypoint_prd.sh

++ benchWD=/home/frappe
++ cd /home/frappe/production_config
++ sudo cp common_site_config_docker.json /home/frappe/bench/sites/common_site_config.json
++ sudo cp supervisor.conf /etc/supervisor/conf.d/supervisor.conf
++ sudo -E /bin/bash -c 'envsubst '''$NGINX_SERVER_NAME''' < nginx.temp > /etc/nginx/conf.d/default.conf'
/bin/bash: envsubst: command not found`

gettext isn't present in the image, is that the problem or am I missing something?

Dockerhub image doesnt launch on Rancher 2.x

+ sudo service mysql start
sudo: effective uid is not 0, is /usr/bin/sudo on a file system with the 'nosuid' option set or an NFS file system without root privileges?

affects all versions i have tried (multiple), including 11.1.47-py3

[v12] Build error

First occurrence: Build #128 [2019-10-23]
Last success built: v12.0.16 [2019-10-15]

Reading package lists...
Building dependency tree...
Reading state information...
The following packages will be REMOVED:
  guile-2.0-libs* libfribidi0* libgc1c2* libgsasl7* libkyotocabinet16v5*
  libltdl7* liblzo2-2* libmailutils5* libntlm0* libpython2.7* mailutils*
  mailutils-common*
0 upgraded, 0 newly installed, 12 to remove and 12 not upgraded.
After this operation, 23.2 MB disk space will be freed.
(Reading database ... 39596 files and directories currently installed.)
Removing mailutils (1:3.1.1-1) ...
Removing libmailutils5:amd64 (1:3.1.1-1) ...
Removing guile-2.0-libs:amd64 (2.0.13+1-4) ...
Removing libfribidi0:amd64 (0.19.7-1+deb9u1) ...
Removing libgc1c2:amd64 (1:7.4.2-8) ...
Removing libgsasl7 (1.8.0-8+b2) ...
Removing libkyotocabinet16v5:amd64 (1.2.76-4.2+b1) ...
Removing libltdl7:amd64 (2.4.6-2) ...
Removing liblzo2-2:amd64 (2.08-1.2+b2) ...
Removing libntlm0:amd64 (1.4-8) ...
Removing libpython2.7:amd64 (2.7.13-2+deb9u3) ...
Removing mailutils-common (1:3.1.1-1) ...
Processing triggers for libc-bin (2.24-11+deb9u3) ...
Starting MariaDB database server: mysqld already running.
Creating Database...
Installing frappe...
Updating DocTypes for frappe        : [========================================]Traceback (most recent call last):
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 484, in connect
	sock = self._connect()
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 541, in _connect
	raise err
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 529, in _connect
	sock.connect(socket_address)
OSError: [Errno 99] Cannot assign requested address
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/client.py", line 2879, in execute
	return execute(conn, stack, raise_on_error)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/client.py", line 2749, in _execute_transaction
	connection.send_packed_command(all_cmds)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 585, in send_packed_command
	self.connect()
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 489, in connect
	raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 99 connecting to localhost:11000. Cannot assign requested address.
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 484, in connect
	sock = self._connect()
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 541, in _connect
	raise err
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 529, in _connect
	sock.connect(socket_address)
OSError: [Errno 99] Cannot assign requested address
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 193, in _run_module_as_main
	"__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
	exec(code, run_globals)
  File "/home/frappe/bench/apps/frappe/frappe/utils/bench_helper.py", line 97, in <module>
	main()
  File "/home/frappe/bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
	click.Group(commands=commands)(prog_name='bench')
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 764, in __call__
	return self.main(*args, **kwargs)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 717, in main
	rv = self.invoke(ctx)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 1137, in invoke
	return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 1137, in invoke
	return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 956, in invoke
	return ctx.invoke(self.callback, **ctx.params)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 555, in invoke
	return callback(*args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/commands/site.py", line 32, in new_site
	db_type=db_type)
  File "/home/frappe/bench/apps/frappe/frappe/commands/site.py", line 73, in _new_site
	_install_app(app, verbose=verbose, set_as_patched=not source_sql)
  File "/home/frappe/bench/apps/frappe/frappe/installer.py", line 92, in install_app
	frappe.get_attr(after_install)()
  File "/home/frappe/bench/apps/frappe/frappe/utils/install.py", line 19, in after_install
	install_basic_docs()
  File "/home/frappe/bench/apps/frappe/frappe/utils/install.py", line 77, in install_basic_docs
	frappe.get_doc(d).insert()
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 259, in insert
	self.run_post_save_methods()
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 919, in run_post_save_methods
	self.run_method("on_update")
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 787, in run_method
	out = Document.hook(fn)(self, *args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 1058, in composer
	return composed(self, method, *args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 1041, in runner
	add_to_return_value(self, fn(self, *args, **kwargs))
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 781, in <lambda>
	fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/core/doctype/user/user.py", line 93, in on_update
	self.share_with_self()
  File "/home/frappe/bench/apps/frappe/frappe/core/doctype/user/user.py", line 177, in share_with_self
	flags={"ignore_share_permission": True})
  File "/home/frappe/bench/apps/frappe/frappe/share.py", line 44, in add
	notify_assignment(user, doctype, name, everyone)
  File "/home/frappe/bench/apps/frappe/frappe/share.py", line 171, in notify_assignment
	enqueue_create_notification(shared_by, notification_doc)
  File "/home/frappe/bench/apps/frappe/frappe/desk/doctype/notification_log/notification_log.py", line 38, in enqueue_create_notification
	now=frappe.flags.in_test
  File "/home/frappe/bench/apps/frappe/frappe/__init__.py", line 1475, in enqueue
	return frappe.utils.background_jobs.enqueue(*args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/utils/background_jobs.py", line 69, in enqueue
	kwargs=queue_args)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/rq/queue.py", line 258, in enqueue_call
	job = self.enqueue_job(job, at_front=at_front)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/rq/queue.py", line 331, in enqueue_job
	pipe.execute()
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/client.py", line 2894, in execute
	return execute(conn, stack, raise_on_error)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/client.py", line 2749, in _execute_transaction
	connection.send_packed_command(all_cmds)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 585, in send_packed_command
	self.connect()
  File "/home/frappe/bench/env/lib/python3.5/site-packages/redis/connection.py", line 489, in connect
	raise ConnectionError(self._error_message(e))
redis.exceptions.ConnectionError: Error 99 connecting to localhost:11000. Cannot assign requested address.
The command '/bin/sh -c sudo service mysql start     && mysql --user="root" --execute="ALTER USER 'root'@'localhost' IDENTIFIED BY 'travis';"     && git clone $benchRepo /tmp/.bench --depth 1 --branch $benchBranch     && wget $easyinstallRepo     && sed -i '/mariadb/d' /tmp/.bench/playbooks/site.yml     && python install.py     --without-bench-setup     && rm -rf bench     && git clone --branch $benchBranch --depth 1 --origin upstream $benchRepo $benchPath      && sudo pip install -e $benchPath     && bench init $benchFolderName --frappe-path $frappeRepo --frappe-branch $appBranch --python $pythonVersion     && cd $benchFolderName     && bench get-app erpnext $erpnextRepo --branch $appBranch     && bench update --patch     && rm -rf     apps/frappe_io     apps/foundation     && sed -i '/foundation\|frappe_io/d' sites/apps.txt     && sudo rm -rf /tmp/*     && sudo apt-get autoremove --purge -y     && sudo apt-get clean     && sudo service mysql start     && bench new-site $siteName     --mariadb-root-password $mysqlPass      --admin-password $adminPass     && bench --site $siteName install-app erpnext' returned a non-zero code: 1
The command ".travis/build_image.sh" failed and exited with 1 during .

Production setup

During the installation of production setup I met the following challenges:
I am installing to a digital ocean server with an IP address no domain name established yet and am wondering. What should I place here :

  • benchNewSiteName=example1.com
  • NGINX_SERVER_NAME=example1.com

and also here 👍

docker stack deploy -c proxy.yml <proxy_stack_name> docker stack deploy -c db.yml <db_stack_name> docker stack deploy -c frappe.yml <frappe_stack_name>

Whats is to be replaced in between the angle brackets, where do I get those variables.

Trial Setup localhost not Up

Reset the docker "Reset to factory defaults...' in docker setting and tried the easiest one (Trial Setup) with mas-py3-latest. But the http://localhost:8000/ show nothing. Don't know which one is wrong.

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\WINDOWS\system32> docker pull pipech/erpnext-docker-debian:mas-py3-latest
mas-py3-latest: Pulling from pipech/erpnext-docker-debian
5e6ec7f28fb7: Pull complete
3cf17b373001: Pull complete
7b23a3f83a09: Pull complete
268608fc2c0a: Pull complete
163e85c235df: Pull complete
9bc1eeba2548: Pull complete
804806f68463: Pull complete
f729397d88e5: Pull complete
4c2ed157a37d: Pull complete
a8004303490a: Pull complete
b1a69f2f7cc9: Pull complete
b46b4b238e90: Pull complete
Digest: sha256:7a3eb9fd0e5ac009106600d7ba4b46162ff23671fd6c1576dcc7d2ff25053a0a
Status: Downloaded newer image for pipech/erpnext-docker-debian:mas-py3-latest
PS C:\WINDOWS\system32> docker run -d -p 8000-8005:8000-8005 -p 9000-9005:9000-9005 -p 3306-3307:3306-3307 pipech/erpnext-docker-debian:mas-py3-latest
d89469abb696e33331816cb71ea69b6dd080d0257c3242abc4ffc211e1a55e40
C:\Program Files\Docker\Docker\Resources\bin\docker.exe: Error response from daemon: driver failed programming external connectivity on endpoint competent_bardeen (f5a9afbdec028a90375ce67c2a167de2252f2c2e46a04515cf1a14a537acb7bc): Error starting userland proxy: Bind for 0.0.0.0:3306 failed: port is already allocated.
PS C:\WINDOWS\system32> docker run -d -p 8000-8005:8000-8005 -p 9000-9005:9000-9005 pipech/erpnext-docker-debian:mas-py3-latest
32c1f97daeace55959e6f7fa8ade9792375f23a40236959b498c7218164bd641
PS C:\WINDOWS\system32> docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
pipech/erpnext-docker-debian mas-py3-latest fd6f579bfaa2 17 hours ago 2.79GB
docker4w/nsenter-dockerd latest 2f1c802f322f 4 months ago 187kB
PS C:\WINDOWS\system32> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
PS C:\WINDOWS\system32> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
32c1f97daeac pipech/erpnext-docker-debian:mas-py3-latest "/usr/local/bin/entr…" 5 minutes ago Exited (1) 4 minutes ago optimistic_hawking
d89469abb696 pipech/erpnext-docker-debian:mas-py3-latest "/usr/local/bin/entr…" 5 minutes ago Created competent_bardeen

Default Email Templates use {{ link }} that pulls container port 8000 causing unreachable link

Forgive me if this has already been addressed. For the automated emails, such as password reset, invites, etc. in ERPNext, the links that get sent by default are generating using the container port of 8000. For example http://my.erpnext.com:8000/resetmypassword/etc.

This causes the link to be unreachable because Traefik is not exposing 8000 as an entrypoint. Any recommendations on how to resolve this issue? Or did I miss something in the instructions? Thanks in advance.

***Perhaps adding entrypoints for default Erpnext port and redirecting to https in Traefik config file.

OSError: [Errno 18] Invalid cross-device link

development setup
bench new-site dev1.loc

frappe@558c9f47083b:~/bench$ bench new-site test.a --verbose                                                                                      
Created user b64f0534bb29a93a                                                                                                                                  
Created database b64f0534bb29a93a                                                                                                                              
Granted privileges to user b64f0534bb29a93a and database b64f0534bb29a93a                                                                                      
================================================================================                                                                               
Creation of your site - test.a failed because MariaDB is not properly                                                                                             
configured to use the Barracuda storage engine.                                                                                                                
Please add the settings below to MariaDB's my.cnf, restart MariaDB then                                                                                        
run `bench new-site test.a` again.                                                                                                                                
																																							   
																																							   
[mysqld]                                                                                                                                                       
innodb-file-format=barracuda                                                                                                                                   
innodb-file-per-table=1                                                                                                                                        
innodb-large-prefix=1                                                                                                                                          
character-set-client-handshake = FALSE                                                                                                                         
character-set-server = utf8mb4                                                                                                                                 
collation-server = utf8mb4_unicode_ci                                                                                                                          
																																							   
[mysql]                                                                                                                                                        
default-character-set = utf8mb4                                                                                                                                
																																							   
================================================================================                                                                               
Traceback (most recent call last):                                                                                                                             
  File "/usr/lib/python2.7/runpy.py", line 174, in _run_module_as_main                                                                                         
	"__main__", fname, loader, pkg_name)                                                                                                                       
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code                                                                                                    
	exec code in run_globals                                                                                                                                   
  File "/home/frappe/bench/apps/frappe/frappe/utils/bench_helper.py", line 94, in <module>                                                                     
	main()                                                                                                                                                     
  File "/home/frappe/bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main                                                                         
	click.Group(commands=commands)(prog_name='bench')                                                                                                          
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 722, in __call__                                                         
	return self.main(*args, **kwargs)                                                                                                                          
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 697, in main                                                             
	rv = self.invoke(ctx)                                                                                                                                      
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke                                                          
	return _process_result(sub_ctx.command.invoke(sub_ctx))                                                                                                    
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 1066, in invoke                                                          
	return _process_result(sub_ctx.command.invoke(sub_ctx))                                                                                                    
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 895, in invoke                                                           
	return ctx.invoke(self.callback, **ctx.params)                                                                                                             
  File "/home/frappe/bench/env/local/lib/python2.7/site-packages/click/core.py", line 535, in invoke                                                           
	return callback(*args, **kwargs)                                                                                                                           
  File "/home/frappe/bench/apps/frappe/frappe/commands/site.py", line 34, in new_site                                                                          
	verbose=verbose, install_apps=install_app, source_sql=source_sql, force=force)                                                                             
  File "/home/frappe/bench/apps/frappe/frappe/commands/site.py", line 78, in _new_site                                                                         
	_drop_site(site, mariadb_root_username, mariadb_root_password, force=True)                                                                                 
  File "/home/frappe/bench/apps/frappe/frappe/commands/site.py", line 382, in _drop_site                                                                       
	move(archived_sites_path, site)                                                                                                                            
  File "/home/frappe/bench/apps/frappe/frappe/commands/site.py", line 401, in move                                                                             
	os.rename(old_path, final_new_path)                                                                                                                        
OSError: [Errno 18] Invalid cross-device link   

pipech/erpnext-docker-debian:v10.1.44
Docker version 18.06.0-ce, build 0ffa825

Domain Production Configuration

Thanks for this repo! Is really helpful :)

I just have a quick question, in your Production Setup Wiki one of the steps is to edit In production_setup/prd.yml

However, that file does not exist, is it a typo or should I create the file and only write:

labels:
    - "traefik.frontend.rule=Host:example1.com"

SSL Problems

If you start the docker swarm, enter the frappe bash and type:

wkhtmltopdf https://www.google.com google.pdf

you get this error:

frappe@e8451fef2110:~/bench$ wkhtmltopdf https://www.google.com google.pdf Loading pages (1/6) QSslSocket: cannot resolve CRYPTO_num_locks ] 10% QSslSocket: cannot resolve CRYPTO_set_id_callback QSslSocket: cannot resolve CRYPTO_set_locking_callback QSslSocket: cannot resolve sk_free QSslSocket: cannot resolve sk_num QSslSocket: cannot resolve sk_pop_free QSslSocket: cannot resolve sk_value QSslSocket: cannot resolve SSL_library_init QSslSocket: cannot resolve SSL_load_error_strings QSslSocket: cannot resolve SSLv3_client_method QSslSocket: cannot resolve SSLv23_client_method QSslSocket: cannot resolve SSLv3_server_method QSslSocket: cannot resolve SSLv23_server_method QSslSocket: cannot resolve X509_STORE_CTX_get_chain QSslSocket: cannot resolve OPENSSL_add_all_algorithms_noconf QSslSocket: cannot resolve OPENSSL_add_all_algorithms_conf QSslSocket: cannot resolve SSLeay QSslSocket: cannot call unresolved function CRYPTO_num_locks QSslSocket: cannot call unresolved function CRYPTO_set_id_callback QSslSocket: cannot call unresolved function CRYPTO_set_locking_callback QSslSocket: cannot call unresolved function SSL_library_init QSslSocket: cannot call unresolved function SSLv23_client_method QSslSocket: cannot call unresolved function sk_num QSslSocket: cannot call unresolved function SSLv23_client_method QSslSocket: cannot call unresolved function SSL_library_init Error: Failed loading page https://www.google.com (sometimes it will work just to ignore this error with --load-error-handling ignore) Exit with code 1 due to network error: UnknownNetworkError QSslSocket: cannot call unresolved function CRYPTO_num_locks QSslSocket: cannot call unresolved function CRYPTO_set_id_callback QSslSocket: cannot call unresolved function CRYPTO_set_locking_callback

you can fix this with:

sudo apt-get install libssl1.0-dev

This error shows in erpnext generated PDFs - the Logo f.e. can be missing if it's a https src.

Build error: v10.x.x / python2

Error message

INFO:bench.app:getting app erpnext
INFO:bench.utils:git clone https://github.com/frappe/erpnext --branch v10.x.x --depth 1 --origin upstream
Cloning into 'erpnext'...
Checking out files: 100% (6318/6318), done.
INFO:bench.app:installing erpnext
INFO:bench.utils:./env/bin/pip install -q  -e ./apps/erpnext 
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
INFO:bench.utils:bench build --app erpnext
Usage: bench  build [OPTIONS]
Try "bench  build --help" for help.
Error: no such option: --app
('installing', u'erpnext')
Traceback (most recent call last):
  File "/usr/local/bin/bench", line 11, in <module>
	load_entry_point('bench', 'console_scripts', 'bench')()
  File "/home/frappe/bench-repo/bench/cli.py", line 40, in cli
	bench_command()
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 764, in __call__
	return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 717, in main
	rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 1137, in invoke
	return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 956, in invoke
	return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 555, in invoke
	return callback(*args, **kwargs)
  File "/home/frappe/bench-repo/bench/commands/make.py", line 40, in get_app
	get_app(git_url, branch=branch)
  File "/home/frappe/bench-repo/bench/app.py", line 140, in get_app
	build_assets(bench_path=bench_path, app=app_name)
  File "/home/frappe/bench-repo/bench/utils.py", line 206, in build_assets
	exec_cmd(command, cwd=bench_path)
  File "/home/frappe/bench-repo/bench/utils.py", line 159, in exec_cmd
	raise CommandFailedError(cmd)
bench.utils.CommandFailedError: bench build --app erpnext

Travis
#91 - 23/05/19
#92 - 28/05/19

Cause by this line
https://github.com/frappe/bench/blob/92c17216f686759c882346b1864d5c0e81845dbc/bench/utils.py#L203-L206

Which call bench build with --app argument
https://github.com/frappe/frappe/blob/b0f9001c72a147921a118e868bb69158d2db969a/frappe/commands/utils.py#L15-L27

Which call frappe.build.bundle function
In version 11, 12 there is an app agrument in frappe.build.bundle function
https://github.com/frappe/frappe/blob/f75aa3beffe1639b999cb60e93707a494e6c61b3/frappe/build.py#L33-L47

But in version 10 there is no app agrument in frappe.build.bundle function
https://github.com/frappe/frappe/blob/3513e6b32ddc7aaec766fd9be976d20e049eab5b/frappe/build.py#L29-L42

Can't find frappe container ID

I am the newbie to docker and follow the step to set up production as per your manual. But stuck at the frappe container ID step. Please guide me the correct direction. Thanks in advance.

Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\WINDOWS\system32> docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
docker4w/nsenter-dockerd latest 2f1c802f322f 4 months ago 187kB
PS C:\WINDOWS\system32> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
PS C:\WINDOWS\system32> docker pull pipech/erpnext-docker-debian:sta-py2-latest
sta-py2-latest: Pulling from pipech/erpnext-docker-debian
cd8eada9c7bb: Pull complete
d8b1a5347e4d: Pull complete
92788d81d6b5: Pull complete
52aff3ed3fa4: Pull complete
33ac4d5b22ed: Pull complete
1199d2f56ef7: Pull complete
8cdd05f54f03: Pull complete
d434a892d100: Pull complete
e86ed71dbea6: Pull complete
8481442f0ce1: Pull complete
c972c7b52725: Pull complete
7137e0aed0d2: Pull complete
Digest: sha256:49db0035d7589a34453deda3c7b2165d8624dffcfbd0edf8b08f23670cf5e19c
Status: Downloaded newer image for pipech/erpnext-docker-debian:sta-py2-latest
PS C:\WINDOWS\system32> docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
pipech/erpnext-docker-debian sta-py2-latest 69fef46a9930 4 weeks ago 2.97GB
docker4w/nsenter-dockerd latest 2f1c802f322f 4 months ago 187kB
PS C:\WINDOWS\system32> docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
PS C:\WINDOWS\system32> docker swarm init
Swarm initialized: current node (gw35at2m9ohw4v9jiqc1zkrcj) is now a manager.

To add a worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-4kao6xxxxxxxxxxxxxxxxxxxxx 192.168.65.3:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

PS C:\WINDOWS\system32> git clone https://github.com/pipech/erpnext-docker-debian.git
Cloning into 'erpnext-docker-debian'...
remote: Enumerating objects: 63, done.
remote: Counting objects: 100% (63/63), done.
remote: Compressing objects: 100% (48/48), done.
remote: Total 1323 (delta 26), reused 33 (delta 14), pack-reused 1260
Receiving objects: 100% (1323/1323), 198.23 KiB | 96.00 KiB/s, done.
Resolving deltas: 100% (737/737), done.
PS C:\WINDOWS\system32> cd erpnext-docker-debian/production_setup
PS C:\WINDOWS\system32\erpnext-docker-debian\production_setup> docker network create --driver overlay --scope swarm traefik_proxy
vrk3ik8tyu7inlv4atnjwiqbf
PS C:\WINDOWS\system32\erpnext-docker-debian\production_setup> docker stack deploy -c prd.yml prd1
Creating network prd1_default
Creating config prd1_redis-socketio-conf
Creating config prd1_traefik-conf
Creating config prd1_mariadb-conf
Creating config prd1_mariadb-init-conf
Creating config prd1_redis-cache-conf
Creating config prd1_redis-queue-conf
Creating service prd1_frappe
Creating service prd1_mariadb
Creating service prd1_redis-cache
Creating service prd1_redis-queue
Creating service prd1_redis-socketio
Creating service prd1_traefik
PS C:\WINDOWS\system32\erpnext-docker-debian\production_setup> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
78d534a8ae7d pipech/erpnext-docker-debian:sta-py2-latest "/home/frappe/produc…" 1 second ago Created prd1_frappe.1.ji0abe8pqj53fij8m7zxvjego
24474fb3ffad pipech/erpnext-docker-debian:sta-py2-latest "/home/frappe/produc…" 17 seconds ago Created 3306-3307/tcp, 8000-8005/tcp, 9000-9005/tcp prd1_frappe.1.bh5l9pdxyao6v3qtzciy19cw3
450a6e2ba149 pipech/erpnext-docker-debian:sta-py2-latest "/home/frappe/produc…" 28 seconds ago Created 3306-3307/tcp, 8000-8005/tcp, 9000-9005/tcp prd1_frappe.1.0unwlq7ul6ha27gr58sq2fwa6
dd184940ab1e pipech/erpnext-docker-debian:sta-py2-latest "/home/frappe/produc…" 39 seconds ago Created 3306-3307/tcp, 8000-8005/tcp, 9000-9005/tcp prd1_frappe.1.0oklh9d1k3mbm4eewarkpgthd
b7356b7a5632 pipech/erpnext-docker-debian:sta-py2-latest "/home/frappe/produc…" 50 seconds ago Created 3306-3307/tcp, 8000-8005/tcp, 9000-9005/tcp prd1_frappe.1.s9137a6sjoo73x4hgcxw55ygh
cda5b472e0a5 pipech/erpnext-docker-debian:sta-py2-latest "/home/frappe/produc…" About a minute ago Created 3306-3307/tcp, 8000-8005/tcp, 9000-9005/tcp prd1_frappe.1.xkuf9o598yyc9366sgjwhzp0d
PS C:\WINDOWS\system32\erpnext-docker-debian\production_setup> docker exec -it 78d534a8ae7d bash
Error: No such container: 78d534a8ae7d

External mariadb and configs

Hi there

Thanks for the builds.

I wondered do you have a production build with the ability to have an external mariadb database and if so which configs do I update to redirect to my external db docker?

Thanks in advance.

frappe init.sh fails on mv

When I run the ./init.sh script, the mv fails

. init.sh
++ sudo mv ./sites-dev/apps.txt ./sites-dev/assets ./sites-dev/common_site_config.json ./sites-dev/currentsite.txt ./sites-dev/site1.local ./sites/
mv: will not create hard link './sites/site1.local/locks' to directory './sites/assets'

nginx.tmpl not found - production_setup

https://pipech.github.io/erpnext-docker-debian/production_setup/

Hi, It seems to missing nginx.tmpl file
thanks.

$ git clone https://github.com/pipech/erpnext-docker-debian.git
Cloning into 'erpnext-docker-debian'...
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (60/60), done.
remote: Total 338 (delta 66), reused 96 (delta 51), pack-reused 226
Receiving objects: 100% (338/338), 59.61 KiB | 455.00 KiB/s, done.
Resolving deltas: 100% (175/175), done.

$ cd erpnext-docker-debian/production_setup

$ docker stack deploy -c prd.yml mystack
Creating network mystack_default
open /c/Users/hgati/tmp/erpnext-docker-debian/production_setup/conf/nginx-tmpl-conf/nginx.tmpl: The system cannot find the path specified.

$ ls
conf  Dockerfile  prd.yml

Slideshow Creation Fails w/ error: AttributeError: 'map' object has no attribute 'split'

So I've searched around a bit and I see that back when v11 was in dev there was a similar issue: https://discuss.erpnext.com/t/website-slide-show-attributeerror-map-object-has-no-attribute-split/43904 ,however, I've tested this with the "Production" vm image that is provided by ERPNext and cannot reproduce the error. Wondering if @pipech is experiencing the same with the latest docker image? It's clearly a python error and I think it's a bit misleading, but I could use some guidance on this. Here's a snippet of the specific error I am getting:

Traceback (most recent call last):
  File "/home/frappe/bench/apps/frappe/frappe/app.py", line 61, in application
	response = frappe.handler.handle()
  File "/home/frappe/bench/apps/frappe/frappe/handler.py", line 21, in handle
	data = execute_cmd(cmd)
  File "/home/frappe/bench/apps/frappe/frappe/handler.py", line 56, in execute_cmd
	return frappe.call(method, **frappe.form_dict)
  File "/home/frappe/bench/apps/frappe/frappe/__init__.py", line 1019, in call
	return fn(*args, **newargs)
  File "/home/frappe/bench/apps/frappe/frappe/desk/form/save.py", line 22, in savedocs
	doc.save()
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 260, in save
	return self._save(*args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 283, in _save
	self.insert()
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 222, in insert
	self.run_before_save_methods()
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 876, in run_before_save_methods
	self.run_method("validate")
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 772, in run_method
	out = Document.hook(fn)(self, *args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 1048, in composer
	return composed(self, method, *args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 1031, in runner
	add_to_return_value(self, fn(self, *args, **kwargs))
  File "/home/frappe/bench/apps/frappe/frappe/model/document.py", line 766, in <lambda>
	fn = lambda self, *args, **kwargs: getattr(self, method)(*args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/website/doctype/website_slideshow/website_slideshow.py", line 14, in validate
	self.validate_images()
  File "/home/frappe/bench/apps/frappe/frappe/website/doctype/website_slideshow/website_slideshow.py", line 25, in validate_images
	result = frappe.get_all("File", filters={ "file_url":("in", files) }, fields="is_private")
  File "/home/frappe/bench/apps/frappe/frappe/__init__.py", line 1274, in get_all
	return get_list(doctype, *args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/__init__.py", line 1247, in get_list
	return frappe.model.db_query.DatabaseQuery(doctype).execute(None, *args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/model/db_query.py", line 93, in execute
	result = self.build_and_run()
  File "/home/frappe/bench/apps/frappe/frappe/model/db_query.py", line 105, in build_and_run
	args = self.prepare_args()
  File "/home/frappe/bench/apps/frappe/frappe/model/db_query.py", line 124, in prepare_args
	self.build_conditions()
  File "/home/frappe/bench/apps/frappe/frappe/model/db_query.py", line 303, in build_conditions
	self.build_filter_conditions(self.filters, self.conditions)
  File "/home/frappe/bench/apps/frappe/frappe/model/db_query.py", line 324, in build_filter_conditions
	conditions.append(self.prepare_filter_condition(f))
  File "/home/frappe/bench/apps/frappe/frappe/model/db_query.py", line 382, in prepare_filter_condition
	values = values.split(",")
AttributeError: 'map' object has no attribute 'split'

Setup Node Exporter on AWS EC2 go version issue

node_exporter]$ make
Makefile.common:54: This repository requires Go >= 1.11 because of Go modules
Makefile.common:55: Some recipes may not work as expected as the current Go runtime is 'go1.10.3'

checking code style
checking license header
running golangci-lint
/home/ec2-user/go/bin/golangci-lint run ./...
ERRO Running error: context loading failed: failed to load program with go/packages: unsupported version of go: exit status 2: flag provided but not defined: -compiled
usage: list [-e] [-f format] [-json] [build flags] [packages]
Run 'go help list' for details.

make: *** [common-lint] Error 3

production setup - domain really required?

in the instructions for the production setup it says

This setup is meant to run on server with public IP address and domain pointing to those IP address, otherwise it won’t work.

I am wondering whether the "domain pointing to those IP addresses" part is actually correct. I mean you should be able to access your ERPNext instance directly via the IP addresse as well, wouldn't you?

Error : bench.utils.CommandFailedError: ./env/bin/pip install -q -e ./apps/custom_app --no-cache-dir

Command > bench new-app custom-app

Error >

Command "python setup.py egg_info" failed with error code 1 in /home/frappe/bench/apps/thai_wht/
Traceback (most recent call last):
  File "/usr/local/bin/bench", line 11, in <module>
	load_entry_point('bench', 'console_scripts', 'bench')()
  File "/home/frappe/bench-repo/bench/cli.py", line 40, in cli
	bench_command()
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 722, in __call__
	return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 697, in main
	rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
	return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 895, in invoke
	return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 535, in invoke
	return callback(*args, **kwargs)
  File "/home/frappe/bench-repo/bench/commands/make.py", line 48, in new_app
	new_app(app_name)
  File "/home/frappe/bench-repo/bench/app.py", line 156, in new_app
	install_app(app, bench_path=bench_path)
  File "/home/frappe/bench-repo/bench/app.py", line 167, in install_app
	find_links=find_links))
  File "/home/frappe/bench-repo/bench/utils.py", line 153, in exec_cmd
	raise CommandFailedError(cmd)
bench.utils.CommandFailedError: ./env/bin/pip install -q  -e ./apps/thai_wht --no-cache-dir

Workaround >
frappe/utils/boilerplate.py line 275
Change install_requires = f.read().strip().split('\n')
To install_requires = f.read().strip().split('\\n')

Ref >
https://discuss.erpnext.com/t/unable-to-create-an-app/36901/14
https://discuss.erpnext.com/t/create-new-app-failed-with-error-command-python-setup-py-egg-info-failed-with-error-code-1/36967

Known-Bug for Version >

  • v10.1.30
  • v10.1.35
  • v10.1.37

How do I add another domain to an existing site?

Trying to figure out how to pull off the typical bench setup add-domain domain —site site.

I’ve also tried adding a new site acoording to the production documentation but still getting the 404 error.

Build Error : AttributeError: 'NoneType' object has no attribute 'group'

The command '/bin/sh -c wget $easyinstallRepo     && python install.py     --without-bench-setup     && rm -rf bench     && git clone -b $benchBranch $benchRepo $benchPath      && sudo pip install -e $benchPath     && bench init $benchFolderName --frappe-path $frappeRepo --frappe-branch $frappeBranch --python $pythonVersion     && cd $benchFolderName     && sudo service mysql start     && bench new-site $siteName     --mariadb-root-password $mysqlPass      --admin-password $adminPass     && bench get-app erpnext $erpnextRepo --branch $erpnextBranch     && bench --site $siteName install-app erpnext     && bench switch-to-branch $branch     && bench update --patch     && mysql -u "root" "-p$mysqlPass" -e "CREATE USER '$remoteUser'@'%' IDENTIFIED BY '$remotePass';"     && mysql -u "root" "-p$mysqlPass" -e "GRANT ALL ON *.* TO '$remoteUser'@'%';"' returned a non-zero code: 1	

Traceback

�[91mTraceback (most recent call last):
  File "/usr/local/bin/bench", line 11, in <module>
	load_entry_point('bench', 'console_scripts', 'bench')()
  File "/home/frappe/bench-repo/bench/cli.py", line 40, in cli
	bench_command()
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 722, in __call__
�[0m
�[91m    return self.main(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 697, in main
�[0m
�[91m    rv = self.invoke(ctx)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
�[0m
�[91m    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 895, in invoke
	return ctx.invoke(self.callback, **ctx.params)
  File "/usr/local/lib/python2.7/dist-packages/click/core.py", line 535, in invoke
	return callback(*args, **kwargs)
  File "/home/frappe/bench-repo/bench/commands/update.py", line 126, in switch_to_branch
	switch_to_branch(branch=branch, apps=list(apps), upgrade=upgrade)
  File "/home/frappe/bench-repo/bench/app.py", line 394, in switch_to_branch
	switch_branch(branch, apps=apps, bench_path=bench_path, upgrade=upgrade)
  File "/home/frappe/bench-repo/bench/app.py", line 362, in switch_branch
	version_upgrade = is_version_upgrade(app=app, bench_path=bench_path, branch=branch)
  File "/home/frappe/bench-repo/bench/app.py", line 262, in is_version_upgrade
	upstream_version = get_upstream_version(app=app, branch=branch, bench_path=bench_path)
  File "/home/frappe/bench-repo/bench/app.py", line 335, in get_upstream_version
	return get_version_from_string(contents)
  File "/home/frappe/bench-repo/bench/app.py", line 405, in get_version_from_string
	return match.group(2)
AttributeError: 'NoneType' object has no attribute 'group'

Full error log

Production Setup with Private IP

Have tried and passed production setup in my docker pipech/erpnext-docker-debian:12.x.x-190226-py3. But can't browse through local machine, because am testing inside my local machine.

Do noted "This setup is meant to run on server with public IP address and domain pointing to those IP address, otherwise it won’t work."

How could I setup the production setting with localhost browsing same as Trial setup?

Thanks in advance!

Question: Traefik instead of nginx for reverse proxy smart?

I'm currently evaluating deployment patterns for ERPNext and found your repo. Is there something about Frappe/bench that might prevent me from trying to switch to Traefik for rev proxy? The intent is to run additional low-use containers to the same host/instance for more efficient resource utilization.

Edit: Short answer is yes, but I'm still investigating if there will be any side-affects...

version: '3.3'

networks:
  proxy:
    external:
      name: proxy

services:

  traefik:
    image: traefik
    command: --api --web --docker --docker.watch --docker.domain=localhost --logLevel=DEBUG
    networks:
      - proxy
    ports:
      # - "80:80"     # The HTTP port
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - "8080:8080" # The Web UI (enabled by --api)
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock # So that Traefik can listen to the Docker events

  nginx-frappe:
    image: nginx:1.12.2
    environment:
      - VIRTUAL_HOST=frappe.localhost
    networks:
      - proxy
      - default
    volumes:
      - ./conf/nginx-conf/nginx.conf:/etc/nginx/conf.d/default.conf
      - frappe-sites-volumes:/home/frappe/bench/sites
      - frappe-apps-volumes:/home/frappe/bench/apps
    labels:
      - "traefik.backend=frappe"
      - "traefik.docker.network=proxy"
      - "traefik.enable=true"
      - "traefik.frontend.rule=Host:frappe.docker.localhost"
      - "traefik.port=80"
      - "traefik.protocol=http"

  mariadb:
    image: mariadb:10.2.12
    environment:
      - MYSQL_USER=root
      - MYSQL_ROOT_PASSWORD=123
    networks:
      - default
    volumes:
      - ./conf/mariadb-conf/mariadb.cnf:/etc/mysql/conf.d/mariadb.cnf
      - ./conf/mariadb-conf/init.sql:/home/init.sql
      - mariadb-data-volumes:/var/lib/mysql
    ports:
      - "3307:3306"

  redis-cache:
    image: redis:alpine
    networks:
      - default
    volumes:
      - ./conf/redis-conf/redis_cache.conf:/etc/conf.d/redis.conf
    command: ["redis-server","/etc/conf.d/redis.conf"]

  redis-queue:
    image: redis:alpine
    networks:
      - default
    volumes:
      - ./conf/redis-conf/redis_queue.conf:/etc/conf.d/redis.conf
    command: ["redis-server","/etc/conf.d/redis.conf"]

  redis-socketio:
    image: redis:alpine
    networks:
      - default
    volumes:
      - ./conf/redis-conf/redis_socketio.conf:/etc/conf.d/redis.conf
    command: ["redis-server","/etc/conf.d/redis.conf"]

  frappe:
    image: pipech/erpnext-docker-debian-production:stable
    environment:
    # beware prdsite1.local has been hardcoded into nginx-conf/nginx.conf
      - benchNewSiteName=prdsite1.local
    networks:
      - proxy
      - default
    # ports:
    #   - "8000:8000"   #webserver_port
    #   - "9000:9000"   #socketio_port
    #   - "6787:6787"   #file_watcher_port
    expose:
      - "8000"
      - "9000"
      - "6787"
    volumes:
      - ./conf/frappe-docker-conf/init.sh:/home/frappe/init.sh
      - frappe-sites-volumes:/home/frappe/bench/sites
      - frappe-apps-volumes:/home/frappe/bench/apps
      - frappe-logs-volumes:/home/frappe/bench/logs
    stdin_open: true
    tty: true
    depends_on:
      - mariadb
      - redis-cache
      - redis-queue
      - redis-socketio

  portainer:
    image: portainer/portainer
    restart: unless-stopped
    networks:
      - default
      - proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      - "traefik.frontend.rule=Host:portainer.docker.localhost"
      - "traefik.port=9000"
      - "traefik.backend=portainer"
      - "traefik.docker.network=proxy"

volumes:
  frappe-sites-volumes:
  frappe-apps-volumes:
  frappe-logs-volumes:
  mariadb-data-volumes:

My primary reason for doing this is to be able to test "production" configuration prior to deployment... and Traefik has made me lazy in this respect.

Reducing Image Size

I've tried.

  • combine all run command
  • not init new site

It didn't works.

FROM debian:9.3

ENV systemUser=frappe \
    # set local
    LC_ALL=en_US.UTF-8 \
    LC_CTYPE=en_US.UTF-8 \
    LANG=en_US.UTF-8 \
    # frappe related env
    easyinstallRepo='https://raw.githubusercontent.com/frappe/bench/master/playbooks/install.py' \
    benchPath=bench-repo \
    benchRepo='https://github.com/frappe/bench' \
    benchBranch=master \
    frappeRepo='https://github.com/frappe/frappe' \
    frappeBranch=master \
    # for python 2 use = python
    # for python 3 use = python3 or python3.6 for centos
    pythonVersion=python \
    benchFolderName=bench \
    erpnextRepo='https://github.com/frappe/erpnext' \
    erpnextBranch=master \
    siteName=site1.local \
    branch=master \
    adminPass=12345 \
    mysqlPass=travis \
    # mysql remote user
    remoteUser=remote \
    remotePass=12345

# install prerequisite
RUN apt-get -y update \
    && apt-get -y install \
    build-essential \
    python-setuptools \
    curl \
    wget \
    nano \
    cron \
    gettext-base \
    sudo \
    locales \
    supervisor \
    nginx \
    && apt-get autoremove --purge \
    && apt-get clean \
    # work around for  "cmd": "chsh frappe -s $(which bash)", "stderr": "Password: chsh: PAM: Authentication failure"
    # caused by > bench/playbooks/create_user.yml > shell: "chsh {{ frappe_user }} -s $(which bash)"
    && sed -i 's/auth       required   pam_shells.so/auth       sufficient   pam_shells.so/' /etc/pam.d/chsh \
    # Set locales
    && sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen \
    && locale-gen \
    # change user and workdir
    && adduser --disabled-password --gecos "" $systemUser \
    && usermod -aG sudo $systemUser \
    && echo "%sudo  ALL=(ALL)  NOPASSWD: ALL" > /etc/sudoers.d/sudoers \
    # install bench prerequisite
    && wget $easyinstallRepo \
    && python install.py \
    --without-bench-setup \
    --user $systemUser \
    # change directory
    && cd /home/$systemUser \
    # install bench & init bench folder
    && sudo -u $systemUser git clone --branch $benchBranch --depth 1 --origin upstream $benchRepo $benchPath  \
    && pip install -e $benchPath \
    && sudo -u $systemUser bench init $benchFolderName --frappe-path $frappeRepo --frappe-branch $frappeBranch --python $pythonVersion \
    # cd to bench folder and start mysql service
    && cd /home/$systemUser/$benchFolderName \
    && service mysql start \
    # create new site
    && sudo -u $systemUser bench new-site $siteName \
    --mariadb-root-password $mysqlPass  \
    --admin-password $adminPass \
    # install erpnext
    && sudo -u $systemUser bench get-app erpnext $erpnextRepo --branch $erpnextBranch \
    && sudo -u $systemUser bench --site $siteName install-app erpnext \
    # fix for Setup failed >> Could not start up: Error in setup
    && sudo -u $systemUser bench update --patch \
    # add mysql remote user, so we can connect to mysql inside container from host
    && mysql -u "root" "-p$mysqlPass" -e "CREATE USER '$remoteUser'@'%' IDENTIFIED BY '$remotePass';" \
    && mysql -u "root" "-p$mysqlPass" -e "GRANT ALL ON *.* TO '$remoteUser'@'%';" \
    # change back config for work around for  "cmd": "chsh frappe -s $(which bash)", "stderr": "Password: chsh: PAM: Authentication failure"
    && sed -i 's/auth       sufficient   pam_shells.so/auth       required   pam_shells.so/' /etc/pam.d/chsh

# set user and workdir
WORKDIR /home/$syste
mUser/$benchFolderName

# copy production config
COPY production_setup/conf/frappe-docker-conf /home/$systemUser/production_config
# fix for [docker Error response from daemon OCI runtime create failed starting container process caused "permission denied" unknown]
RUN sudo chmod +x /home/$systemUser/production_config/entrypoint_prd.sh

# run start mysql service when container start
COPY entrypoint.sh /usr/local/bin/
# fix for [docker Error response from daemon OCI runtime create failed starting container process caused "permission denied" unknown]
RUN sudo chmod +x /usr/local/bin/entrypoint.sh
CMD ["/usr/local/bin/entrypoint.sh"]

# expose port
EXPOSE 8000-8005 9000-9005 3306-3307

Error in VSCode container

First of all, thanks for creating this repo. It's a lifesaver for frappe developers.

I'm getting the following error when opening the folder in VSCode insider build (https://github.com/pipech/erpnext-docker-debian/wiki/Development-setup-Inside-Container-with-VS-Code) -

ERROR: for development_setup_vscode_devcontainer_frappe_1 Cannot start service frappe: OCI runtime create failed: container_linux.go:344: starting container process caused "exec: "/home/frappe/bench/entrypoint.sh": permission denied": unknown

I followed the steps outlined in the Wiki page. Let me know if I'm missing something. Thanks.

Production Setup #bench backup

When trying to backup bench throw error. Please advise. Thanks in advance!

root@03ec4aada0f2:/home/frappe/bench# bench backup
Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 193, in _run_module_as_main
	"__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
	exec(code, run_globals)
  File "/home/frappe/bench/apps/frappe/frappe/utils/bench_helper.py", line 97, in <module>
	main()
  File "/home/frappe/bench/apps/frappe/frappe/utils/bench_helper.py", line 18, in main
	click.Group(commands=commands)(prog_name='bench')
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 764, in __call__
	return self.main(*args, **kwargs)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 717, in main
	rv = self.invoke(ctx)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 1137, in invoke
	return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 1137, in invoke
	return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 956, in invoke
	return ctx.invoke(self.callback, **ctx.params)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/core.py", line 555, in invoke
	return callback(*args, **kwargs)
  File "/home/frappe/bench/env/lib/python3.5/site-packages/click/decorators.py", line 17, in new_func
	return f(get_current_context(), *args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/commands/__init__.py", line 25, in _func
	ret = f(frappe._dict(ctx.obj), *args, **kwargs)
  File "/home/frappe/bench/apps/frappe/frappe/commands/site.py", line 302, in backup
	odb = scheduled_backup(ignore_files=not with_files, backup_path_db=backup_path_db, backup_path_files=backup_path_files, backup_path_private_files=backup_path_private_files, force=True)
  File "/home/frappe/bench/apps/frappe/frappe/utils/backups.py", line 170, in scheduled_backup
	odb = new_backup(older_than, ignore_files, backup_path_db=backup_path_db, backup_path_files=backup_path_files, force=force)
  File "/home/frappe/bench/apps/frappe/frappe/utils/backups.py", line 174, in new_backup
	delete_temp_backups(older_than = frappe.conf.keep_backups_for_hours or 24)
  File "/home/frappe/bench/apps/frappe/frappe/utils/backups.py", line 193, in delete_temp_backups
	os.remove(this_file_path)
PermissionError: [Errno 13] Permission denied: './erpnext.com/private/backups/20190312_232916-zenboxallin_one-database.sql.gz'

build error

https://github.com/pipech/erpnext-docker-debian/blob/master/Dockerfile
dockerfile build error.
how can i fix ?

Cloning into '/tmp/.bench'...

Traceback (most recent call last):
  File "install.py", line 400, in <module>

    install_bench(args)
  File "install.py", line 83, in install_bench
    raise Exception('Please run this script as a non-root user with sudo privileges, but without using sudo or pass --user=USER')
Exception: Please run this script as a non-root user with sudo privileges, but without using sudo or pass --user=USER

Error: ResponseItem.ErrorDetail[code=1,message=The command '/bin/sh -c wget $easyinstallRepo     && python install.py     --without-site     --$benchSetup     --mysql-root-password $mysqlPass      --admin-password $adminPass      --bench-name $benchName      --bench-branch $benchBranch' returned a non-zero code: 1]
Failed to deploy 'erpnext Dockerfile: Dockerfile': The command '/bin/sh -c wget $easyinstallRepo     && python install.py     --without-site     --$benchSetup     --mysql-root-password $mysqlPass      --admin-password $adminPass      --bench-name $benchName      --bench-branch $benchBranch' returned a non-zero code: 1

Import Not Working

Hi @pipech

Trust you're doing great. It seems like the Data Import feature isn't working in this setup. Once I click on 'Start Import', the status changes to 'Failed'

Please advise

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.