📜 ⬆️ ⬇️

FastReport.Mono. Part 2: Web Report in Docker Container



In the previous part of the publication, I described how to run the demo report FastReport.Mono. Now, I propose to move to a new level and “wrap” all the necessary components in Docker containers.


Understand, in heaven only say that about the sea. How infinitely beautiful it is ...

In recent years, everyone and everywhere talk about Docker, because containers are stylish, fashionable and sexy youth. Many developers and administrators use Docker on business and without any need. But, if you really need this and interesting - welcome under cat. Unlike the first part, there will be a maximum of text and a minimum of images.

As already noted, for FastReport.Mono to work correctly, we may need 2 containers:
')

We create both containers based on the debian: stretch image from the Docker repository.

FRMono container


The first container, as already mentioned, will contain Apache 2.4. In addition, when assembling, we will immediately add Mono and FastRepor there.

In principle, nothing prevents you from expanding the Dockerfile and organizing an automatic installation of another Oracle Instant Client, but since The article is devoted to the demo Web-report - we do not need it.

Dockerfile
FROM debian:stretch ENV TZ Europe/Moscow ENV DEBIAN_FRONTEND noninteractive ENV DISPLAY :1 WORKDIR / RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf RUN ["mkdir", "-p", "/opt/fastreport/htdocs/bin"] RUN apt-get update \ && apt-get -y install apt-utils \ && apt-get -y install unzip \ && apt-get -y install mono-complete mono-xsp apache2 libapache2-mod-mono # Apache setup COPY 001-mono.conf /etc/apache2/sites-available/001-mono.conf RUN /usr/sbin/update-rc.d apache2 disable \ && /usr/sbin/a2dismod mod_mono_auto \ && /usr/sbin/a2dissite 000-default \ && /usr/sbin/a2ensite 001-mono # FastReport.Mono setup # Download official Demo ADD https://www.fastreport.ru/public_download/frmono_demo.zip /tmp/frmono_demo.zip # Or add from local filesystem #COPY frmono_demo.zip /tmp/frmono_demo.zip # Extract and copy to destinations RUN ["unzip", "/tmp/frmono_demo.zip", "-d", "/tmp/frmono.demo"] RUN cp -rp /tmp/frmono.demo/Demos/C#/Web/* /opt/fastreport/htdocs RUN cp /tmp/frmono.demo/FastReport.*.dll /opt/fastreport/htdocs/bin RUN chown -R www-data:www-data /opt/fastreport # Volume for X11 unix socket VOLUME /tmp/.X11-unix # Start Apache in foreground to prevent container exit CMD ["/usr/sbin/apachectl", "-DFOREGROUND"] 

Actually, there is nothing difficult or cunning in setting up. The main thing that you should pay attention to: you do not need to run Apache as a background process, you need to bring it to the fore. Otherwise, the container will complete its work immediately after launch.

The virtual host configuration file for Apache, in principle, is a truncated version of the config shown in the first part of the publication. However, there are some differences. This is due to the fact that a slightly different directory structure will be used (with the placement of libraries in the bin directory).

I don’t see any particular difference in these approaches. In addition, in the container, you can safely use port 80.

001-mono.conf
 <VirtualHost *:80> DocumentRoot "/opt/fastreport/htdocs" <IfModule mod_mono.c> MonoUnixSocket FrSite /tmp/.mod_mono_server MonoServerPath FrSite /usr/bin/mod-mono-server4 MonoPath FrSite /usr/lib/mono/4.5:/usr/lib:/usr/lib/mono/4.0 AddMonoApplications FrSite "/:/opt/fastreport/htdocs" MonoAutoApplication Disabled MonoDocumentRootDir /opt/fastreport/htdocs MonoDebug false MonoSetEnv FrSite DISPLAY=:1;HOME=/opt/fastreport AddHandler mono .aspx .ascx .asax .ashx .config .cs .asmx .axd </IfModule> <Directory "/opt/fastreport/htdocs"> Require all granted Options Indexes FollowSymLinks MultiViews AllowOverride All <IfModule mod_mono.c> SetHandler mono MonoSetServerAlias FrSite DirectoryIndex Default.aspx </IfModule> </Directory> <Directory "/opt/fastreport/htdocs/bin"> Require all denied </Directory> </VirtualHost> 


Run the build process:

 docker build -t debian-stretch-mono:latest . 

Container X11Dummy


In the first part of this series of publications, I already mentioned that to use System.Windows.Forms, you must have an X server. Since in the container with Apache, Mono and FastReport there are no “X's”, we need to get them from somewhere.

Two options are possible:


The first option will require different settings, depending on your OS. After all, in Linux it may be, for example, X.org , in Mac OS - XQuartz , and in Windows you will have to deliver Xming
The second option is more consistent with the Docker concept and allows you to create a system that is easily portable and independent of the host OS. The interaction between containers can be implemented via a tcp or unix-socket. In my opinion, the option of using a unix-socket is great for solving this problem.

Dockerfile
 FROM debian:stretch ENV TZ Europe/Moscow ENV DEBIAN_FRONTEND noninteractive ENV DISPLAY :1 RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf RUN apt-get update \ && apt-get -y install apt-utils \ && apt-get -y install xserver-xorg-video-dummy x11-apps VOLUME /tmp/.X11-unix COPY xorg.mini.conf /etc/X11/xorg.conf CMD /usr/bin/Xorg -noreset +extension GLX +extension RANDR +extension RENDER -logfile /tmp/xdummy.log -config /etc/X11/xorg.conf $DISPLAY 

If you carefully examine the Docerfile under the spoiler, then you should pay attention to two points. The first is the use of the video driver from the xserver-xorg-video-dummy package. An “empty” driver that tells the X server that it displays an image, but actually does nothing.

The second is to set the DISPLAY environment variable to a value that differs from the usual one according to all sorts of instructions: 0. Extremely precautionary, if you suddenly decide to expose a UNIX socket through the host's / tmp OS.

The configuration file of the X-server is a variation on the subject of this config, walking with various changes throughout the network. I came across a very long version with a bunch of Modelines (alas, I could not remember the source) and I tried to squeeze it as much as possible (although I think you can still).

xorg.mini.conf
 Section "ServerFlags" Option "DontVTSwitch" "true" Option "AllowMouseOpenFail" "true" Option "PciForceNone" "true" Option "AllowEmptyInput" "true" Option "AutoEnableDevices" "false" Option "AutoAddDevices" "false" EndSection Section "Device" Identifier "dummy_videocard" Driver "dummy" DacSpeed 600 Option "ConstantDPI" "true" VideoRam 256000 EndSection Section "Monitor" Identifier "dummy_monitor" HorizSync 1.0 - 2000.0 VertRefresh 1.0 - 200.0 Modeline "1920x1080" 23.53 1920 1952 2040 2072 1080 1106 1108 1135 Modeline "1280x1024" 31.50 1280 1312 1424 1456 1024 1048 1052 1076 Modeline "1280x720" 59.42 1280 1312 1536 1568 720 735 741 757 Modeline "1024x768" 18.71 1024 1056 1120 1152 768 786 789 807 EndSection Section "Screen" Identifier "dummy_screen" Device "dummy_videocard" Monitor "dummy_monitor" DefaultDepth 24 SubSection "Display" Viewport 0 0 Depth 8 Modes "1920x1080" "1280x1024" "1280x800" "1024x768" Virtual 8192 4096 EndSubSection SubSection "Display" Viewport 0 0 Depth 16 Modes "1920x1080" "1280x1024" "1280x800" "1024x768" Virtual 8192 4096 EndSubSection SubSection "Display" Viewport 0 0 Depth 24 Modes "1920x1080" "1280x1024" "1280x800" "1024x768" Virtual 8192 4096 EndSubSection SubSection "Display" Viewport 0 0 Depth 30 Modes "1920x1080" "1280x1024" "1280x800" "1024x768" Virtual 8192 4096 EndSubSection EndSection Section "ServerLayout" Identifier "dummy_layout" Screen "dummy_screen" EndSection 


We collect:

 docker build -t debian-stretch-x11dummy:latest . 

Run with Docker-compose


For ease of service management, docker-compose is fine. During the launch process, we need to:


Based on the above requirements, we get the minimum required docker-compose.yml.

docker-compose.yml
 version: "2" services: fastreport: container_name: frmono image: debian-stretch-mono:latest volumes: - ./.x11-unixsoc:/tmp/.X11-unix ports: - "127.0.0.1:8085:80" xorg: container_name: x11dummy image: debian-stretch-x11dummy:latest volumes: - ./.x11-unixsoc:/tmp/.X11-unix 


NB If you are not familiar with YAML , note that the formatting is done with spaces .

Since A unix socket is, in essence, a file, then we use plug-in volumes — the ability of the container to interact with the host. With this approach, both data exchange containers will use the .x11-unixsoc directory located in the startup directory.

We start and check:

 docker-compose up 

And, as one of my friends likes to say, “the cherry on the cake”: automate the launch of containers when the OS starts using Systemd. Everything is carried out in two simple steps. First, it is necessary and sufficient to create the file /etc/system.d/system/docker-frmono.service, the approximate content of which is given under the spoiler. Why approximate? At a minimum, you need to change the paths according to the location of the configuration files you chose and the installation location of the docker-compose.

docker-frmono.service
 [Unit] Description=FastReport Docker Requires=docker.service After=docker.service [Service] Restart=always ExecStart=/usr/local/bin/docker-compose -f /opt/frdocker/docker-compose.yml start ExecStop=/usr/local/bin/docker-compose -f /opt/frdocker/docker-compose.yml stop [Install] WantedBy=multi-user.target 


Second, register the service in the system and “enable” it:

 systemctl daemon-reload systemctl enable docker-frmono 


PS It is possible that in the process of experiments, you have accumulated a certain number of "curved" images. You can clean it up as follows:

 docker images | grep "<none>" | awk '{split($0,a," ");print a[3];}' | xargs -I{} docker rmi "{}" 

All the configuration files used in the article are available on github.

Source: https://habr.com/ru/post/351980/


All Articles