Experiment Introduction:
Docker is an open-source application container engine, based on the Go programming language, and follows the Apache 2.0 open-source license. It enables developers to package their applications and dependencies into a lightweight, portable container, which can then be deployed on any popular Linux machine or used for virtualization. Containers utilize a sandbox mechanism, ensuring that they do not share interfaces with each other (similar to iPhone apps), and more importantly, they incur very low performance overhead. Docker has been divided into CE (Community Edition) and EE (Enterprise Edition) since version 17.03. For this tutorial, we will use the Community Edition.
Materials for the Experiment:
- One HS-2 server
Server Configuration:
-
CPU: SG2042
-
RAM: 128GB
-
Operating System: Ubuntu 22.10 (GNU/Linux 6.1.31 riscv64)
Experiment Steps:
Install Docker:
sudo apt install docker.io
Next, pull an Ubuntu image (I’m using the 22.04 image here):
sudo docker pull riscv64/ubuntu:22.04
Create a test container and start it:
sudo docker run --name ubuntu -itd riscv64/ubuntu:22.04
sudo docker start ubuntu
Check the container’s status:
sudo docker ps
Access the shell inside the container:
sudo docker exec -it ubuntu /bin/bash
Due to the fact that most Docker images currently support only x86 and ARM architectures, with limited support for RISC-V containers, to explore all RISC-V compatible containers, you can refer to the RISC-V64 section on Docker Hub. In this article, we will directly create a new Ubuntu 20.04 image to run two services: Flask and Nginx.
Create a container named “ubuntu-web,” open and forward two ports (5000 to 5050, 80 to 8008), and create a shared folder (for transferring static websites into the container):
sudo docker run -p 5050:5000 -p 8008:80 -v /home/sputnik/ubuntu_web_share:/root --name ubuntu-web -itd riscv64/ubuntu:22.04
Start the container:
sudo docker start ubuntu-web
Access the container:
sudo docker exec -it ubuntu-web /bin/bash
Navigate to the home directory inside the container and update the repository:
Upgrade the system to the full version (if you find the official Ubuntu Ports image download slow, you can refer to the tutorial on the Tsinghua University Tuna mirror site. However, you need to update the apt cache first to install vim and ca-certificates and then follow the mirror site’s instructions. Of course, other Chinese mirror sites are also acceptable as long as they have the Ubuntu Ports image):
unminimize
Install the required packages (if vim is not installed, add vim at the end):
apt install python3 python3-pip libpython3-dev libffi-dev unzip
Use the Tuna PyPi source:
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
Install Flask and other necessary components:
pip install flask gevent flask-cors
Create a new app.py
file and write the following code:
from flask import Flask
import platform
app = Flask(__name__)
@app.route('/')
def hello_world():
return "Greetings from a container ({} {} {})!".format(platform.uname()[0], platform.uname()[2], platform.uname()[-1])
if __name__ == '__main__':
app.run(host="0.0.0.0", port=5000)
Save and run:
python3 app.py
Access [your_ip_address]:[your_flask_port]
to see the following content:
Next, we will build a simple website using the Vue.js + Nginx + Flask combination. First, install Nginx:
apt install nginx
Start the Nginx service:
service nginx start
Access [server_address]:[your_Nginx_port]
:
Next, let’s create a simple website. This time, we’ll use Vite for building (using cnpm might be faster):
cnpm create vite@latest
cd riscv-site
cnpm install
Test it:
cnpm run dev
Next, refer to the Vite or Vue documentation to write the front-end content (custom content or modify the Vite official example). If you use Axios to make requests directly, you will encounter CORS restrictions and access denial.
First, import CORS from flask_cors:
from flask_cors import CORS
Then, add the following two lines of code under “app = Flask(name)” in app.py:
CORS(app, resources={"/*": {"origins": "http://*"}})
CORS(app, resources={"/*": {"origins": "https://*"}})
The rest can be modified as needed, or you can refer to the following code. The final code is as follows (Flask):
from flask import Flask
from flask_cors import CORS
import platform
from gevent import pywsgi
app = Flask(__name__)
CORS(app, resources={"/*": {"origins": "http://*"}})
CORS(app, resources={"/*": {"origins": "https://*"}})
@app.route('/')
def hello_world():
return "Greetings from {} ({} {})!".format(platform.uname()[0], platform.uname()[2], platform.uname()[-1])
if __name__ == '__main__':
server = pywsgi.WSGIServer(('0.0.0.0', 5000), app)
server.serve_forever()
# app.run()
Note: You can use pywsgi in conjunction with it for production environments. The front-end part (Vue.js) code is as follows:
App.vue:
<script setup>
import axios from 'axios'
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue'
let text = ref("")
const show_text = async () => {
try {
const response = await axios.get("[你的Flask服务器地址]");
console.log(response.data)
text.value = response.data
} catch (error) {
console.error(error);
}
}
show_text()
</script>
<template>
<div>
<a href="https://riscv.org" target="_blank">
<img src="./assets/RISC-V_Stacked_Color.svg" class="logo" alt="Vite logo" />
</a>
<a href="https://vuejs.org/" target="_blank">
<img src="./assets/vue.svg" class="logo vue" alt="Vue logo" />
</a>
</div>
<HelloWorld :msg="text" />
</template>
<style scoped>
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #003262);
}
.logo.vue:hover {
filter: drop-shadow(0 0 2em #42b883aa);
}
</style>
HelloWorld.vue:
<script setup>
import { ref } from 'vue'
defineProps({
msg: String,
})
const count = ref(0)
</script>
<template>
<h1>{{ msg }}</h1>
<p>
Check out
<a href="http://blog.rvv.top:8002/"
>RISC-V Growth Diary</a
> for further information
</p>
<p class="read-the-docs">Click on the RISC-V and Vue logos to learn more</p>
</template>
<style scoped>
.read-the-docs {
color: #888;
}
</style>
Note: In the Vite project, you can install other npm packages (such as Echarts, Element+, etc.) according to your specific requirements.
Next, we will deploy the website to a web container. First, we will build the Vite project into static files:
cnpm run build
After a successful build, you will see the following content:
You will find a “dist” folder after the build. Package the “dist” folder and upload it to the server, then transfer the “dist.zip” into the shared folder on the server:
sudo cp dist.zip ./ubuntu_web_share/
Clear the contents under “/var/www/html/”:
rm -rf /var/www/html/*
Copy all the contents from the “dist” folder to “/var/www/html/”:
cp -R ./* /var/www/html/
Access the browser at [server_address]:[NGINX_server_port]
:
Experiment Summary:
Through this experiment, we quickly got started with Docker. Thanks to Docker’s sandbox mechanism, we were able to configure independent development environments without affecting the host machine’s environment. We then packaged these environments into images for deployment in production. Additionally, by using Vite, debugging Vue.js websites became more convenient, and it also supports packaging static files for deployment on Nginx servers or GitHub Pages.
References: