├── .circleci └── config.yml ├── .gitignore ├── .idea ├── .gitignore ├── libreoffice-lambda-base-image.iml ├── misc.xml ├── modules.xml └── vcs.xml ├── Dockerfile.node16-x86_64 ├── Dockerfile.node18-x86_64 ├── Dockerfile.node20-x86_64 ├── Dockerfile.python3_12-x86_64 ├── LICENSE ├── README.md └── renovate.json /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | 3 | orbs: 4 | aws-cli: circleci/aws-cli@4.1.3 5 | aws-ecr: circleci/aws-ecr@9.1.0 6 | docker: circleci/docker@2.1.3 7 | 8 | parameters: 9 | node_image_tag: 10 | type: string 11 | default: '7.6-node20-x86_64' 12 | python_image_tag: 13 | type: string 14 | default: '7.6-python3.12-x86_64' 15 | 16 | jobs: 17 | build_node: 18 | executor: 'aws-ecr/default' 19 | steps: 20 | - checkout 21 | - aws-ecr/build_image: 22 | dockerfile: Dockerfile.node20-x86_64 23 | no_output_timeout: 10m 24 | tag: << pipeline.parameters.node_image_tag >> 25 | region: ${AWS_DEFAULT_REGION} 26 | skip_when_tags_exist: false 27 | push_image: false 28 | repo: lambda-libreoffice-base 29 | 30 | build_python: 31 | executor: 'aws-ecr/default' 32 | steps: 33 | - checkout 34 | - aws-ecr/build_image: 35 | dockerfile: Dockerfile.python3_12-x86_64 36 | no_output_timeout: 10m 37 | tag: << pipeline.parameters.python_image_tag >> 38 | region: ${AWS_DEFAULT_REGION} 39 | skip_when_tags_exist: false 40 | push_image: false 41 | repo: lambda-libreoffice-base 42 | 43 | workflows: 44 | build_and_push_images: 45 | jobs: 46 | - docker/hadolint: 47 | dockerfiles: Dockerfile.node20-x86_64,Dockerfile.python3_12-x86_64 48 | executor-class: medium 49 | ignore-rules: 'DL3033,SC3040,DL4006,DL3003,DL3032,SC2015,DL3041,SC2035' 50 | 51 | - build_node: 52 | context: prod-us 53 | filters: 54 | branches: 55 | only: 56 | - /feature\/.*/ 57 | 58 | - build_python: 59 | context: prod-us 60 | filters: 61 | branches: 62 | only: 63 | - /feature\/.*/ 64 | 65 | - aws-ecr/build_and_push_image: 66 | name: push_node_image 67 | auth: 68 | - aws-cli/setup 69 | context: prod-us 70 | executor: aws-ecr/default 71 | create_repo: false 72 | repo: lambda-libreoffice-base 73 | tag: << pipeline.parameters.node_image_tag >> 74 | dockerfile: Dockerfile.node20-x86_64 75 | no_output_timeout: 20m 76 | public_registry: true 77 | push_image: true 78 | region: ${AWS_DEFAULT_REGION} 79 | repo_scan_on_push: true 80 | skip_when_tags_exist: false 81 | account_id: AWS_ACCOUNT_ID 82 | public_registry_alias: shelf 83 | filters: 84 | branches: 85 | only: 86 | - master 87 | 88 | - aws-ecr/build_and_push_image: 89 | name: push_python_image 90 | auth: 91 | - aws-cli/setup 92 | context: prod-us 93 | executor: aws-ecr/default 94 | create_repo: false 95 | repo: lambda-libreoffice-base 96 | tag: << pipeline.parameters.python_image_tag >> 97 | dockerfile: Dockerfile.python3_12-x86_64 98 | no_output_timeout: 20m 99 | public_registry: true 100 | push_image: true 101 | region: ${AWS_DEFAULT_REGION} 102 | repo_scan_on_push: true 103 | skip_when_tags_exist: false 104 | account_id: AWS_ACCOUNT_ID 105 | public_registry_alias: shelf 106 | filters: 107 | branches: 108 | only: 109 | - master 110 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .aider* 2 | .DS_Store -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | -------------------------------------------------------------------------------- /.idea/libreoffice-lambda-base-image.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /Dockerfile.node16-x86_64: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:16-x86_64 2 | 3 | # binutils is needed for "strip" command 4 | RUN yum install \ 5 | tar \ 6 | gzip \ 7 | libdbusmenu.x86_64 \ 8 | libdbusmenu-gtk2.x86_64 \ 9 | libSM.x86_64 \ 10 | xorg-x11-fonts-* \ 11 | google-noto-sans-cjk-fonts.noarch \ 12 | binutils.x86_64 \ 13 | -y && \ 14 | yum clean all 15 | 16 | RUN set -xo pipefail && \ 17 | curl "https://ftp.halifax.rwth-aachen.de/tdf/libreoffice/stable/7.4.3/rpm/x86_64/LibreOffice_7.4.3_Linux_x86-64_rpm.tar.gz" | tar -xz 18 | 19 | RUN cd LibreOffice_7.4.3.2_Linux_x86-64_rpm/RPMS && \ 20 | yum install *.rpm -y && \ 21 | rm -rf /var/task/LibreOffice_7.4.0* && \ 22 | cd /opt/libreoffice7.4/ && \ 23 | strip ./**/* || true 24 | 25 | ENV HOME=/tmp 26 | 27 | # Trigger dummy run to generate bootstrap files to improve cold start performance 28 | RUN touch /tmp/test.txt \ 29 | && cd /tmp \ 30 | && libreoffice7.4 --headless --invisible --nodefault --view \ 31 | --nolockcheck --nologo --norestore --convert-to pdf \ 32 | --outdir /tmp /tmp/test.txt \ 33 | && rm /tmp/test.* 34 | 35 | -------------------------------------------------------------------------------- /Dockerfile.node18-x86_64: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:18-x86_64 2 | 3 | # binutils is needed for "strip" command 4 | RUN yum install \ 5 | tar \ 6 | gzip \ 7 | libdbusmenu.x86_64 \ 8 | libdbusmenu-gtk2.x86_64 \ 9 | libSM.x86_64 \ 10 | xorg-x11-fonts-* \ 11 | google-noto-sans-cjk-fonts.noarch \ 12 | binutils.x86_64 \ 13 | -y && \ 14 | yum clean all 15 | 16 | RUN set -xo pipefail && \ 17 | curl "https://mirrors.ukfast.co.uk/sites/documentfoundation.org/tdf/libreoffice/stable/7.6.5/rpm/x86_64/LibreOffice_7.6.5_Linux_x86-64_rpm.tar.gz" | tar -xz 18 | 19 | RUN cd LibreOffice_7.6.5.2_Linux_x86-64_rpm/RPMS && \ 20 | yum install *.rpm -y && \ 21 | rm -rf /var/task/LibreOffice_7.6.5.2* && \ 22 | cd /opt/libreoffice7.6/ && \ 23 | strip ./**/* || true 24 | 25 | ENV HOME=/tmp 26 | 27 | # Trigger dummy run to generate bootstrap files to improve cold start performance 28 | RUN touch /tmp/test.txt \ 29 | && cd /tmp \ 30 | && libreoffice7.6 --headless --invisible --nodefault --view \ 31 | --nolockcheck --nologo --norestore --convert-to pdf \ 32 | --outdir /tmp /tmp/test.txt \ 33 | && rm /tmp/test.* 34 | -------------------------------------------------------------------------------- /Dockerfile.node20-x86_64: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:20-x86_64 2 | 3 | ENV PATH=/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin 4 | 5 | # Configure linker to correctly point to libraries 6 | ENV LD_LIBRARY_PATH="/usr/lib:/usr/lib64" 7 | RUN dnf install -y xorg-x11-fonts-* libSM.x86_64 libXinerama-devel google-noto-sans-cjk-fonts binutils tar gzip xz \ 8 | openssl nss-tools dbus-libs cups-libs && dnf clean all 9 | 10 | RUN cp /lib64/libssl.so.3 /lib64/libssl3.so 11 | 12 | RUN mkdir ~/libre && cd ~/libre && curl -s -L https://download.documentfoundation.org/libreoffice/stable/7.6.7/rpm/x86_64/LibreOffice_7.6.7_Linux_x86-64_rpm.tar.gz | tar xvz 13 | 14 | RUN cd ~/libre/LibreOffice_7.6.7.2_Linux_x86-64_rpm/RPMS/ && rpm -Uvh *.rpm && rm -fr ~/libre 15 | 16 | ENV HOME=/tmp 17 | 18 | # Trigger dummy run to generate bootstrap files to improve cold start performance 19 | RUN touch /tmp/test.txt \ 20 | && cd /tmp \ 21 | && libreoffice7.6 --headless --invisible --nodefault --view \ 22 | --nolockcheck --nologo --norestore --convert-to pdf \ 23 | --outdir /tmp /tmp/test.txt \ 24 | && rm /tmp/test.* 25 | -------------------------------------------------------------------------------- /Dockerfile.python3_12-x86_64: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/python:3.12-x86_64 2 | 3 | ENV PATH=/var/lang/bin:/usr/local/bin:/usr/bin/:/bin:/opt/bin 4 | 5 | # Configure linker to correctly point to libraries 6 | ENV LD_LIBRARY_PATH="/usr/lib:/usr/lib64" 7 | RUN dnf install -y xorg-x11-fonts-* libSM.x86_64 libXinerama-devel google-noto-sans-cjk-fonts binutils tar gzip xz \ 8 | openssl nss-tools dbus-libs cups-libs && dnf clean all 9 | 10 | RUN cp /lib64/libssl.so.3 /lib64/libssl3.so 11 | 12 | RUN mkdir ~/libre && cd ~/libre && curl -s -L https://downloadarchive.documentfoundation.org/libreoffice/old/7.6.7.2/rpm/x86_64/LibreOffice_7.6.7.2_Linux_x86-64_rpm.tar.gz | tar xvz 13 | 14 | RUN cd ~/libre/LibreOffice_7.6.7.2_Linux_x86-64_rpm/RPMS/ && rpm -Uvh *.rpm && rm -fr ~/libre 15 | 16 | ENV HOME=/tmp 17 | 18 | # Trigger dummy run to generate bootstrap files to improve cold start performance 19 | RUN touch /tmp/test.txt \ 20 | && cd /tmp \ 21 | && libreoffice7.6 --headless --invisible --nodefault --view \ 22 | --nolockcheck --nologo --norestore --convert-to pdf \ 23 | --outdir /tmp /tmp/test.txt \ 24 | && rm /tmp/test.* 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Shelf 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 | # LibreOffice Lambda Base Image 2 | 3 | > LibreOffice 7.6 base image for Lambda Node.js 20 x86_64 and Python 3.12 x86_64 to be used as a base for your own images. 4 | 5 | ## Usage 6 | 7 | Includes CJK fonts support! 877 MB in size. 8 | 9 | [Blog post announcement](https://vladholubiev.medium.com/running-libreoffice-in-aws-lambda-2022-edition-open-sourced-9bb0028911d8) 10 | 11 | > Set environment variable `HOME=/tmp` in your Lambda function. 12 | 13 | ### Node.js 20 x86_64 14 | 15 | ```Dockerfile 16 | FROM public.ecr.aws/shelf/lambda-libreoffice-base:7.6-node20-x86_64 17 | 18 | COPY handler.js ${LAMBDA_TASK_ROOT}/ 19 | 20 | CMD [ "handler.handler" ] 21 | ``` 22 | 23 | And your `handler.js`: 24 | 25 | ```javascript 26 | const {execSync} = require('child_process'); 27 | const {writeFileSync} = require('fs'); 28 | 29 | module.exports.handler = () => { 30 | writeFileSync('/tmp/hello.txt', Buffer.from('Hello World!')); 31 | 32 | execSync(` 33 | cd /tmp 34 | libreoffice7.6 --headless --invisible --nodefault --view --nolockcheck --nologo --norestore --convert-to pdf --outdir /tmp ./hello.txt 35 | `); 36 | }; 37 | ``` 38 | 39 | ### Python 3.12 x86_64 40 | 41 | ```Dockerfile 42 | FROM public.ecr.aws/shelf/lambda-libreoffice-base:7.6-python3.12-x86_64 43 | 44 | COPY handler.py ${LAMBDA_TASK_ROOT}/ 45 | 46 | CMD [ "handler.handler" ] 47 | ``` 48 | 49 | And your `handler.py`: 50 | 51 | ```python 52 | import subprocess 53 | 54 | def handler(event, context): 55 | with open('/tmp/hello.txt', 'w') as f: 56 | f.write('Hello World!') 57 | 58 | subprocess.run([ 59 | 'libreoffice7.6', 60 | '--headless', 61 | '--invisible', 62 | '--nodefault', 63 | '--view', 64 | '--nolockcheck', 65 | '--nologo', 66 | '--norestore', 67 | '--convert-to', 68 | 'pdf', 69 | '--outdir', 70 | '/tmp', 71 | '/tmp/hello.txt' 72 | ], check=True) 73 | 74 | ``` 75 | 76 | ## Troubleshooting 77 | 78 |
79 | Command failed: Fatal Error: The application cannot be started. User installation could not be completed. 80 | 81 | Set environment variable `HOME=/tmp` in your Lambda function. 82 |
83 | 84 | ## Available Tags & Versions 85 | 86 | * `7.6-node20-x86_64` 87 | * `7.6-python3.12-x86_64` 88 | * `7.6-node18-x86_64` 89 | * `7.4-node16-x86_64` 90 | * `7.3-node16-x86_64` 91 | 92 | ## See Also 93 | 94 | * [aws-lambda-libreoffice](https://github.com/shelfio/aws-lambda-libreoffice) - utility to work with Docker version of LibreOffice in Lambda 95 | * [libreoffica-lambda-layer](https://github.com/shelfio/libreoffice-lambda-layer) - deprecated; this is the predecessor of this image 96 | 97 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["github>shelfio/renovate-config-public"], 3 | "labels": ["backend"] 4 | } 5 | --------------------------------------------------------------------------------