Skip to main content

Docker, Virtual-Desktop and build-docker-image

Previously, my work platform involved using development, testing, and production environments. Docker is relatively new to me. As I also held a system administrator role, the characterization of Docker as "lightweight and simple" by supporters in the programming development community left me puzzled for a while. Here's a brief explanation of the differences between VMs, Docker, and Virtual Desktops as I understand them.

The platforms most people commonly interact with are standalone systems, which typically include Windows, Mac, Android, and iOS. In the early Unix era, the system architecture consisted of a Host and Terminals. Terminals are lightweight systems with basic functions, which can also be seen today in devices like the Raspberry Pi.

When work requires several systems to perform different tasks, having a separate hardware device for each can be wasteful. This led to the development of Hypervisor and VM (Virtual Machine) architectures.

Sometimes institutions need to provide public computers for authorized users without leaving user data on the machines. Virtual Desktop imports user settings to the client computer upon login, addressing this need.

Actually, Docker is not as lightweight as it seems. Its containers include the OS and all installed programs, not just the app and its dependencies.
Docker is suitable for packaging tests but does not offer the same level of OS operability to users as VMs do. Therefore, Docker's base OS is typically Alpine, which provides basic Linux functionalities.  Below are the original sizes of the Alpine and Mint (Ubuntu) images.



Creating a Docker Image

I often conduct platform tests, so I prefer not to use images that are too large. For testing development functions, I favor ultra-small OS like Alpine. Its commands are somewhat different from common Linux commands, but fortunately, the concepts are similar.

There are many quick-start courses available online. Since I tend to prefer official website data over sifting through my bookmarks, let's begin this note from the initialization. Docker has two configuration methods: one is operational, and the other is programmatic.

Example: Create a container that reads user input.


Operational:

Download the basic operating system. You can find pre-made system or function packages created by others on https://hub.docker.com/. System types such as Alpine, Ubuntu. Function packages such as Python, NGINX. (I have already logged in to Docker).

docker pull alpine

Establish container, execute system.
ducker run -it --name testInput alpine /bin/ash


Install Python. 

  apk add python3 py3-pip
  ln -sf python3 /usr/bin/python
  

Write test program.
vi /home/printInput.py


(exit docker: ctrl+p , ctrl+q )

Save the modified OS as a new image; the image name must be all lowercase.

docker container ls 


docker commit 0340edf99261 atfuture7/testinput

Launch a new container with the new image to run a custom-written Python script.

docker run -it -rm atfuture7/testinput python3 /home/printInput.py



Execution :


ref: 

https://docs.docker.com/engine/reference/run/

https://stackoverflow.com/questions/32353055/how-to-start-a-stopped-docker-container-with-a-different-command


Programmatic:

Running Docker initialization in a new directory.

docker init 

Next, a guided process will assist in creating basic data. I chose the "Other option" as a skeleton.

Other - general purpose starting point for containerizing your application

After initialization, Docker creates 4 basic files.

The current version recommends using Compose to combine different resources.

docker compose up --build

Here, I'll explain a simplified Dockerfile, primarily aimed at customizing images.

docker build -t testinupt2 . 


The Dockerfile modifies the inherited image and can be divided into different stages.

ref: https://docs.docker.com/build/building/multi-stage/

DOCKER_BUILDKIT determines whether to use BuildKit.

    FROM alpine:latest as base
    FROM base as build
    FROM base AS final
    

Modify the build stage to execute a Python script.



If using the old build method, all stages will be executed. By adopting stages, the builder will proceed in the order of inheritance, with the final product being the specified stage.
Note: During compilation, the original image name was set to "testinput2." However, a "pull access denied for testinput2" error kept occurring during execution. Deleting and rebuilding the image did not update it. Both the "created time" and "Image hierarchy" were not of the new version. I suspect it's because when logged in, the image name needs to be [account name]/[image name]. Without [account name], it's considered not part of one's account directory images.Although this image has not been pushed to the cloud.
docker build --target build -t atfuture7/testinupt2 .
Launching a new container with a custom image to run a self-written Python script. 

docker run -it -rm atfuture7/testinput2 

Running the new image.

Since the entrypoint is defined in the Dockerfile, there's no need to specify a run command when executing the image.

docker run -it  atfuture7/testinput2

My sample in GitHub: https://github.com/atfuture7/testcode/tree/master/docker/01_docker_skeleton

Comments

Popular posts from this blog

Bookmark service (MongoDB & Spring REST) -2/2

    I accidentally deleted my development VM. I got lucky having the habit of taking notes. This blog is useful. Development VM is doom to be lost. Rebuild it waste time, but having a clean slate is refreshing~. What concerns me more is my AWS free quota this month is reaching 85%. The second VM I launched but never being used might be the one to blame. (Of course, my mistake.) I terminated the wrong VM. Now I got Linux 2 built. Great, just threw away everything happened on AMI.  1st layer: Page Page class   Originally, I need to prepare getter/setter for all class properties for Spring. By using lombok, I only need to create constructors. lombok will deal with getter/setter and toString(). But there are chances to call getter/setter, but how? .......Naming convention.... Capitalize the 1st character with the prefix get/set.  Annotation @Data was used on this class.  Repository class Spring Docs: Repository https://docs.spring.io/spring-data/mongodb/docs/3.0.0.RELEASE/reference/html/#m

Built LAMP on AWS AMI, and update/install Python3.6, pip v20, Apache wsgi and Flask

I got one half day free and I spent it on building a LAMP on AWS AMI. I also wanted to squeeze Flask into Apache. So I also install/update Python 3.6, pip V.20.1, Apache wsgi and Flask. I wrapped up progress for now before I forgot all resources.    On AWS marketplace, everyone can pay for a good suit such as Django. I’m not interested in content creation unless there are interesting topics to resolve. I don’t know what left to do if I bought a solution; and I may get annoyed like everyone else if the solution causes more problems. To build on my own is more realistic and practical. Installing a LAMP (Linux, Apache, MySQL, PHP) was smooth while following AWS tutorial. Tutorial: Install a LAMP Web Server with the Amazon Linux AMI https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-LAMP.html To build Flask is absolutely a different thing….  still failed before I fell asleep... If I choose AWS EC2 Ubuntu instance, most tutorials are based on this Linux version. Unfortunately I oft

Comments for my Server/Client Web API samples

        Finally, I finished the comments for python/07 and 09 projects. I almost forgot to put the date on source code which is used to note how long it took me. Not precisely in hours….. I didn’t include source code in my previous post. If choosing code-section for this post…… maybe I want to mark out my comment….. (Really?!)          Once my work was developing websites for enterprises, including ERP, CRM or content sites. The sustainability of network and security are important issues. There are 2 methods for HTML Form submission: GET and POST. Submit via POST is secure, compared to GET which piles parameters on URL. RESTful API is mainly using GET.         Yup, even if you have a certification key, if you put the value on the URL, it is visible data. When writing socket-communication, client-server sockets are a pair; both follow the agreement on commands and structures; and there are countless ports for usage. Plain text on the message of socket communication usually wouldn’t be