Come abbiamo visto in altri articoli, e’ possibile usare il progetto FN con diversi linguaggi di programmazione tramite immagini container predefinite. I linguaggi ufficialmente supportati sono:
- go
- java
- Node.js
- ruby
- Python
- C#
Puoi farlo con la direttiva runtime, ad esempio:
fn init --runtime python test
Il comando produce un file func.yaml di questo tipo:
| |
In alcuni casi, pero’, le immagini predefinite non sono sufficienti: puo’ servire supporto extra per un linguaggio, driver aggiuntivi o strumenti non presenti.
Per risolvere il problema possiamo usare un Dockerfile e un ambiente custom. Possiamo estendere l’immagine FN di base oppure partire da un’immagine completamente diversa.
Come demo ho creato questo esempio
. In particolare il file func.yaml e’ il seguente:
1schema_version: 20180708
2name: customimage
3version: 0.0.1
4runtime: docker
5memory: 256In questo modo FN usa un Dockerfile locale, salvato allo stesso livello, per creare l’ambiente di esecuzione della funzione. Nell’esempio il Dockerfile e’ questo:
1FROM fnproject/python:3.9
2WORKDIR /function
3ADD requirements.txt /function/
4
5RUN pip3 install --target /python/ --no-cache --no-cache-dir -r requirements.txt &&\
6 rm -fr ~/.cache/pip /tmp* requirements.txt func.yaml Dockerfile .venv &&\
7 chmod -R o+r /python
8
9# install Oracle database client
10RUN microdnf install oracle-instantclient-release-el8 &&\
11 microdnf install oracle-instantclient-basic &&\
12 microdnf clean all
13
14ADD . /function/
15
16RUN chmod -R o+r /function
17
18ENV PYTHONPATH=/function:/python
19
20ENTRYPOINT ["/python/bin/fdk", "/function/func.py", "handler"]In questo Dockerfile abbiamo personalizzato l’immagine ufficiale Python 3.9 con il client database Oracle.
E’ possibile fare test locali senza distribuire ogni volta l’immagine nel repository remoto usando l’opzione --local nella fase di deploy:
fn deploy --app app --local
Eseguendo il server FN in locale sara’ possibile eseguire il codice della funzione come su OCI, ma localmente.
Avvia quindi in un terminale separato l’istanza del server FN:
fn start
E in un altro terminale il classico comando di invocazione, per esempio:
echo -n '{"name": "Oracle"}' | fn invoke app hello
