diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index ed74c84..d95d50a 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -1,6 +1,7 @@ # Run in local ``` -make build +make clean +FLAVOR=lxqt ARCH=amd64 IMAGE=ubuntu:18.04 make build make run ``` diff --git a/Dockerfile.amd64 b/Dockerfile.amd64 index 409db20..b2e0b36 100644 --- a/Dockerfile.amd64 +++ b/Dockerfile.amd64 @@ -1,30 +1,47 @@ +# Built with arch: amd64 flavor: lxde image: ubuntu:18.04 localbuild: 1 +# ################################################################################ # base system ################################################################################ -ARG image=ubuntu:18.04 -FROM $image as system -ARG localbuild -RUN echo "LOCALBUILD=$localbuild" -RUN if [ "x$localbuild" != "x" ]; then sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; fi +FROM ubuntu:18.04 as system + + + +RUN sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; + # built-in packages -RUN apt-get update \ - && apt-get install -y --no-install-recommends software-properties-common curl apache2-utils \ - && apt-get update \ - && add-apt-repository -y ppa:fcwu-tw/apps \ - && apt-get install -y --no-install-recommends --allow-unauthenticated \ - supervisor nginx sudo vim-tiny net-tools zenity xz-utils \ +ENV DEBIAN_FRONTEND noninteractive +RUN apt update \ + && apt install -y --no-install-recommends software-properties-common curl apache2-utils \ + && apt update \ + && apt install -y --no-install-recommends --allow-unauthenticated \ + supervisor nginx sudo net-tools zenity xz-utils \ dbus-x11 x11-utils alsa-utils \ mesa-utils libgl1-mesa-dri \ - lxde xvfb x11vnc=0.9.16-1 \ - gtk2-engines-murrine gnome-themes-standard gtk2-engines-pixbuf gtk2-engines-murrine arc-theme \ - firefox chromium-browser \ - ttf-ubuntu-font-family ttf-wqy-zenhei \ - && add-apt-repository -r ppa:fcwu-tw/apps \ - && apt-get autoclean \ - && apt-get autoremove \ + && apt autoclean -y \ + && apt autoremove -y \ && rm -rf /var/lib/apt/lists/* +# install debs error if combine together +RUN add-apt-repository -y ppa:fcwu-tw/apps \ + && apt update \ + && apt install -y --no-install-recommends --allow-unauthenticated \ + xvfb x11vnc=0.9.16-1 \ + vim-tiny firefox chromium-browser ttf-ubuntu-font-family ttf-wqy-zenhei \ + && add-apt-repository -r ppa:fcwu-tw/apps \ + && apt autoclean -y \ + && apt autoremove -y \ + && rm -rf /var/lib/apt/lists/* + +RUN apt update \ + && apt install -y --no-install-recommends --allow-unauthenticated \ + lxde gtk2-engines-murrine gnome-themes-standard gtk2-engines-pixbuf gtk2-engines-murrine arc-theme \ + && apt autoclean -y \ + && apt autoremove -y \ + && rm -rf /var/lib/apt/lists/* + + # Additional packages require ~600MB # libreoffice pinta language-pack-zh-hant language-pack-gnome-zh-hant firefox-locale-zh-hant libreoffice-l10n-zh-tw @@ -54,13 +71,14 @@ RUN apt-get update \ ################################################################################ # builder ################################################################################ -FROM ubuntu:16.04 as builder +FROM ubuntu:18.04 as builder + + +RUN sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; -ARG localbuild -RUN if [ "x$localbuild" != "x" ]; then sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; fi RUN apt-get update \ - && apt-get install -y --no-install-recommends curl ca-certificates + && apt-get install -y --no-install-recommends curl ca-certificates gnupg patch # nodejs RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - \ @@ -79,6 +97,7 @@ RUN cd /src/web \ && npm run build + ################################################################################ # merge ################################################################################ diff --git a/Dockerfile.armhf b/Dockerfile.armhf index 92e2b20..8ee92b2 100644 --- a/Dockerfile.armhf +++ b/Dockerfile.armhf @@ -1,21 +1,27 @@ -FROM ubuntu:18.04 as amd64 -RUN apt update && apt install -y qemu-user-static - +# Built with arch: armhf flavor: lxde image: ubuntu:18.04 localbuild: 1 +# ################################################################################ # base system ################################################################################ + +# qemu helper for arm build +FROM ubuntu:18.04 as amd64 +RUN apt update && apt install -y qemu-user-static FROM arm32v7/ubuntu:18.04 as system - COPY --from=amd64 /usr/bin/qemu-arm-static /usr/bin/ -ARG localbuild -RUN if [ "x$localbuild" != "x" ]; then sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; fi + + +RUN sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; + + +# built-in packages ENV DEBIAN_FRONTEND noninteractive RUN apt update \ && apt install -y --no-install-recommends software-properties-common curl apache2-utils \ && apt update \ && apt install -y --no-install-recommends --allow-unauthenticated \ - supervisor nginx sudo vim-tiny net-tools zenity xz-utils \ + supervisor nginx sudo net-tools zenity xz-utils \ dbus-x11 x11-utils alsa-utils \ mesa-utils libgl1-mesa-dri \ && apt autoclean -y \ @@ -25,30 +31,32 @@ RUN apt update \ RUN add-apt-repository -y ppa:fcwu-tw/apps \ && apt update \ && apt install -y --no-install-recommends --allow-unauthenticated \ - lxde xvfb x11vnc=0.9.16-1 \ - firefox chromium-browser \ - ttf-ubuntu-font-family ttf-wqy-zenhei \ + xvfb x11vnc=0.9.16-1 \ + vim-tiny firefox chromium-browser ttf-ubuntu-font-family ttf-wqy-zenhei \ && add-apt-repository -r ppa:fcwu-tw/apps \ && apt autoclean -y \ && apt autoremove -y \ && rm -rf /var/lib/apt/lists/* + RUN apt update \ && apt install -y --no-install-recommends --allow-unauthenticated \ - gtk2-engines-murrine gnome-themes-standard gtk2-engines-pixbuf gtk2-engines-murrine arc-theme \ + lxde gtk2-engines-murrine gnome-themes-standard gtk2-engines-pixbuf gtk2-engines-murrine arc-theme \ && apt autoclean -y \ && apt autoremove -y \ && rm -rf /var/lib/apt/lists/* + + # Additional packages require ~600MB # libreoffice pinta language-pack-zh-hant language-pack-gnome-zh-hant firefox-locale-zh-hant libreoffice-l10n-zh-tw -# tini for subreap +# tini for subreap ARG TINI_VERSION=v0.18.0 -ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-armhf /bin/tini +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /bin/tini RUN chmod +x /bin/tini # ffmpeg -#RUN mkdir -p /usr/local/ffmpeg \ -# && curl -sSL https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-64bit-static.tar.xz | tar xJvf - -C /usr/local/ffmpeg/ --strip 1 +RUN mkdir -p /usr/local/ffmpeg \ + && curl -sSL https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz | tar xJvf - -C /usr/local/ffmpeg/ --strip 1 # python library COPY image/usr/local/lib/web/backend/requirements.txt /tmp/ @@ -69,8 +77,9 @@ RUN apt-get update \ ################################################################################ FROM ubuntu:18.04 as builder -ARG localbuild -RUN if [ "x$localbuild" != "x" ]; then sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; fi + +RUN sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; + RUN apt-get update \ && apt-get install -y --no-install-recommends curl ca-certificates gnupg patch @@ -90,6 +99,8 @@ COPY web /src/web RUN cd /src/web \ && yarn \ && npm run build + + RUN cd /src/web/dist/static/novnc && patch -p0 < /src/web/novnc-armhf-1.patch @@ -106,5 +117,5 @@ EXPOSE 80 WORKDIR /root ENV HOME=/home/ubuntu \ SHELL=/bin/bash -HEALTHCHECK --interval=30s --timeout=5s CMD curl --fail http://127.0.0.1/api/health +HEALTHCHECK --interval=30s --timeout=5s CMD curl --fail http://127.0.0.1:6079/api/health ENTRYPOINT ["/startup.sh"] diff --git a/Dockerfile.j2 b/Dockerfile.j2 new file mode 100644 index 0000000..1f83e1e --- /dev/null +++ b/Dockerfile.j2 @@ -0,0 +1,130 @@ +# Built with arch: {{ arch }} flavor: {{ flavor }} image: {{ image }} localbuild: {{localbuild }} +# +################################################################################ +# base system +################################################################################ +{%if arch == "amd64"%} +FROM {{image}} as system +{%elif arch == "armhf"%} +# qemu helper for arm build +FROM {{image}} as amd64 +RUN apt update && apt install -y qemu-user-static +FROM arm32v7/{{image}} as system +COPY --from=amd64 /usr/bin/qemu-arm-static /usr/bin/ +{%endif%} + +{% if localbuild %} +RUN sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; +{% endif %} + +# built-in packages +ENV DEBIAN_FRONTEND noninteractive +RUN apt update \ + && apt install -y --no-install-recommends software-properties-common curl apache2-utils \ + && apt update \ + && apt install -y --no-install-recommends --allow-unauthenticated \ + supervisor nginx sudo net-tools zenity xz-utils \ + dbus-x11 x11-utils alsa-utils \ + mesa-utils libgl1-mesa-dri \ + && apt autoclean -y \ + && apt autoremove -y \ + && rm -rf /var/lib/apt/lists/* +# install debs error if combine together +RUN add-apt-repository -y ppa:fcwu-tw/apps \ + && apt update \ + && apt install -y --no-install-recommends --allow-unauthenticated \ + xvfb x11vnc=0.9.16-1 \ + {%for package in addon_packages%}{{package}} {%endfor%} \ + && add-apt-repository -r ppa:fcwu-tw/apps \ + && apt autoclean -y \ + && apt autoremove -y \ + && rm -rf /var/lib/apt/lists/* +{%if desktop == "lxde" %} +RUN apt update \ + && apt install -y --no-install-recommends --allow-unauthenticated \ + lxde gtk2-engines-murrine gnome-themes-standard gtk2-engines-pixbuf gtk2-engines-murrine arc-theme \ + && apt autoclean -y \ + && apt autoremove -y \ + && rm -rf /var/lib/apt/lists/* +{%endif%} +{%if desktop == "lxqt" %} +RUN apt update \ + && apt install -y --no-install-recommends --allow-unauthenticated \ + lxqt openbox gtk2-engines-murrine gnome-themes-standard gtk2-engines-pixbuf arc-theme \ + && apt autoclean -y \ + && apt autoremove -y \ + && rm -rf /var/lib/apt/lists/* +{%endif%} +# Additional packages require ~600MB +# libreoffice pinta language-pack-zh-hant language-pack-gnome-zh-hant firefox-locale-zh-hant libreoffice-l10n-zh-tw + +# tini for subreap +ARG TINI_VERSION=v0.18.0 +ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /bin/tini +RUN chmod +x /bin/tini + +# ffmpeg +RUN mkdir -p /usr/local/ffmpeg \ + && curl -sSL https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz | tar xJvf - -C /usr/local/ffmpeg/ --strip 1 + +# python library +COPY image/usr/local/lib/web/backend/requirements.txt /tmp/ +RUN apt-get update \ + && dpkg-query -W -f='${Package}\n' > /tmp/a.txt \ + && apt-get install -y python-pip python-dev build-essential \ + && pip install setuptools wheel && pip install -r /tmp/requirements.txt \ + && dpkg-query -W -f='${Package}\n' > /tmp/b.txt \ + && apt-get remove -y `diff --changed-group-format='%>' --unchanged-group-format='' /tmp/a.txt /tmp/b.txt | xargs` \ + && apt-get autoclean -y \ + && apt-get autoremove -y \ + && rm -rf /var/lib/apt/lists/* \ + && rm -rf /var/cache/apt/* /tmp/a.txt /tmp/b.txt + + +################################################################################ +# builder +################################################################################ +FROM {{image}} as builder + +{% if localbuild %} +RUN sed -i 's#http://archive.ubuntu.com/#http://tw.archive.ubuntu.com/#' /etc/apt/sources.list; +{% endif %} + +RUN apt-get update \ + && apt-get install -y --no-install-recommends curl ca-certificates gnupg patch + +# nodejs +RUN curl -sL https://deb.nodesource.com/setup_8.x | bash - \ + && apt-get install -y nodejs + +# yarn +RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \ + && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \ + && apt-get update \ + && apt-get install -y yarn + +# build frontend +COPY web /src/web +RUN cd /src/web \ + && yarn \ + && npm run build + +{%if arch == "armhf"%} +RUN cd /src/web/dist/static/novnc && patch -p0 < /src/web/novnc-armhf-1.patch +{%endif%} + +################################################################################ +# merge +################################################################################ +FROM system +LABEL maintainer="fcwu.tw@gmail.com" + +COPY --from=builder /src/web/dist/ /usr/local/lib/web/frontend/ +COPY image / + +EXPOSE 80 +WORKDIR /root +ENV HOME=/home/ubuntu \ + SHELL=/bin/bash +HEALTHCHECK --interval=30s --timeout=5s CMD curl --fail http://127.0.0.1:6079/api/health +ENTRYPOINT ["/startup.sh"] diff --git a/Makefile b/Makefile index 6d07a07..078c5e7 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,13 @@ REPO ?= dorowu/ubuntu-desktop-lxde-vnc TAG ?= latest IMAGE ?= ubuntu:18.04 LOCALBUILD ?= 1 +FLAVOR ?= lxde +ARCH ?= amd64 -build: - docker build -t $(REPO):$(TAG) --build-arg localbuild=$(LOCALBUILD) --build-arg image=$(IMAGE) . +templates = Dockerfile image/etc/supervisor/conf.d/supervisord.conf + +build: $(templates) + docker build -t $(REPO):$(TAG) . run: docker run --rm \ @@ -27,3 +31,14 @@ gen-ssl: mkdir -p ssl openssl req -x509 -nodes -days 365 -newkey rsa:2048 \ -keyout ssl/nginx.key -out ssl/nginx.crt + +clean: + rm -f $(templates) + +%: %.j2 flavors/$(FLAVOR).yml + docker run -v $(shell pwd):/data vikingco/jinja2cli \ + -D flavor=$(FLAVOR) \ + -D image=$(IMAGE) \ + -D localbuild=$(LOCALBUILD) \ + -D arch=$(ARCH) \ + $< flavors/$(FLAVOR).yml > $@ || rm $@ diff --git a/README.md b/README.md index c3344b3..d1c5c47 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,20 @@ Following is the screen capture of these operations. Turn on your sound at the e [![demo video](http://img.youtube.com/vi/Kv9FGClP1-k/0.jpg)](http://www.youtube.com/watch?v=Kv9FGClP1-k) +Generate Dockerfile from jinja template +------------------- + +Dockerfile and configuration can be generated by template. + +- arch: one of `amd64` or `armhf` +- flavor: refer to file in flavor/`flavor`.yml +- image: base image +- localbuild: build from local that will use mirror site if set +- desktop: desktop environment which is set in flavor +- addon_package: Debian package to be installed which is set in flavor + +Dockerfile and configuration are re-generate if they do not exist. Or you may force to re-generate by removing them with the command `make clean`. + Troubleshooting and FAQ ================== diff --git a/flavors/lxde.yml b/flavors/lxde.yml new file mode 100644 index 0000000..be9438b --- /dev/null +++ b/flavors/lxde.yml @@ -0,0 +1,8 @@ +--- +addon_packages: + - vim-tiny + - firefox + - chromium-browser + - ttf-ubuntu-font-family + - ttf-wqy-zenhei +desktop: lxde diff --git a/flavors/lxqt.yml b/flavors/lxqt.yml new file mode 100644 index 0000000..40733b3 --- /dev/null +++ b/flavors/lxqt.yml @@ -0,0 +1,8 @@ +--- +addon_packages: + - vim-tiny + - firefox + - chromium-browser + - ttf-ubuntu-font-family + - ttf-wqy-zenhei +desktop: lxqt diff --git a/image/etc/supervisor/conf.d/supervisord.conf b/image/etc/supervisor/conf.d/supervisord.conf index 27690e9..2b538da 100644 --- a/image/etc/supervisor/conf.d/supervisord.conf +++ b/image/etc/supervisor/conf.d/supervisord.conf @@ -17,14 +17,10 @@ stdout_logfile_maxbytes=0 stderr_logfile=/dev/fd/1 stderr_logfile_maxbytes=0 + [group:x] programs=xvfb,wm,lxpanel,pcmanfm,x11vnc,novnc -[program:xvfb] -priority=10 -command=/usr/local/bin/xvfb.sh -stopsignal=KILL - [program:wm] priority=15 command=/usr/bin/openbox @@ -44,6 +40,14 @@ command=/usr/bin/pcmanfm --desktop --profile LXDE user=%USER% environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%" + + + +[program:xvfb] +priority=10 +command=/usr/local/bin/xvfb.sh +stopsignal=KILL + [program:x11vnc] priority=20 command=x11vnc -display :1 -xkb -forever -shared -repeat diff --git a/image/etc/supervisor/conf.d/supervisord.conf.j2 b/image/etc/supervisor/conf.d/supervisord.conf.j2 new file mode 100644 index 0000000..faca832 --- /dev/null +++ b/image/etc/supervisor/conf.d/supervisord.conf.j2 @@ -0,0 +1,74 @@ +[supervisord] +redirect_stderr=true +stopsignal=QUIT +autorestart=true +directory=/root + +[program:nginx] +priority=10 +command=nginx -c /etc/nginx/nginx.conf -g 'daemon off;' + +[program:web] +priority=10 +directory=/usr/local/lib/web/backend +command=/usr/local/lib/web/backend/run.py +stdout_logfile=/dev/fd/1 +stdout_logfile_maxbytes=0 +stderr_logfile=/dev/fd/1 +stderr_logfile_maxbytes=0 + +{% if desktop == "lxde" %} +[group:x] +programs=xvfb,wm,lxpanel,pcmanfm,x11vnc,novnc + +[program:wm] +priority=15 +command=/usr/bin/openbox +environment=DISPLAY=":1",HOME="/root",USER="root" + +[program:lxpanel] +priority=15 +directory=%HOME% +command=/usr/bin/lxpanel --profile LXDE +user=%USER% +environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%" + +[program:pcmanfm] +priority=15 +directory=%HOME% +command=/usr/bin/pcmanfm --desktop --profile LXDE +user=%USER% +environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%" +{% endif %} + +{% if desktop == "lxqt" %} +[group:x] +programs=xvfb,wm,lxpanel,x11vnc,novnc + +[program:wm] +priority=15 +command=/usr/bin/openbox +environment=DISPLAY=":1",HOME="/root",USER="root" + +[program:lxpanel] +priority=15 +directory=%HOME% +command=/usr/bin/startlxqt +user=%USER% +environment=DISPLAY=":1",HOME="%HOME%",USER="%USER%" +{% endif %} + +[program:xvfb] +priority=10 +command=/usr/local/bin/xvfb.sh +stopsignal=KILL + +[program:x11vnc] +priority=20 +command=x11vnc -display :1 -xkb -forever -shared -repeat + +[program:novnc] +priority=25 +directory=/usr/local/lib/web/frontend/static/novnc +command=bash /usr/local/lib/web/frontend/static/novnc/utils/launch.sh --listen 6081 +stopasgroup=true