├── .github └── workflows │ ├── auto-check-new-releases.yml │ ├── docker-images.yml │ └── manual-release.yml ├── .gitignore ├── LICENSE ├── README.md ├── default-requirements.txt ├── demo ├── .env.example ├── README.md ├── docker-compose-local.yml ├── docker-compose.yml ├── local-files │ └── .gitkeep ├── python_scripts │ ├── hello.py │ ├── hello_faker.py │ └── hello_naskpy.py └── requirements.txt ├── images ├── n8n-debian │ ├── Dockerfile │ ├── README.md │ └── docker-entrypoint.sh └── n8n │ ├── Dockerfile │ ├── README.md │ ├── docker-entrypoint.sh │ └── hooks │ └── build └── release-versions └── n8n-latest.txt /.github/workflows/auto-check-new-releases.yml: -------------------------------------------------------------------------------- 1 | ################### 2 | # ENV VARS: 3 | # # - FULL_NAME 4 | # # - EMAIL 5 | # - PAT (generated at Personal Access Tokens - with workflow access checked) 6 | ################### 7 | 8 | name: Check for new releases 9 | # Automatically check for new releases (new versions) 10 | on: 11 | schedule: 12 | - cron: "0 0 */1 * *" 13 | 14 | jobs: 15 | get-version: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - uses: actions/checkout@v2 19 | with: 20 | token: ${{ secrets.PAT }} 21 | - name: Fetch release version 22 | id: fetch-version 23 | run: | 24 | curl -sL https://raw.githubusercontent.com/n8n-io/n8n/master/package.json | jq -r ".version" > release-versions/n8n-latest.txt 25 | echo ::set-output name=version::$(cat release-versions/n8n-latest.txt) 26 | 27 | # - name: Check for modified files 28 | # id: git-check 29 | # run: echo ::set-output name=modified::$([ -z "`git status --porcelain`" ] && echo "false" || echo "true") 30 | # - name: Commit latest release version 31 | # if: steps.git-check.outputs.modified == 'true' 32 | # run: | 33 | # git config --global user.name '${{ secrets.FULL_NAME }}' 34 | # git config --global user.email '${{ secrets.EMAIL }}' 35 | # git commit -am "New release: $(cat release-versions/n8n-latest.txt)" 36 | # git push 37 | 38 | - uses: stefanzweifel/git-auto-commit-action@v4 39 | with: 40 | commit_message: New auto release v${{steps.fetch-version.outputs.version}} -------------------------------------------------------------------------------- /.github/workflows/docker-images.yml: -------------------------------------------------------------------------------- 1 | ########### 2 | # ENV VARS: 3 | # - DOCKER_USERNAME 4 | # - DOCKER_PASSWORD 5 | # - GITHUB_TOKEN (default) 6 | ########### 7 | 8 | name: Docker Image CI 9 | 10 | on: 11 | push: 12 | paths: 13 | - 'release-versions/*' 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Get current repository 20 | uses: actions/checkout@v1 21 | - name: Get the version 22 | id: vars 23 | run: echo ::set-output name=tag::$(cat release-versions/n8n-latest.txt) 24 | - name: Set up QEMU 25 | uses: docker/setup-qemu-action@v1 26 | - name: Set up Docker Buildx 27 | uses: docker/setup-buildx-action@v1 28 | - name: Login to DockerHub 29 | uses: docker/login-action@v1 30 | with: 31 | username: ${{ secrets.DOCKER_USERNAME }} 32 | password: ${{ secrets.DOCKER_PASSWORD }} 33 | 34 | - run: cp default-requirements.txt images/n8n/requirements.txt 35 | - name: Build (default => alpine) 36 | uses: docker/build-push-action@v2 37 | with: 38 | context: ./images/n8n 39 | build-args: | 40 | N8N_VERSION=${{steps.vars.outputs.tag}} 41 | platforms: linux/amd64 42 | push: true 43 | tags: | 44 | ${{ secrets.DOCKER_USERNAME }}/n8n-python:${{ steps.vars.outputs.tag }} 45 | ${{ secrets.DOCKER_USERNAME }}/n8n-python:latest 46 | 47 | - run: cp default-requirements.txt images/n8n-debian/requirements.txt 48 | - name: Build (debian) 49 | uses: docker/build-push-action@v2 50 | with: 51 | context: ./images/n8n-debian 52 | build-args: | 53 | N8N_VERSION=${{ steps.vars.outputs.tag }} 54 | platforms: linux/amd64,linux/arm64,linux/arm/v7 55 | push: true 56 | tags: | 57 | ${{ secrets.DOCKER_USERNAME }}/n8n-python:${{ steps.vars.outputs.tag }}-debian 58 | ${{ secrets.DOCKER_USERNAME }}/n8n-python:latest-debian 59 | 60 | - name: Docker Hub Description (README.md) 61 | uses: peter-evans/dockerhub-description@v2 62 | with: 63 | username: ${{ secrets.DOCKER_USERNAME }} 64 | password: ${{ secrets.DOCKER_PASSWORD }} 65 | repository: naskio/n8n-python 66 | readme-filepath: README.md 67 | 68 | - name: Create Release in GitHub 69 | id: create_release 70 | uses: actions/create-release@v1 71 | continue-on-error: true 72 | env: 73 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token 74 | with: 75 | tag_name: v${{steps.vars.outputs.tag}} 76 | release_name: Release ${{steps.vars.outputs.tag}} 77 | body: n8n v${{steps.vars.outputs.tag}} (python3 included) -------------------------------------------------------------------------------- /.github/workflows/manual-release.yml: -------------------------------------------------------------------------------- 1 | ################### 2 | # ENV VARS: 3 | # - PAT (generated at Personal Access Tokens - with workflow access checked) 4 | ################### 5 | 6 | name: Create new release manually 7 | 8 | on: 9 | workflow_dispatch: 10 | inputs: 11 | version: 12 | description: 'version' 13 | required: true 14 | default: '0.179.0' 15 | type: string 16 | 17 | jobs: 18 | get-version: 19 | runs-on: ubuntu-latest 20 | steps: 21 | 22 | - uses: actions/checkout@v2 23 | with: 24 | token: ${{ secrets.PAT }} 25 | 26 | ## if we prefer without an input 27 | # - name: Fetch release version 28 | # id: fetch-version 29 | # run: | 30 | # curl -sL https://raw.githubusercontent.com/n8n-io/n8n/master/package.json | jq -r ".version" > release-versions/n8n-latest.txt 31 | # echo ::set-output name=version::$(cat release-versions/n8n-latest.txt) 32 | 33 | - name: Fetch release version 34 | id: fetch-version 35 | run: | 36 | echo "${{ github.event.inputs.version }}" > release-versions/n8n-latest.txt 37 | 38 | - uses: stefanzweifel/git-auto-commit-action@v4 39 | with: 40 | commit_message: New manual release ${{ github.event.inputs.version }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | 132 | ### IDEA 133 | .idea/ 134 | cmake-build-*/ 135 | .idea_modules/ 136 | # File-based project format 137 | *.iws 138 | # IntelliJ 139 | out/ 140 | ### IDEA 141 | 142 | ### VS Code 143 | .vscode/ 144 | .history/ 145 | *.code-workspace 146 | ### VS Code 147 | 148 | ### MAC OS 149 | # General 150 | .DS_Store 151 | .AppleDouble 152 | .LSOverride 153 | 154 | # Icon must end with two \r 155 | Icon 156 | 157 | # Thumbnails 158 | ._* 159 | 160 | # Files that might appear in the root of a volume 161 | .DocumentRevisions-V100 162 | .fseventsd 163 | .Spotlight-V100 164 | .TemporaryItems 165 | .Trashes 166 | .VolumeIcon.icns 167 | .com.apple.timemachine.donotpresent 168 | 169 | # Directories potentially created on remote AFP share 170 | .AppleDB 171 | .AppleDesktop 172 | Network Trash Folder 173 | Temporary Items 174 | .apdisk 175 | ### MAC OS 176 | 177 | 178 | # Others 179 | *.tmp.* 180 | *.tmp 181 | n8n_data/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Mehdi Nassim KHODJA 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # n8n - docker image with Python 3.10 and custom node PythonFunction 2 | 3 | ![n8n.io - Workflow Automation](https://raw.githubusercontent.com/n8n-io/n8n/master/assets/n8n-logo.png) 4 | 5 | This [image](https://hub.docker.com/r/naskio/n8n-python) includes Python 3.10 by default. it can be used to run python 6 | scripts inside n8n using the [Execute Command](https://docs.n8n.io/nodes/n8n-nodes-base.executeCommand/) node or code 7 | snippets using the custom node [Python Function](https://www.github.com/naskio/n8n-nodes-python). 8 | 9 | > Run python 3.10 code on n8n. 10 | 11 | [Docker Hub](https://hub.docker.com/r/naskio/n8n-python) 12 | 13 | [GitHub repository](https://www.github.com/naskio/docker-n8n-python) 14 | 15 | ## Image Setup 16 | 17 | Using docker compose 18 | [docker-compose.yml](./demo/docker-compose-local.yml) 19 | 20 | ## Usage 21 | 22 | ### Run Python Code 23 | 24 | The image includes the custom module [n8n-nodes-python](https://www.github.com/naskio/n8n-nodes-python) by default. 25 | 26 | We can use this custom node [Python Function](https://www.github.com/naskio/n8n-nodes-python) to run a python code over 27 | the `items` (works the same way as [Function](https://docs.n8n.io/nodes/n8n-nodes-base.function) node) 28 | 29 | [Python Function node docs](https://www.github.com/naskio/n8n-nodes-python) 30 | 31 | ### Run mounted Python scripts using the ExecuteCommand node 32 | 33 | You can run `*.py`files that has been mounted to the container using 34 | the [ExecuteCommand](https://docs.n8n.io/nodes/n8n-nodes-base.executeCommand/) node. 35 | 36 | ### Installing external packages 37 | 38 | The [ExecuteCommand](https://docs.n8n.io/nodes/n8n-nodes-base.executeCommand/) node can be used to install python 39 | packages or install dependencies from a mounted `requirements.txt` file to the container. 40 | 41 | It can be combined with [n8nTrigger](https://docs.n8n.io/nodes/n8n-nodes-base.n8nTrigger) to install packages directly 42 | after starting the container. 43 | 44 | > Once the packages are installed, it can be used in the Python Function node. `import ` 45 | 46 | ## Documentation 47 | 48 | The official n8n documentation can be found under: [https://docs.n8n.io](https://docs.n8n.io) 49 | 50 | Additional information and example workflows on the n8n.io website: [https://n8n.io](https://n8n.io) 51 | 52 | Learn [how to run n8n in **Docker**](https://github.com/n8n-io/n8n/tree/master/docker/images/n8n/README.md) -------------------------------------------------------------------------------- /default-requirements.txt: -------------------------------------------------------------------------------- 1 | fire -------------------------------------------------------------------------------- /demo/.env.example: -------------------------------------------------------------------------------- 1 | VIRTUAL_HOST=workflows.example.com 2 | WEBMASTER_EMAIL=webmaster@example.com 3 | TIMEZONE=Europe/Paris 4 | N8N_BASIC_AUTH_USER=n8n 5 | N8N_BASIC_AUTH_PASSWORD=n8n_password 6 | POSTGRES_DB=n8n 7 | POSTGRES_USER=postgres 8 | POSTGRES_PASSWORD=postgres 9 | -------------------------------------------------------------------------------- /demo/README.md: -------------------------------------------------------------------------------- 1 | # docker-n8n-python 2 | 3 | Docker Compose configuration file for n8n with Python, ready to use 4 | 5 | ## Demo 6 | 7 | ``` 8 | docker-compose -f docker-compose-local.yml up 9 | docker-compose -f docker-compose-local.yml up -d 10 | docker-compose -f docker-compose-local.yml down 11 | ``` 12 | 13 | ## prerequisites 14 | 15 | - [Postgres](https://hub.docker.com/r/postgres/) 16 | - jwilder/nginx-proxy 17 | 18 | ## Step-by-step instructions 19 | 20 | - Configure `.env` file 21 | - Run `docker-compose up -d` 22 | - In order to run python scripts inside n8n 23 | ```shell 24 | cd /py_scripts 25 | cd /files 26 | cat /requirements/requirements.txt 27 | ``` 28 | 29 | ## Further information 30 | 31 | Read more 32 | at [n8n.io](https://docs.n8n.io/getting-started/installation/advanced/server-setup.html#docker-compose-example) 33 | , [here](https://github.com/n8n-io/n8n/blob/master/docker/compose/withPostgres/docker-compose.yml) 34 | or [here](https://github.com/n8n-io/n8n/blob/master/docker/images/n8n/README.md) 35 | 36 | for additional information about adding Python to n8n: 37 | 38 | - [Discussion](https://community.n8n.io/t/run-shell-script/2073) 39 | - [Discussion](https://community.n8n.io/t/running-a-python-script-thats-in-a-virtualenv/6354) 40 | - [Discussion](https://community.n8n.io/t/running-python-with-n8n/5715/7) 41 | - [Discussion](https://community.n8n.io/t/webhooks-do-not-work-on-a-public-domain/8558/16) 42 | 43 | Based on [no-official image](https://hub.docker.com/r/rrrlobert/n8n-debian) -------------------------------------------------------------------------------- /demo/docker-compose-local.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | n8n-python: 5 | image: naskio/n8n-python:latest-debian # use this if intended to use heavy python packages 6 | # image: naskio/n8n-python # alpine for light python packages 7 | # command: /bin/sh -c "n8n start" 8 | restart: always 9 | container_name: n8n-python 10 | environment: 11 | GENERIC_TIMEZONE: ${TIMEZONE} 12 | TZ: ${TIMEZONE} 13 | ports: 14 | - "5678:5678" 15 | volumes: 16 | - ./n8n_data:/home/node/.n8n 17 | - ./local-files:/data/files # by default workdir == /data 18 | - ./python_scripts:/data/py_scripts 19 | - ./requirements.txt:/data/requirements.txt -------------------------------------------------------------------------------- /demo/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | 3 | services: 4 | n8n-python: 5 | image: naskio/n8n-python 6 | # command: /bin/sh -c "sleep 5; n8n start" # Wait 5 seconds to start n8n to make sure that PostgreSQL is ready 7 | restart: always 8 | container_name: n8n-python 9 | expose: 10 | - 5678 11 | environment: 12 | NODE_ENV: production 13 | N8N_BASIC_AUTH_ACTIVE: true 14 | N8N_BASIC_AUTH_USER: ${N8N_BASIC_AUTH_USER} 15 | N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD} 16 | N8N_HOST: ${VIRTUAL_HOST} 17 | N8N_PORT: 5678 18 | N8N_PROTOCOL: https 19 | GENERIC_TIMEZONE: ${TIMEZONE} 20 | TZ: ${TIMEZONE} 21 | WEBHOOK_URL: https://${VIRTUAL_HOST}/ 22 | WEBHOOK_TUNNEL_URL: https://${VIRTUAL_HOST}/ 23 | VUE_APP_URL_BASE_API: https://${VIRTUAL_HOST}/ 24 | VIRTUAL_PORT: 5678 25 | VIRTUAL_HOST: ${VIRTUAL_HOST} 26 | LETSENCRYPT_HOST: ${VIRTUAL_HOST} 27 | LETSENCRYPT_EMAIL: ${WEBMASTER_EMAIL} 28 | DB_TYPE: postgresdb 29 | DB_POSTGRESDB_HOST: postgres 30 | DB_POSTGRESDB_PORT: 5432 31 | DB_POSTGRESDB_DATABASE: ${POSTGRES_DB} 32 | DB_POSTGRESDB_USER: ${POSTGRES_USER} 33 | DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD} 34 | volumes: 35 | - data:/home/node/.n8n 36 | - ./local-files:/data/files 37 | - ./python_scripts:/data/py_scripts 38 | - ./requirements.txt:/data/requirements.txt 39 | networks: 40 | - auto-reverse-proxy-global-network 41 | - postgres_service-network 42 | 43 | volumes: 44 | data: 45 | 46 | networks: 47 | auto-reverse-proxy-global-network: 48 | external: true 49 | postgres_service-network: 50 | external: true -------------------------------------------------------------------------------- /demo/local-files/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naskio/docker-n8n-python/260eb91debb6aee2223cd64e3884afe430cd2846/demo/local-files/.gitkeep -------------------------------------------------------------------------------- /demo/python_scripts/hello.py: -------------------------------------------------------------------------------- 1 | if __name__ == '__main__': 2 | print('Hello, world!') 3 | exit(0) 4 | -------------------------------------------------------------------------------- /demo/python_scripts/hello_faker.py: -------------------------------------------------------------------------------- 1 | from faker import Faker 2 | 3 | if __name__ == '__main__': 4 | fake = Faker() 5 | print(fake.name()) 6 | exit(0) 7 | -------------------------------------------------------------------------------- /demo/python_scripts/hello_naskpy.py: -------------------------------------------------------------------------------- 1 | from naskpy.main import hello_world 2 | 3 | if __name__ == '__main__': 4 | print(hello_world()) 5 | exit(0) 6 | -------------------------------------------------------------------------------- /demo/requirements.txt: -------------------------------------------------------------------------------- 1 | fire 2 | Faker 3 | numpy 4 | # doesn't support Python 3.10 yet 5 | pandas 6 | instaloader 7 | instapy 8 | pymongo 9 | mongoengine 10 | # naskpy 11 | -------------------------------------------------------------------------------- /images/n8n-debian/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nikolaik/python-nodejs:python3.10-nodejs18 2 | 3 | # changing user `pn` to `node` 4 | RUN usermod --login node --move-home --home /home/node pn 5 | RUN groupmod --new-name node pn 6 | 7 | ARG N8N_VERSION 8 | 9 | RUN if [ -z "$N8N_VERSION" ] ; then echo "The N8N_VERSION argument is missing!" ; exit 1; fi 10 | 11 | RUN \ 12 | apt-get update && \ 13 | apt-get -y install graphicsmagick gosu git 14 | 15 | # Install python requirements 16 | RUN mkdir /requirements 17 | COPY requirements.txt /requirements/requirements.txt 18 | RUN python -m pip install --upgrade pip setuptools wheel 19 | RUN pip install -r /requirements/requirements.txt 20 | 21 | # Set a custom user to not have n8n run as root 22 | USER root 23 | 24 | RUN npm_config_user=root npm install -g full-icu n8n@${N8N_VERSION} 25 | 26 | # Install n8n-nodes-python module 27 | RUN cd /usr/lib/node_modules/n8n && npm install n8n-nodes-python 28 | 29 | ENV NODE_ICU_DATA /usr/lib/node_modules/full-icu 30 | 31 | WORKDIR /data 32 | 33 | COPY docker-entrypoint.sh /docker-entrypoint.sh 34 | ENTRYPOINT ["/docker-entrypoint.sh"] 35 | 36 | EXPOSE 5678/tcp 37 | -------------------------------------------------------------------------------- /images/n8n-debian/README.md: -------------------------------------------------------------------------------- 1 | ## n8n - Debian Docker Image 2 | 3 | Dockerfile to build n8n with Debian. 4 | 5 | For information about how to run n8n with Docker check the generic 6 | [Docker-Readme](https://github.com/n8n-io/n8n/tree/master/docker/images/n8n/README.md) 7 | 8 | 9 | ``` 10 | docker build --build-arg N8N_VERSION= -t n8nio/n8n: . 11 | 12 | # For example: 13 | docker build --build-arg N8N_VERSION=0.43.0 -t n8nio/n8n:0.43.0-debian . 14 | ``` 15 | 16 | ``` 17 | docker run -it --rm \ 18 | --name n8n \ 19 | -p 5678:5678 \ 20 | n8nio/n8n:0.43.0-debian 21 | ``` 22 | -------------------------------------------------------------------------------- /images/n8n-debian/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -d /root/.n8n ] ; then 4 | chmod o+rx /root 5 | chown -R node /root/.n8n 6 | ln -s /root/.n8n /home/node/ 7 | fi 8 | 9 | if [ "$#" -gt 0 ]; then 10 | # Got started with arguments 11 | exec gosu node "$@" 12 | else 13 | # Got started without arguments 14 | exec gosu node n8n 15 | fi 16 | -------------------------------------------------------------------------------- /images/n8n/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nikolaik/python-nodejs:python3.10-nodejs18-alpine 2 | 3 | # changing user `pn` to `node` 4 | RUN deluser pn && rm -r /home/pn # delete: user + group 5 | RUN addgroup -g 1000 -S node && adduser -u 1000 -S node -G node -s /bin/sh # create: user + group 6 | 7 | ARG N8N_VERSION 8 | 9 | RUN if [ -z "$N8N_VERSION" ] ; then echo "The N8N_VERSION argument is missing!" ; exit 1; fi 10 | 11 | # Update everything and install needed dependencies 12 | RUN apk add --update graphicsmagick tzdata git tini su-exec 13 | 14 | # # Set a custom user to not have n8n run as root 15 | USER root 16 | 17 | # Install n8n and the also temporary all the packages 18 | # it needs to build it correctly. 19 | RUN apk --update add --virtual build-dependencies build-base ca-certificates && \ 20 | npm_config_user=root npm install -g full-icu n8n@${N8N_VERSION} && \ 21 | apk del build-dependencies \ 22 | && rm -rf /root /tmp/* /var/cache/apk/* && mkdir /root; 23 | 24 | # Install n8n-nodes-python module 25 | RUN cd /usr/local/lib/node_modules/n8n && npm install n8n-nodes-python 26 | 27 | # Install fonts 28 | RUN apk --no-cache add --virtual fonts msttcorefonts-installer fontconfig && \ 29 | update-ms-fonts && \ 30 | fc-cache -f && \ 31 | apk del fonts && \ 32 | find /usr/share/fonts/truetype/msttcorefonts/ -type l -exec unlink {} \; \ 33 | && rm -rf /root /tmp/* /var/cache/apk/* && mkdir /root 34 | 35 | # (note: use debian instead of alpine if you want to use Pandas or heavy libraries) 36 | # Install Python Development Tools (disabled) 37 | # RUN apk update && apk --no-cache add make automake gcc g++ subversion python3-dev 38 | # RUN apk update && apk --no-cache add musl-dev linux-headers g++ 39 | # RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/community" >> /etc/apk/repositories 40 | # RUN apk --no-cache --update-cache add gfortran build-base wget freetype-dev libpng-dev openblas-dev 41 | # RUN apk --no-cache --update-cache add wget libgfortran musl-dev linux-headers 42 | 43 | # Install python requirements 44 | RUN mkdir /requirements 45 | COPY requirements.txt /requirements/requirements.txt 46 | RUN python -m pip install --upgrade pip setuptools wheel 47 | RUN pip install -r /requirements/requirements.txt 48 | 49 | ENV NODE_ICU_DATA /usr/local/lib/node_modules/full-icu 50 | 51 | WORKDIR /data 52 | 53 | COPY docker-entrypoint.sh /docker-entrypoint.sh 54 | ENTRYPOINT ["tini", "--", "/docker-entrypoint.sh"] 55 | 56 | EXPOSE 5678/tcp 57 | -------------------------------------------------------------------------------- /images/n8n/README.md: -------------------------------------------------------------------------------- 1 | # n8n - Workflow Automation 2 | 3 | ![n8n.io - Workflow Automation](https://raw.githubusercontent.com/n8n-io/n8n/master/assets/n8n-logo.png) 4 | 5 | n8n is a free and open [fair-code](http://faircode.io) distributed node based Workflow Automation Tool. It can be 6 | self-hosted, easily extended, and so also used with internal tools. 7 | 8 | n8n.io - Screenshot 9 | 10 | ## Contents 11 | 12 | - [Demo](#demo) 13 | - [Available integrations](#available-integrations) 14 | - [Documentation](#documentation) 15 | - [Start n8n in Docker](#start-n8n-in-docker) 16 | - [Start with tunnel](#start-with-tunnel) 17 | - [Securing n8n](#securing-n8n) 18 | - [Persist data](#persist-data) 19 | - [Passing Sensitive Data via File](#passing-sensitive-data-via-file) 20 | - [Updating a Running docker-compose Instance](#updating-a-running-docker-compose-instance) 21 | - [Example Setup with Lets Encrypt](#example-setup-with-lets-encrypt) 22 | - [What does n8n mean and how do you pronounce it](#what-does-n8n-mean-and-how-do-you-pronounce-it) 23 | - [Support](#support) 24 | - [Jobs](#jobs) 25 | - [Upgrading](#upgrading) 26 | - [License](#license) 27 | 28 | ## Demo 29 | 30 | [:tv: A short demo (< 3 min)](https://www.youtube.com/watch?v=3w7xIMKLVAg) 31 | which shows how to create a simple workflow which automatically sends a new Slack notification every time a Github 32 | repository received or lost a star. 33 | 34 | ## Available integrations 35 | 36 | n8n has 200+ different nodes to automate workflows. The list can be found 37 | on: [https://n8n.io/nodes](https://n8n.io/nodes) 38 | 39 | ## Documentation 40 | 41 | The official n8n documentation can be found under: [https://docs.n8n.io](https://docs.n8n.io) 42 | 43 | Additional information and example workflows on the n8n.io website: [https://n8n.io](https://n8n.io) 44 | 45 | ## Start n8n in Docker 46 | 47 | ``` 48 | docker run -it --rm \ 49 | --name n8n \ 50 | -p 5678:5678 \ 51 | -v ~/.n8n:/home/node/.n8n \ 52 | n8nio/n8n 53 | ``` 54 | 55 | You can then access n8n by opening: 56 | [http://localhost:5678](http://localhost:5678) 57 | 58 | ## Start with tunnel 59 | 60 | > **WARNING**: This is only meant for local development and testing. Should not be used in production! 61 | 62 | To be able to use webhooks which all triggers of external services like Github rely on n8n has to be reachable from the 63 | web. To make that easy n8n has a special tunnel service (uses this 64 | code: [https://github.com/localtunnel/localtunnel](https://github.com/localtunnel/localtunnel)) which redirects requests 65 | from our servers to your local n8n instance. 66 | 67 | To use it simply start n8n with `--tunnel` 68 | 69 | ``` 70 | docker run -it --rm \ 71 | --name n8n \ 72 | -p 5678:5678 \ 73 | -v ~/.n8n:/home/node/.n8n \ 74 | n8nio/n8n \ 75 | n8n start --tunnel 76 | ``` 77 | 78 | ## Securing n8n 79 | 80 | By default n8n can be accessed by everybody. This is OK if you have it only running locally but if you deploy it on a 81 | server which is accessible from the web you have to make sure that n8n is protected! 82 | Right now we have very basic protection via basic-auth in place. It can be activated by setting the following 83 | environment variables: 84 | 85 | ``` 86 | N8N_BASIC_AUTH_ACTIVE=true 87 | N8N_BASIC_AUTH_USER= 88 | N8N_BASIC_AUTH_PASSWORD= 89 | ``` 90 | 91 | ## Persist data 92 | 93 | The workflow data gets by default saved in an SQLite database in the user folder (`/home/node/.n8n`). That folder also 94 | additionally contains the settings like webhook URL and encryption key. 95 | 96 | ``` 97 | docker run -it --rm \ 98 | --name n8n \ 99 | -p 5678:5678 \ 100 | -v ~/.n8n:/home/node/.n8n \ 101 | n8nio/n8n 102 | ``` 103 | 104 | ### Start with other Database 105 | 106 | By default n8n uses SQLite to save credentials, past executions and workflows. n8n however also supports PostgresDB, 107 | MySQL and MariaDB. To use them simply a few environment variables have to be set. 108 | 109 | It is important to still persist the data in the `/root/.n8n` folder. The reason is that it contains n8n user data. That 110 | is the name of the webhook 111 | (in case) the n8n tunnel gets used and even more important the encryption key for the credentials. If none gets found 112 | n8n creates automatically one on startup. In case credentials are already saved with a different encryption key it can 113 | not be used anymore as encrypting it is not possible anymore. 114 | 115 | #### Use with PostgresDB 116 | 117 | Replace the following placeholders with the actual data: 118 | 119 | - POSTGRES_DATABASE 120 | - POSTGRES_HOST 121 | - POSTGRES_PASSWORD 122 | - POSTGRES_PORT 123 | - POSTGRES_USER 124 | - POSTGRES_SCHEMA 125 | 126 | ``` 127 | docker run -it --rm \ 128 | --name n8n \ 129 | -p 5678:5678 \ 130 | -e DB_TYPE=postgresdb \ 131 | -e DB_POSTGRESDB_DATABASE= \ 132 | -e DB_POSTGRESDB_HOST= \ 133 | -e DB_POSTGRESDB_PORT= \ 134 | -e DB_POSTGRESDB_USER= \ 135 | -e DB_POSTGRESDB_SCHEMA= \ 136 | -e DB_POSTGRESDB_PASSWORD= \ 137 | -v ~/.n8n:/home/node/.n8n \ 138 | n8nio/n8n \ 139 | n8n start 140 | ``` 141 | 142 | A full working setup with docker-compose can be 143 | found [here](https://github.com/n8n-io/n8n/blob/master/docker/compose/withPostgres/README.md) 144 | 145 | #### Use with MySQL 146 | 147 | Replace the following placeholders with the actual data: 148 | 149 | - MYSQLDB_DATABASE 150 | - MYSQLDB_HOST 151 | - MYSQLDB_PASSWORD 152 | - MYSQLDB_PORT 153 | - MYSQLDB_USER 154 | 155 | ``` 156 | docker run -it --rm \ 157 | --name n8n \ 158 | -p 5678:5678 \ 159 | -e DB_TYPE=mysqldb \ 160 | -e DB_MYSQLDB_DATABASE= \ 161 | -e DB_MYSQLDB_HOST= \ 162 | -e DB_MYSQLDB_PORT= \ 163 | -e DB_MYSQLDB_USER= \ 164 | -e DB_MYSQLDB_PASSWORD= \ 165 | -v ~/.n8n:/home/node/.n8n \ 166 | n8nio/n8n \ 167 | n8n start 168 | ``` 169 | 170 | ## Passing Sensitive Data via File 171 | 172 | To avoid passing sensitive information via environment variables "_FILE" may be appended to some environment variables. 173 | It will then load the data from a file with the given name. That makes it possible to load data easily from Docker- and 174 | Kubernetes-Secrets. 175 | 176 | The following environment variables support file input: 177 | 178 | - DB_POSTGRESDB_DATABASE_FILE 179 | - DB_POSTGRESDB_HOST_FILE 180 | - DB_POSTGRESDB_PASSWORD_FILE 181 | - DB_POSTGRESDB_PORT_FILE 182 | - DB_POSTGRESDB_USER_FILE 183 | - DB_POSTGRESDB_SCHEMA_FILE 184 | - N8N_BASIC_AUTH_PASSWORD_FILE 185 | - N8N_BASIC_AUTH_USER_FILE 186 | 187 | ## Example Setup with Lets Encrypt 188 | 189 | A basic step by step example setup of n8n with docker-compose and Lets Encrypt is available on the 190 | [Server Setup](https://docs.n8n.io/#/server-setup) page. 191 | 192 | ## Updating a running docker-compose instance 193 | 194 | ``` 195 | # Pull down the latest version from dockerhub 196 | docker pull n8nio/n8n 197 | # Stop current setup 198 | sudo docker-compose stop 199 | # Delete it (will only delete the docker-containers, data is stored separately) 200 | sudo docker-compose rm 201 | # Then start it again 202 | sudo docker-compose up -d 203 | ``` 204 | 205 | ## Setting Timezone 206 | 207 | To define the timezone n8n should use, the environment variable `GENERIC_TIMEZONE` can be set. This gets used by for 208 | example the Cron-Node. Apart from that can also the timezone of the system be set separately. Which controls what some 209 | scripts and commands return like `$ date`. The system timezone can be set via the environment variable `TZ`. 210 | 211 | Example to use the same timezone for both: 212 | 213 | ``` 214 | docker run -it --rm \ 215 | --name n8n \ 216 | -p 5678:5678 \ 217 | -e GENERIC_TIMEZONE="Europe/Berlin" \ 218 | -e TZ="Europe/Berlin" \ 219 | n8nio/n8n 220 | ``` 221 | 222 | ## Build Docker-Image 223 | 224 | ``` 225 | docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 --build-arg N8N_VERSION= -t n8nio/n8n: . 226 | 227 | # For example: 228 | docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 --build-arg N8N_VERSION=0.114.0 -t n8nio/n8n:0.114.0 . 229 | ``` 230 | 231 | ## What does n8n mean and how do you pronounce it? 232 | 233 | **Short answer:** It means "nodemation" and it is pronounced as n-eight-n. 234 | 235 | **Long answer:** I get that question quite often (more often than I expected) 236 | so I decided it is probably best to answer it here. While looking for a good name for the project with a free domain I 237 | realized very quickly that all the good ones I could think of were already taken. So, in the end, I chose nodemation. " 238 | node-" in the sense that it uses a Node-View and that it uses Node.js and "-mation" for "automation" which is what the 239 | project is supposed to help with. However, I did not like how long the name was and I could not imagine writing 240 | something that long every time in the CLI. That is when I then ended up on 241 | "n8n". Sure does not work perfectly but does neither for Kubernetes (k8s) and did not hear anybody complain there. So I 242 | guess it should be ok. 243 | 244 | ## Support 245 | 246 | If you have problems or questions go to our forum, we will then try to help you asap: 247 | 248 | [https://community.n8n.io](https://community.n8n.io) 249 | 250 | ## Jobs 251 | 252 | If you are interested in working for n8n and so shape the future of the project check out 253 | our [job posts](https://apply.workable.com/n8n/) 254 | 255 | ## Upgrading 256 | 257 | Before you upgrade to the latest version make sure to check here if there are any breaking changes which concern you: 258 | [Breaking Changes](https://github.com/n8n-io/n8n/blob/master/packages/cli/BREAKING-CHANGES.md) 259 | 260 | ## License 261 | 262 | n8n is [fair-code](http://faircode.io) distributed under [**Apache 2.0 with Commons 263 | Clause**](https://github.com/n8n-io/n8n/blob/master/packages/cli/LICENSE.md) license 264 | 265 | Additional information about license can be found in the [FAQ](https://docs.n8n.io/#/faq?id=license) 266 | -------------------------------------------------------------------------------- /images/n8n/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ -d /root/.n8n ] ; then 4 | chmod o+rx /root 5 | chown -R node /root/.n8n 6 | ln -s /root/.n8n /home/node/ 7 | fi 8 | 9 | chown -R node /home/node 10 | 11 | if [ "$#" -gt 0 ]; then 12 | # Got started with arguments 13 | exec su-exec node "$@" 14 | else 15 | # Got started without arguments 16 | exec su-exec node n8n 17 | fi 18 | -------------------------------------------------------------------------------- /images/n8n/hooks/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | docker build --build-arg N8N_VERSION=$DOCKER_TAG -f $DOCKERFILE_PATH -t $IMAGE_NAME . 3 | -------------------------------------------------------------------------------- /release-versions/n8n-latest.txt: -------------------------------------------------------------------------------- 1 | 1.97.0 2 | --------------------------------------------------------------------------------