English/Japanese TeX Live examples in a Docker container.
$ docker-compose build
$ make test-english.pdf
$ make test-japanese.pdf
$ make clean| ** | |
| !docker-entrypoint.sh | 
| #!/usr/bin/env perl | |
| # https://ctan.org/pkg/latexmk | |
| $latex = 'uplatex -kanji=utf8 -synctex=1 -file-line-error -halt-on-error -interaction=nonstopmode %O %S'; | |
| $bibtex = 'upbibtex -kanji=utf8 %O %B'; | |
| $bibtex_use = 1.5; | |
| $dvipdf = 'dvipdfmx %O -o %D %S'; | 
| version: "3.8" | |
| services: | |
| texlive: | |
| build: . | |
| volumes: | |
| - .:/work:rw | |
| working_dir: /work | 
| #!/usr/bin/env bash | |
| set -e | |
| USERNAME=user | |
| GROUPNAME=group | |
| # UID is already set by bash and it's read-only. | |
| GID="$(id -g)" | |
| GETENT_PASSWD="$(getent passwd $UID || true)" | |
| GETENT_GROUP="$(getent group $GID || true)" | |
| if [ -n "$GETENT_GROUP" ]; then | |
| groupmod --new-name "$GROUPNAME" "$(echo $GETENT_GROUP | cut -d: -f1)" | |
| else | |
| groupadd --gid "$GID" "$GROUPNAME" | |
| fi | |
| if [ -n "$GETENT_PASSWD" ]; then | |
| # XXX: A user cannot change their name by theirselves... | |
| USERNAME="$(echo $GETENT_PASSWD | cut -d: -f1)" | |
| usermod --gid "$GID" "$USERNAME" | |
| else | |
| useradd --uid "$UID" --gid "$GID" --create-home "$USERNAME" | |
| fi | |
| usermod --append --group sudo "$USERNAME" | |
| sudo chmod u-s /usr/sbin/useradd /usr/sbin/groupadd /usr/sbin/usermod | |
| export HOME="$(getent passwd $USERNAME | cut -d: -f6)" | |
| if [ $# -eq 0 ]; then | |
| exec /bin/bash --login | |
| else | |
| exec "$@" | |
| fi | 
| { | |
| "folders": [ | |
| { | |
| "name": "root", | |
| "path": "." | |
| } | |
| ], | |
| "settings": { | |
| "latex-workshop.latex.tools": [ | |
| { | |
| "name": "build_pdf", | |
| "command": "make", | |
| "args": [ | |
| "%DOCFILE%.pdf" | |
| ] | |
| } | |
| ], | |
| "latex-workshop.latex.recipes": [ | |
| { | |
| "name": "Build PDF file", | |
| "tools": [ | |
| "build_pdf" | |
| ] | |
| } | |
| ] | |
| }, | |
| "extensions": { | |
| "recommendations": [ | |
| "james-yu.latex-workshop" | |
| ] | |
| } | |
| } | 
| FROM ubuntu:focal | |
| ARG DEBIAN_FRONTEND=noninteractive | |
| RUN apt-get update \ | |
| && apt-get upgrade --yes \ | |
| && apt-get install --yes --no-install-recommends \ | |
| sudo less nano ghostscript latexmk texlive-lang-japanese texlive-pictures \ | |
| texlive-science texlive-publishers \ | |
| && apt-get clean \ | |
| && rm --recursive --force /var/cache/apt/archives/* /var/lib/apt/lists/* \ | |
| && chmod u+s /usr/sbin/useradd /usr/sbin/groupadd \ | |
| /usr/sbin/usermod /usr/sbin/groupmod \ | |
| && echo "%sudo ALL=(ALL) NOPASSWD: ALL" >>"/etc/sudoers" | |
| COPY docker-entrypoint.sh / | |
| ENTRYPOINT ["/docker-entrypoint.sh"] | 
| .PHONY: all | |
| all: | |
| DOCKER_COMPOSE ?= docker-compose | |
| DOCKER_COMPOSE_SERVICE ?= texlive | |
| DOCKER_COMPOSE_OPTIONS := --rm --user "$(shell id -u):$(shell id -g)" | |
| DOCKER_COMPOSE_RUN := $(DOCKER_COMPOSE) run $(DOCKER_COMPOSE_OPTIONS) \ | |
| "$(DOCKER_COMPOSE_SERVICE)" | |
| LATEXMK ?= latexmk | |
| LATEXMK_OPTIONS := -r .latexmkrc | |
| test-english.pdf: LATEXMK_OPTIONS += -pdf | |
| test-japanese.pdf: LATEXMK_OPTIONS += -pdfdvi | |
| %.pdf: %.tex force-phony | |
| $(DOCKER_COMPOSE_RUN) $(LATEXMK) $(LATEXMK_OPTIONS) "$<" | |
| .PHONY: clean | |
| clean: | |
| $(DOCKER_COMPOSE_RUN) $(LATEXMK) $(LATEXMK_OPTIONS) -C | |
| .PHONY: shell | |
| shell: | |
| $(DOCKER_COMPOSE_RUN) | |
| .PHONY: force-phony | 
| \documentclass[a4paper, 11pt]{article} | |
| \begin{document} | |
| \title{Title} | |
| \author{Author Name} | |
| \maketitle | |
| \abstract{ | |
| Abstract. | |
| } | |
| \section{Section} | |
| The quick brown fox jumped over the lazy dog. | |
| \end{document} | 
| \documentclass[a4j, 11pt]{ujarticle} | |
| \usepackage[ipaex, jis2004]{pxchfon} | |
| \begin{document} | |
| \title{タイトル} | |
| \author{著 者} | |
| \maketitle | |
| \abstract{ | |
| 概要 | |
| } | |
| \section{章} | |
| あいうえお | |
| \end{document} |