development environment – Eternal Night https://www.shuijingwanwq.com There is no problem not worth solving, and no technology not worth learning! Mon, 08 Jun 2026 12:18:23 +0000 en-US hourly 1 https://wordpress.org/?v=7.0 From zero to one: Build a Go + Gin development environment in Trae CN + Docker https://www.shuijingwanwq.com/en/2026/06/08/16568/ https://www.shuijingwanwq.com/en/2026/06/08/16568/#respond Mon, 08 Jun 2026 12:02:40 +0000 https://www.shuijingwanwq.com/?p=16568 Post Views: 14

write in front

Recently I tried to use the trae cn editor on Ubuntu 26.04, with the docker container to develop a Go + Gin project (go-gin-learning). The whole process stepped on some pits, but I also ran through a set of workflow that was relatively easy. This article is a complete record, I hope it can help friends who have encountered similar problems.

If you have read my previous blog (such as‘Build the basic environment based on Docker Compose + Go 1.26.4 in Ubuntu 26.04’), then this article can be regarded as ‘next article’ – from code submission to container operation, all strings together.


1. Preparations on the host

1.1 Install git and configure user information

First make sure that the host has git, then set the global username and mailbox (this information will be written every time):

git config --global user.name "shuijingwan"
git config --global user.email "shuijingwanwq@163.com"

Verify it:

git config --global user.name
git config --global user.email

1.2 Configure GitHub authentication (using Token)

GitHub will no longer support password authentication from 2021, and need to generate Personal Access Token.

  • Login Github → Settings → Developer Settings → Personal Access Tokens → Tokens (Classic)
  • Click on Generate new token (classic)
  • Check repo Permission, copy token after generation (only show once)
  • Execute in the host terminal:
git push origin main

When prompted for a username, enter your GitHub username, and paste the token just copied to the password. Git will remember the authentication information (if Credential Helper is configured) after success.

1.3 Install Go (Host)

In order to make the code completion and syntax jump in the TRAE CN work properly, you need to install Go on the host machine. I chose to use apt to install, which is simple and easy:

sudo apt update
sudo apt install golang-go -y
go version

output:GO Version GO1.26.0 Linux/AMD64

In fact, there is also a Snap version of Go in the system ‘Software’ (see screenshot), but APT is lighter and compatible with the Go version in the container.

Available versions of Go in the Software Center
Available versions of Go in the Software Center

1.4 Installing Go Extensions in Trae CN

Open Extension Store for TRAE CN, search go, find the official extension (published by golang) and install.

Extend Go extensions in the store
Extend Go extensions in the store

After the installation is complete, press Ctrl+Shift+P, enter go: install/update tools, check the pop-up list gopls,dlv,staticcheck and other common tools, click OK.

Select the Go tool to install
Select the Go tool to install

Wait for the installation to complete, then reload the window.

At this point, the code editing environment on the host is ready.

Enter fmt in main.go. You should see a smart prompt.
In main.go in input fmt. You should be able to see smart tips.

The development environment in the container

2.1 Let the container reuse the Git configuration of the host

We want to execute inside the container git commit You can also use the user name and mailbox of the host machine. Modify docker-compose.yml, mount ~/.gitconfig:

volumes:
  - ./:/code
  - ~/.gitconfig:/root/.gitconfig:ro

After restarting the container, enter the container verification:

docker exec -it go-gin-learning sh
git config --global user.name   # 应显示 shuijingwan
git config --global user.email  # 应显示 shuijingwanwq@163.com

2.2 Solve the problem of slow download of Go module

Initially execute inside the container Go mod tidy Always fail or time out because the default proxy goproxy.io Unstable, and the cache is emptied every time the container is rebuilt.

There are two solutions:

  • Set up a more stable proxy:go env -w goproxy=https://goproxy.cn,direct
  • persistent module cache: Mount the directory of the host machine to the container /go/pkg/mod

I used the latter, in docker-compose.yml add in:

volumes:
  - ~/go/pkg-mod-go-gin-learning:/go/pkg/mod

In this way, the dependencies inside the container will be stored in a dedicated directory of the host, and even if the container is deleted, it will not be lost. execute again Go mod tidy time, all Go: downloading All succeeded.

2.3 Run the GIN service

Execute inside the container:

go run main.go

See the output below to indicate that the service has started successfully:

[GIN-debug] Listening and serving HTTP on 0.0.0.0:8080

Access with a browser http://localhost:8080/albums, return JSON data, status code 200.

Requests in the browser are responding normally
Requests in the browser are responding normally

At this time, in the Docker extension panel of Trae CN, you can right-click the container to select Attach shell, conveniently open the container terminal.

Container Operations Menu for Docker Extension Panel
Container Operations Menu for Docker Extension Panel

3. Summary and standardization outlook

Current workflow summary

  1. hosting: Responsible for Git operation, code editing, Go language server (GOPLS).
  2. Container: Responsible for running go run,go test, the dependency module is persisted through the mounted cache directory.
  3. TRAE EN: Provide intelligent completion through the Go extension, attach to the container terminal through the Docker extension, so that ‘edit on the host, run in the container’.

Although Dev Containers is temporarily unavailable on TRAE CN, we still get an efficient and reliable development environment with the combination of ‘Host Go + Container Run + Cache Persistent’.
(by the way,.devcontainer/devcontainer.json I didn’t delete it because other members on the team who use VS Code may also need it. )

The points that can be standardized in the future

  • Encapsulate common commands with Makefile: for example make run,make test,make tidy, reduce manual input.
  • Integrated AIR thermal loading: Install inside the container air, after saving the file, automatically restart the service to improve development efficiency.
  • Write environment configuration as a script: put docker-compose.yml Volumes settings, proxy configuration, dependency installation, etc. are written as setup.sh, it is convenient for new members to quickly join.
  • Consider using Remote – SSH: If the future teams are all developed on the same server, you can use SSH remote development to completely unify the environment.
]]>
https://www.shuijingwanwq.com/en/2026/06/08/16568/feed/ 0
Try Dev Containers in Trae CN: A not very successful step on the pit record https://www.shuijingwanwq.com/en/2026/06/08/16565/ https://www.shuijingwanwq.com/en/2026/06/08/16565/#respond Mon, 08 Jun 2026 10:23:47 +0000 https://www.shuijingwanwq.com/?p=16565 Post Views: 13

write in front

This blog is just a simple record: I tossed the process of Microsoft’s official Dev Containers extension in Trae CN.Let’s talk about the conclusion first: Tossing around and discovering TRAE CN currently (June 2026)Not supported yet dev containers. So this article will not give any ‘perfect solution’, and only leave an introduction in the end – the next step I plan to try another path:Host Go + Container Run + Docker Extension Assist, if you run through, write a separate article to share.

project background: I am now writing with trae cn on ubuntu 26.04 go-gin-learning((https://github.com/shuijingwan/go-gin-learning), a small project of Go + Gin.

Two blogs that have been completed before(all have already been posted):

  1. ‘Build the basic environment based on Docker Compose + Go 1.26.4 in Ubuntu 26.04’
    https://www.shuijingwanwq.com/en/2026/06/03/15642/
    This article mainly fixes the Docker environment, container startup, MySQL/Redis network, etc.
  2. GO + GIN RESTful API: From Environment Build (WSL/Docker/VS Code) to Git Commit and GitHub Hosting
    https://www.shuijingwanwq.com/en/2026/04/03/11106/
    This is in Windows WSL + Docker + VS Code A complete set of processes that have been successfully run through. Now I want to ubuntu + docker + trae cn Implement the same thing again.

So this article is actually a small episode in the middle: I want to try whether I can also use dev containers to ‘moving’ the entire editor into the container in the trae cn, and it turns out that… it is not for the time being.


Why do you want to try dev containers?

Students who have used VS Code should know that the function of Dev Containers is really delicious: you can stuff the entire development environment (including the Go version, toolchain, extension, terminal) into a Docker container. When teamwork or machine change, open the project and click ‘Reopen in container’ to start working directly without installing a bunch of things.

I have used it very well on Windows + WSL + VS Code before (that’s what I wrote in the second blog). So after switching to ubuntu + trae cn, I naturally want to re-enact this experience. So there is the following tossing process.


2. Record of the process of stepping on the pit

2.1 First match the expansion market address

The default expansion market address of TRAE CN isEmpty, you have to fill it yourself. I’m in the settings application.extensionmarketURL Changed to https://marketplace.visualstudio.com/.

[截图 3:修改 application.extensionMarketUrl 设置]

[截图 3:修改 application.extensionMarketUrl 设置]

2.2 Install the official Dev Containers extension

After the address is configured, you can find the official Microsoft ms-vscode-remote.remote-containers out. Click Install.

[截图 4:官方 Dev Containers 扩展的详情页]

[截图 4:官方 Dev Containers 扩展的详情页]

After installing it, the status bar says ‘Users have disabled this extension globally’. Huh? I didn’t do anything…

[截图 5:扩展显示“用户已全局禁用此扩展”及右键菜单]

[截图 5:扩展显示“用户已全局禁用此扩展”及右键菜单]

2.3 Try various ‘enabled’ poses

  • Click on the extension details page ‘Enable (Workspace)’ → No response.
  • with command panel Extensions: Enable Extension Select dev containers → still no response.
  • Even forcibly add 'extensions.enabled' Configuration → still invalid.
[截图 7:工作区设置中添加强制启用配置]

[截图 7:工作区设置中添加强制启用配置]

2.4 Try another market source?

I replaced the market address with https://open-vsx.org/, restart trae cn and search for dev containers – the result is found Open-VSX can’t find the official Microsoft extension at all, only a community version called ‘Artizo dev containers for trae’ came out.

[截图 8:社区版 Artizo Dev Containers for Trae 扩展(仅展示,我没敢装)]

[截图 8:社区版 Artizo Dev Containers for Trae 扩展(仅展示,我没敢装)]

To be honest, I am a little worried about the community version, and I don’t dare to pretend casually.

2.5 Finally try to install VSIX offline

I think, since it is not online, then download the VSIX file manually. Take one out of the VS Code market ms-vscode-remote.remote-containers-0.459.1.vsix, and then use it in trae cn ‘Installation from VSIX’ guide in.

[截图 9:从本地 VSIX 文件安装扩展的文件选择对话框]

[截图 9:从本地 VSIX 文件安装扩展的文件选择对话框]

The installation process looks normal, but after installing… still ‘Users have been disabled globally’. This means that the problem is not in the download or installation link, but the extension itself is not compatible with the activation mechanism of TRAE CN.

2.6 Smooth Docker Extension

Although Dev Containers is useless, I do it MS-AzureTools.vscode-docker(Container tools) are installed, and this can still be used later.

[截图 1:Trae CN 扩展商店中 Docker 扩展的安装界面]

[截图 1:Trae CN 扩展商店中 Docker 扩展的安装界面]

In addition, the container in the Docker sidebar is also running normally.

2.7 Take a look at the official forum

Finally, I went to the official forum of TRAE and searched, and someone asked:[Feedback] Dev Containers extension cannot be used. The official reply is very clear:Dev Containers is not currently supported.

Well, give up.


3. The conclusion is that it is really not supported at present

Summarize the results of this attempt:

  • The official extension is installed, but it always shows that ‘the user has been disabled globally’ and cannot be activated.
  • There is no official version in the open-vsx market at all, there is only one community version (I didn’t install it).
  • Manual VSIX installation cannot be saved, just like it is disabled.
  • The official forum confirmed: not supported.

So, if you also want to reproduce the ‘one-click container’ development experience in VS Code in Trae CN,Don’t bother for now.


4. What are you going to do next?

Although dev containers can’t work, the development still has to continue. I’m going to change my mind and try it ‘Host Go + Container Run + Docker Extension Assistant’ This mixing mode. The general idea is:

  • The host machine installs a Go SDK, so that the code completion of the TRAE CN can work normally.
  • The container continues to run and test, and directly operate the terminals within the container through the ‘Attach shell’ extended by the Docker.
  • The Git operation uses the source code management panel that comes with the Trae CN (the actual tune is the Git of the host), and the code is automatically synchronized through the Volumes mount.

This plan has not officially run, just my next plan. If I can run smoothly, I will write a separate blog to share the specific configuration and usage.

]]>
https://www.shuijingwanwq.com/en/2026/06/08/16565/feed/ 0
Configure development environment: Manage multi-version MySQL and Redis with Docker https://www.shuijingwanwq.com/en/2026/06/01/15368/ https://www.shuijingwanwq.com/en/2026/06/01/15368/#respond Mon, 01 Jun 2026 08:48:33 +0000 https://www.shuijingwanwq.com/?p=15368 Post Views: 14

This article is a development environment for the ‘From Windows to Ubuntu: Complete Guide to Migration and Configuration’ series.
It is suitable for developers who have completed the Ubuntu system installation and hope to build an efficient, isolated and multi-version database environment.


Why use Docker to manage databases?

Under Windows, I am used to running a separate database container with WSL2 + Docker, and it will naturally continue after migrating to Ubuntu. Compared to install directly on the host machine:

  • Coexist with multiple versions: The same machine runs mysql 5.7 and 8.0 at the same time, and redis does not interfere with each other.
  • environmental isolation: The database of each project is shared independently or by version, and the configuration is not fighting.
  • Easy to clean: Release resources when the container stops, the data volume is reserved, and there is no residue after deletion.
  • version locked:mysql:5.7 The image always corresponds to the latest version 5.7, and will not be automatically changed due to system upgrades.

This article has MySQL 5.7, MySQL 8.0, Redis 7.2 For example, build three independent containers for subsequent Go/PHP projects to share.


1. Install the Docker engine (pure command line, no docker desktop)

Ubuntu’s ‘Software’ or ‘Application Center’ cannot find Docker Desktop, which is a feature of the Linux distribution software distribution – professional tools usually need to manually add official software sources. The official source installation is lighter and more stable.

1. Uninstall old packages that may conflict (the new system can be skipped)

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
  sudo apt remove -y $pkg
done

If you are a newly installed Ubuntu 26.04, these packages do not exist, this step can be skipped.

2. Add the official Docker GPG key and software source

sudo apt update
sudo apt install -y ca-certificates curl

sudo install -m 0755 -d /etc/apt/keyrings
sudo curl --http1.1 -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update

Step on the pit record: if curl Download GPG Times Curl: (16) Error in the HTTP2 Framing Layer, plus parameters --http1.1 can be solved.

3. Install the Docker engine and the Compose plugin

sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

4. Add the current user to the Docker group (sudo free)

sudo usermod -aG docker $USER

Must log out and log in again (or restart), otherwise docker The command still requires sudo.

5. Verify the installation

docker --version          # 输出如 Docker version 29.5.2
docker compose version    # 输出 Docker Compose version v2.x

2. Troubleshooting the problem of network and mirror pulling (real record of stepping on the pit)

In the VPN environment, the network timeout is encountered when the first test image is pulled. The following is a complete investigation and solution process.

2.1 First attempt: run hello-world directly

docker run hello-world

output:

Unable to find image 'hello-world:latest' locally
docker: Error response from daemon: failed to resolve reference "docker.io/library/hello-world:latest": failed to do request: Head "https://registry-1.docker.io/v2/library/hello-world/manifests/latest": dial tcp 128.242.240.85:443: i/o timeout

2.2 Restart the Docker service, try again

sudo systemctl restart docker
docker run hello-world

Still timed out, this time the IP becomes 31.13.69.245:

dial tcp 31.13.69.245:443: i/o timeout

2.3 Check if the host can access the Docker Hub

curl -I https://registry-1.docker.io/v2/

output:

HTTP/1.1 200 Connection established

HTTP/2 401 
date: Sun, 31 May 2026 10:04:04 GMT
content-type: application/json
content-length: 87
...

This meansThe host network is normal(Returns 401 because there is no authentication, but the connection is established), the problem is with the Docker daemon itself.

2.4 Configure the domestic mirror accelerator (first attempt)

Create /etc/docker/daemon.json, use the University of Science and Technology of China, NetEase, Baidu mirror:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn",
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com"
  ]
}
EOF
sudo systemctl daemon-reload
docker run hello-world

The result is still timed out (IP becomes 103.97.3.19):

dial tcp 103.97.3.19:443: i/o timeout

2.5 Restart Docker again, the problem remains

sudo systemctl restart docker
docker run hello-world

This error changed:

dial tcp: lookup docker.mirrors.ustc.edu.cn on 127.0.0.53:53: no such host

Explain that the domain name of the image accelerator cannot be resolved – VPN affects DNS.

2.6 Final Scenario: Use DaoCloud Image + Specify Public DNS

Modify /etc/docker/daemon.json, and configure the image and DNS at the same time:

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://docker.m.daocloud.io"],
  "dns": ["8.8.8.8", "1.1.1.1"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker run hello-world

This time it finally succeeded in pulling and running:

latest: Pulling from library/hello-world
4f55086f7dd0: Pull complete 
d5e71e642bf5: Download complete 
Digest: sha256:0e760fdfbc48ba8041e7c6db999bb40bfca508b4be580ac75d32c4e29d202ce1
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
...

Conclusion: In a VPN environment, the Docker daemon may not use the system DNS correctly, and you need to explicitly specify a common DNS (such as 8.8.8.8) and cooperate with an available image accelerator. DaoCloud image docker.m.daocloud.io Available in this environment.


3. Deploy MySQL 5.7/8.0 and Redis 7.2 containers

3.1 Create a project directory

mkdir -p ~/docker/services
cd ~/docker/services

3.2 Writing docker-compose.yml

cat > docker-compose.yml << 'EOF'
version: "3.8"      # 新版 Docker Compose 可省略该行,会有警告但无影响

networks:
  dev-network:
    driver: bridge

services:
  mysql57:
    image: mysql:5.7
    container_name: mysql57
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: mystrongpwd57
    ports:
      - "3306:3306"
    volumes:
      - ./data/mysql57:/var/lib/mysql
    networks:
      - dev-network

  mysql80:
    image: mysql:8.0
    container_name: mysql80
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: mystrongpwd80
    ports:
      - "3307:3306"
    volumes:
      - ./data/mysql80:/var/lib/mysql
    networks:
      - dev-network
    command: --default-authentication-plugin=mysql_native_password

  redis:
    image: redis:7.2
    container_name: redis72
    restart: unless-stopped
    ports:
      - "6379:6379"
    volumes:
      - ./data/redis72:/data
    command: redis-server --requirepass myredispass --appendonly yes
    networks:
      - dev-network
EOF

dodge a pit reminder: MySQL 8.0 needs to be added --default-authentication-plugin=mysql_native_passwordOtherwise, some old client connections will report caching_sha2_password error.

3.3 The first startup (encountered to network fluctuations)

docker compose up -d

The output shows:

WARN[0000] the attribute `version` is obsolete...
[+] up 19/24
 ✘ Image mysql:8.0  Error failed to resolve reference ... EOF

The cause of the error is that authentication failure (EOF) is a temporary problem with the image accelerator when pulling MySQL 8.0.

3.4 Retry directly, success

docker compose up -d

All images were pulled successfully this time:

[+] up 25/34
 ✔ Image mysql:5.7   Pulled
 ✔ Image redis:7.2   Pulled
 ✔ Image mysql:8.0   Pulled
 ✔ Network services_dev-network Created
 ✔ Container mysql57 Started
 ✔ Container redis72 Started
 ✔ Container mysql80 Started

Experience: Docker Hub or mirror accelerator has occasional network problems, and it can often be solved by retrying.


4. Verify container operation and connection test

4.1 View container status

docker ps

output:

CONTAINER ID   IMAGE       COMMAND                   STATUS          PORTS                                                    NAMES
9ec38ca384b6   redis:7.2   "docker-entrypoint.s…"   45 seconds ago   Up 42 seconds   0.0.0.0:6379->6379/tcp, [::]:6379->6379/tcp              redis72
4e93fd2e2c3f   mysql:8.0   "docker-entrypoint.s…"   45 seconds ago   Up 42 seconds   33060/tcp, 0.0.0.0:3307->3306/tcp, [::]:3307->3306/tcp   mysql80
29598dd51087   mysql:5.7   "docker-entrypoint.s…"   45 seconds ago   Up 42 seconds   0.0.0.0:3306->3306/tcp, [::]:3306->3306/tcp, 33060/tcp   mysql57

4.2 Connecting to MySQL 5.7

docker exec -it mysql57 mysql -uroot -pmystrongpwd57

Enter the mysql command line and execute exit Exit.

4.3 Connect MySQL 8.0

docker exec -it mysql80 mysql -uroot -pmystrongpwd80

Also successfully entered.

4.4 Connecting to Redis

docker exec -it redis72 redis-cli -a myredispass

output prompt Warning: using a password with-a... may not be safe(only security warnings, not affecting use), then enter 127.0.0.1:6379> prompt.

At this point, all three database containers have been running normally.

At this point, all three database containers have been running normally.

5. Provide project container connection (network communication)

Database containers are located on custom networks services_dev-network(automatically created by docker-compose). The project container only needs to join the same external network, you can pass container name visit.

Give typical examples docker-compose.yml Fragment:

networks:
  default:
    external:
      name: services_dev-network

services:
  go-app:
    image: golang:1.26-alpine
    networks:
      - default
    environment:
      DB_HOST: mysql57         # 或 mysql80
      REDIS_HOST: redis72

Connect in code mysql57:3306,redis72:6379 can.


6. Version selection instructions and precautions

ServiceVersionmainstreamlife cycle reminder
mysql 5.75.7.44About 18.8%, which is a common version of the legacy systemEOL in October 2023,No more official security updates, it is not necessary to recommend the use of new projects
MySQL 8.08.0.46The current most mainstream (58%)Official support will be April 30, 2026 At the end of the day, you need to upgrade to 8.4 LTS
Redis 7.27.2.xStable and matureThe basic version of the open source branch Valkey, you can use it with confidence

If it is a new project, it is recommended to use it directly MySQL 8.4 LTS(supported until 2031) and Redis 7.2.


7. Quick check of daily management orders

OperatingCommand
Start all servicescd ~/docker/services && docker compose up -d
Stop all servicescd ~/docker/services && docker compose down
Restart MySQL 8.0 aloneDocker restart mysql80
View MySQL 5.7 logsdocker logs -f mysql57
Enter the Redis command linedocker exec -it redis72 redis-cli -a password
Clean up unused images/containersdocker system prune -a
Backup data volumestar -czf mysql57-backup.tar.gz ~/docker/services/data/mysql57

8. Summary

At this point, we have completed a clean, reusable database container environment:

  • MySQL 5.7 → Port 3306
  • MySQL 8.0 → Port 3307
  • Redis 7.2 → Port 6379

All data is persisted in ~/docker/services/data/, the container automatically runs with the system startup. For any subsequent Go, PHP, Node.js projects, just connect these container names through the Docker network, you can quickly get multi-version database support.


The commands in this article are all verified under Ubuntu 26.04, and Docker version 29.5.2.
If you have any questions or exchanges, please leave a message in the comment area.

]]>
https://www.shuijingwanwq.com/en/2026/06/01/15368/feed/ 0
Use Docker + VS Code Dev Container to build a Python music alarm clock development environment (WSL actual war record) https://www.shuijingwanwq.com/en/2026/04/22/10281/ https://www.shuijingwanwq.com/en/2026/04/22/10281/#respond Wed, 22 Apr 2026 07:30:53 +0000 https://www.shuijingwanwq.com/?p=10281 Post Views: 61

1. Background: Why do this environment

In order to learn AI programming tools (such as Tongyi Spirit Code), I am going to implement a ‘Music Alarm Clock’ small project.
Before starting coding, I set up a reusable python dev container development environment.

2. Description of the technology stack

  • Windows 10
  • WSL2 (Ubuntu)
  • docker
  • vs code
  • Python 3.10 (Alpine)
  • dev container

3. Project catalog structure (core focus)

music-alarm/
├── .devcontainer/
│ └── devcontainer.json
├── docker-compose.yml
├── main.py
├── requirements.txt
├── .gitignore
└── readme.md

✔ Explain each file function
📁 .devcontainer/devcontainer.json
VS Code Dev Container profile
to define:

  • which docker service to use
  • working directory
  • plugin
  • Automatically install dependencies
    📁 docker-compose.yml
    Define the python runtime container
  • python image
  • code mount
  • working directory /app
  • keep the container running
    📁 main.py
    Music Alarm Clock Core Logic Entrance
    It will be implemented here later:
  • timing task
  • Play music
    📁 Requirements.txt (reserved)
    Future AI / Music Alarm Clock Dependency Management File
    For example:
    schedule
    PlaySound
    📁 .gitignore
    to ignore:
  • python cache
  • IDE file
  • environmental variable

4. Dev container configuration instructions (emphasis).devcontainer/devcontainer.json

{
  "name": "Python Music Alarm Dev Container",

  "dockerComposeFile": ["../docker-compose.yml"],
  "service": "python",
  "workspaceFolder": "/app",

  "shutdownAction": "stopCompose",

  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance",
        "ms-azuretools.vscode-docker",
        "eamodio.gitlens"
      ],
      "settings": {
        "terminal.integrated.defaultProfile.linux": "sh",
        "python.defaultInterpreterPath": "/usr/local/bin/python"
      }
    }
  },

  "remoteUser": "root",

  "postCreateCommand": "apk update &amp;&amp; apk add git &amp;&amp; pip install --upgrade pip"
}

5. Docker-compose.yml Description (emphasis)

This file is used to start the Python development container and mount the local code:
volumes:

  • ./:/app

👉 Core meaning:

Guaranteed that the code is saved in the host (WSL) and will not be lost as the container is destroyed

services:
  python:
    image: python:3.10-alpine
    container_name: python-music-alarm

    working_dir: /app

    volumes:
      - ./:/app

    tty: true
    stdin_open: true

    command: tail -f /dev/null

    # &#x2714; 关键:保证 Git / VS Code 兼容
    environment:
      - PYTHONDONTWRITEBYTECODE=1
      - PYTHONUNBUFFERED=1

6. How to use VS CODE (operation steps)

Step 1: Open the project
code .
Step 2: Go to Dev Container
Ctrl + Shift + P
→ dev containers: reopen in containers
Step 3: Confirm the environment
python –version
git –version
Step 4: Open Git UI
ctrl + shift + g
Step 5: File – Save the workspace as C:\Users\ThinkPad\VSCodeWorkSpaces\python-music-alarm-app.code-workspace, which is convenient for opening the workspace directly from the file in the later stage

7. Verify whether the environment is successful, the directory structure on GitHub is shown in Figure 1

Verify that the environment is successful, the directory structure on GitHub


✔ python runs
✔ Git available
✔ VS Code into Dev Container
✔ The code is persistent (don’t lose)

8. Summary of this article
With Docker + Dev Container, I have completed a standardized Python development environment.
This has laid the foundation for the follow-up use of Tongyi Spirit Code to realize the ‘Music Alarm Clock’ project.

]]>
https://www.shuijingwanwq.com/en/2026/04/22/10281/feed/ 0
Configure domain names in MailTrap to use mail in development and test environments https://www.shuijingwanwq.com/en/2023/09/07/12337/ https://www.shuijingwanwq.com/en/2023/09/07/12337/#respond Thu, 07 Sep 2023 01:29:03 +0000 https://www.shuijingwanwq.com/?p=12337 Post Views: 16

1. Email testing test emails on staging. Click Start Testing. as shown in Figure 1

Email Testing Test Emails on Staging。点击 Start Testing

Figure 1

2. Click Show Credentials to display the corresponding vouchers. The corresponding credentials can then be copied to the configuration of the development environment. as shown in Figure 2

点击 Show Credentials,显示相应的凭证。然后可将相应的凭证复制到开发环境的配置中

Figure 2

3. Copy the sample code in the curl, and then paste it in the Linux terminal to test the sending of the email. as shown in Figure 3

复制 cURL 中的示例代码,然后在 Linux 终端中粘贴,以测试邮件的发送

Figure 3

4. Then you can see in the outbox that you have received an email. as shown in Figure 4

然后在发件箱中可看见已经收到了一封邮件

Figure 4

5. Use mail to send in the development environment. Finally, in the Outbox, you can view the content of the emails that have been sent. as shown in Figure 5

在开发环境中使用邮件发送。最后在 发件箱 中可以查看已经发送的邮件内容

Figure 5

]]>
https://www.shuijingwanwq.com/en/2023/09/07/12337/feed/ 0
After the WordPress system disk is redeployed (PHP 7.4 upgrade to PHP 8.1), prompt: This site encountered a fatal error. https://www.shuijingwanwq.com/en/2023/07/18/10140/ https://www.shuijingwanwq.com/en/2023/07/18/10140/#respond Tue, 18 Jul 2023 01:30:29 +0000 https://www.shuijingwanwq.com/?p=10140 Post Views: 75 1. Reference:In Alibaba Cloud ECS, CentOS 7 migration (replace) to Alibaba Cloud Linux 3 . After the WordPress system disk is redeployed, it prompts: This site encountered a fatal error. as shown in Figure 1
在 WordPress 的系统盘重新部署后,提示:此站点遇到了致命错误。

Figure 1

2. Learn more about troubleshooting WordPress. Enable developer-only: WordPress debug mode. Edit wp-config.php


/**
 * 开发者专用:WordPress 调试模式。
 *
 * 将这个值改为“true”,WordPress 将显示所有用于开发的提示。
 * 强烈建议插件开发者在开发环境中启用本功能。
 */
define('WP_DEBUG', true);


3. Refresh the page again, report an error


Deprecated: Return type of HMBackUpWordPressCleanUpIterator::accept() should either be compatible with FilterIterator::accept(): bool, or the #[ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in /data/wwwroot/www.shuijingwanwq.com/wp-content/plugins/backupwordpress/classes/class-path.php on line 456

Fatal error: Uncaught Error: Undefined constant &quot;wp_cumulus_widget&quot; in /data/wwwroot/www.shuijingwanwq.com/wp-content/plugins/wp-cumulus/wp-cumulus.php:375 Stack trace: #0 /data/wwwroot/www.shuijingwanwq.com/wp-includes/class-wp-hook.php(308): widget_init_wp_cumulus_widget() #1 /data/wwwroot/www.shuijingwanwq.com/wp-includes/class-wp-hook.php(332): WP_Hook-&gt;apply_filters() #2 /data/wwwroot/www.shuijingwanwq.com/wp-includes/plugin.php(517): WP_Hook-&gt;do_action() #3 /data/wwwroot/www.shuijingwanwq.com/wp-includes/widgets.php(1854): do_action() #4 /data/wwwroot/www.shuijingwanwq.com/wp-includes/class-wp-hook.php(308): wp_widgets_init() #5 /data/wwwroot/www.shuijingwanwq.com/wp-includes/class-wp-hook.php(332): WP_Hook-&gt;apply_filters() #6 /data/wwwroot/www.shuijingwanwq.com/wp-includes/plugin.php(517): WP_Hook-&gt;do_action() #7 /data/wwwroot/www.shuijingwanwq.com/wp-settings.php(623): do_action() #8 /data/wwwroot/www.shuijingwanwq.com/wp-config.php(87): require_once(&#039;...&#039;) #9 /data/wwwroot/www.shuijingwanwq.com/wp-load.php(50): require_once(&#039;...&#039;) #10 /data/wwwroot/www.shuijingwanwq.com/wp-blog-header.php(13): require_once(&#039;...&#039;) #11 /data/wwwroot/www.shuijingwanwq.com/index.php(17): require(&#039;...&#039;) #12 {main} thrown in /data/wwwroot/www.shuijingwanwq.com/wp-content/plugins/wp-cumulus/wp-cumulus.php on line 375


4. If it is found that they are all errors of the plugin, I decided to find a way to disable the plug-in that reports the error. Due to the WordPress dashboard, you need to disable plugins in different ways. Reference:How to Disable WordPress Plugin (4 Ways). 5. Reference:How to Disable WordPress Plugin via phpMyAdmin . Its essence is to operate data in the database. 6. Back up the database first, and then operate the data. Open the table wp_options, as shown in Figure 2
先备份数据库,再操作数据。打开表 wp_options

Figure 2

7. In the Options table, look for the active_plugins entry in the option_name column. Execute the following query SQL. as shown in Figure 3
在选项表中,在 option_name 列中查找 active_plugins 条目。执行以下查询 SQL

Figure 3



SELECT * FROM `wp_options` WHERE `option_name` = 'active_plugins'


8. Copy the value of the column OPTION_VALUE in the query result record, and use the PHP online deserialization tool.



a:14:{i:0;s:53:&quot;accelerated-mobile-pages/accelerated-moblie-pages.php&quot;;i:1;s:19:&quot;akismet/akismet.php&quot;;i:2;s:35:&quot;backupwordpress/backupwordpress.php&quot;;i:3;s:33:&quot;classic-editor/classic-editor.php&quot;;i:4;s:36:&quot;contact-form-7/wp-contact-form-7.php&quot;;i:5;s:45:&quot;disable-google-fonts/disable-google-fonts.php&quot;;i:6;s:72:&quot;golang-brush-for-syntaxhighlighter-evolved/syntaxhighlighter-GoBrush.php&quot;;i:7;s:25:&quot;hueman-addons/ha-fire.php&quot;;i:8;s:15:&quot;light/light.php&quot;;i:9;s:33:&quot;nimble-builder/nimble-builder.php&quot;;i:10;s:47:&quot;regenerate-thumbnails/regenerate-thumbnails.php&quot;;i:11;s:39:&quot;syntaxhighlighter/syntaxhighlighter.php&quot;;i:12;s:25:&quot;wp-cumulus/wp-cumulus.php&quot;;i:13;s:27:&quot;wp-pagenavi/wp-pagenavi.php&quot;;}


Array
(
    [0] =&gt; accelerated-mobile-pages/accelerated-moblie-pages.php
    [1] =&gt; akismet/akismet.php
    [2] =&gt; backupwordpress/backupwordpress.php
    [3] =&gt; classic-editor/classic-editor.php
    [4] =&gt; contact-form-7/wp-contact-form-7.php
    [5] =&gt; disable-google-fonts/disable-google-fonts.php
    [6] =&gt; golang-brush-for-syntaxhighlighter-evolved/syntaxhighlighter-GoBrush.php
    [7] =&gt; hueman-addons/ha-fire.php
    [8] =&gt; light/light.php
    [9] =&gt; nimble-builder/nimble-builder.php
    [10] =&gt; regenerate-thumbnails/regenerate-thumbnails.php
    [11] =&gt; syntaxhighlighter/syntaxhighlighter.php
    [12] =&gt; wp-cumulus/wp-cumulus.php
    [13] =&gt; wp-pagenavi/wp-pagenavi.php
)


9. Remove the plugin in the result of deserialization: backupwordpress/backupwordpress.php, wp-cumulus/wp-cumulus.php, and then php The serialized result is stored in the value of the column Option_VALUE. The PHP code is implemented as follows


<?php
$a = 'a:14:{i:0;s:53:"accelerated-mobile-pages/accelerated-moblie-pages.php";i:1;s:19:"akismet/akismet.php";i:2;s:35:"backupwordpress/backupwordpress.php";i:3;s:33:"classic-editor/classic-editor.php";i:4;s:36:"contact-form-7/wp-contact-form-7.php";i:5;s:45:"disable-google-fonts/disable-google-fonts.php";i:6;s:72:"golang-brush-for-syntaxhighlighter-evolved/syntaxhighlighter-GoBrush.php";i:7;s:25:"hueman-addons/ha-fire.php";i:8;s:15:"light/light.php";i:9;s:33:"nimble-builder/nimble-builder.php";i:10;s:47:"regenerate-thumbnails/regenerate-thumbnails.php";i:11;s:39:"syntaxhighlighter/syntaxhighlighter.php";i:12;s:25:"wp-cumulus/wp-cumulus.php";i:13;s:27:"wp-pagenavi/wp-pagenavi.php";}';
$b = unserialize($a);
print_r($b);
$c = [
    'accelerated-mobile-pages/accelerated-moblie-pages.php',
    'akismet/akismet.php',
    'classic-editor/classic-editor.php',
    'contact-form-7/wp-contact-form-7.php',
    'disable-google-fonts/disable-google-fonts.php',
    'golang-brush-for-syntaxhighlighter-evolved/syntaxhighlighter-GoBrush.php',
    'hueman-addons/ha-fire.php',
    'light/light.php',
    'nimble-builder/nimble-builder.php',
    'regenerate-thumbnails/regenerate-thumbnails.php',
    'syntaxhighlighter/syntaxhighlighter.php',
    'wp-pagenavi/wp-pagenavi.php'
];
print_r($c);
$d = serialize($c);
print_r($d);
exit;
?>





Array
(
    [0] =&gt; accelerated-mobile-pages/accelerated-moblie-pages.php
    [1] =&gt; akismet/akismet.php
    [2] =&gt; classic-editor/classic-editor.php
    [3] =&gt; contact-form-7/wp-contact-form-7.php
    [4] =&gt; disable-google-fonts/disable-google-fonts.php
    [5] =&gt; golang-brush-for-syntaxhighlighter-evolved/syntaxhighlighter-GoBrush.php
    [6] =&gt; hueman-addons/ha-fire.php
    [7] =&gt; light/light.php
    [8] =&gt; nimble-builder/nimble-builder.php
    [9] =&gt; regenerate-thumbnails/regenerate-thumbnails.php
    [10] =&gt; syntaxhighlighter/syntaxhighlighter.php
    [11] =&gt; wp-pagenavi/wp-pagenavi.php
)

a:12:{i:0;s:53:&quot;accelerated-mobile-pages/accelerated-moblie-pages.php&quot;;i:1;s:19:&quot;akismet/akismet.php&quot;;i:2;s:33:&quot;classic-editor/classic-editor.php&quot;;i:3;s:36:&quot;contact-form-7/wp-contact-form-7.php&quot;;i:4;s:45:&quot;disable-google-fonts/disable-google-fonts.php&quot;;i:5;s:72:&quot;golang-brush-for-syntaxhighlighter-evolved/syntaxhighlighter-GoBrush.php&quot;;i:6;s:25:&quot;hueman-addons/ha-fire.php&quot;;i:7;s:15:&quot;light/light.php&quot;;i:8;s:33:&quot;nimble-builder/nimble-builder.php&quot;;i:9;s:47:&quot;regenerate-thumbnails/regenerate-thumbnails.php&quot;;i:10;s:39:&quot;syntaxhighlighter/syntaxhighlighter.php&quot;;i:11;s:27:&quot;wp-pagenavi/wp-pagenavi.php&quot;;}




UPDATE `shuijingwanwq`.`wp_options` SET `option_value`='a:12:{i:0;s:53:"accelerated-mobile-pages/accelerated-moblie-pages.php";i:1;s:19:"akismet/akismet.php";i:2;s:33:"classic-editor/classic-editor.php";i:3;s:36:"contact-form-7/wp-contact-form-7.php";i:4;s:45:"disable-google-fonts/disable-google-fonts.php";i:5;s:72:"golang-brush-for-syntaxhighlighter-evolved/syntaxhighlighter-GoBrush.php";i:6;s:25:"hueman-addons/ha-fire.php";i:7;s:15:"light/light.php";i:8;s:33:"nimble-builder/nimble-builder.php";i:9;s:47:"regenerate-thumbnails/regenerate-thumbnails.php";i:10;s:39:"syntaxhighlighter/syntaxhighlighter.php";i:11;s:27:"wp-pagenavi/wp-pagenavi.php";}' WHERE `option_id`=35;


10. After restoring the changes in step 2, refresh the page again, and the display is normal.]]>
https://www.shuijingwanwq.com/en/2023/07/18/10140/feed/ 0
Build a Laravel Sail development environment in Windows 10 Professional https://www.shuijingwanwq.com/en/2021/12/23/9949/ https://www.shuijingwanwq.com/en/2021/12/23/9949/#respond Thu, 23 Dec 2021 01:45:36 +0000 https://www.shuijingwanwq.com/?p=9949 Post Views: 109 1. Laravel Sail requires Windows 10 systems that support WSL 2. The 2004 version released in May 2020 only supports the WSL 2 function, so our system needs to be updated to the 2004 version equal to or greater than the 2004 version. To view the system version, you can use the winver command, refer to Windows 10 Release Information, the release time of the version is greater than 1909. The system version meets the requirements. as shown in Figure 1
查看系统版本,可以使用 winver 命令,参考 Windows 10 release information ,版本的发布时间大于 1909 即可。

Figure 1

2. First upgrade to: the latest 21H1 version based on 360. as shown in Figure 2
先基于 360 升级至:最新的 21H1 的版本。

Figure 2

3. Check the system version, it has been upgraded to: 21h1 version. as shown in Figure 3
查看系统版本,已经升级至:21H1 的版本。

Figure 3

4. Search to open the windows function management window to ensure that the two places in the red box in the figure below are enabled: Windows subsystem for Linux, remote differential compression API support. as shown in Figure 4
搜索打开 Windows 功能管理 窗口,确保下图红框框住的两个地方都已开启:适用于 Linux 的 Windows 子系统、远程差分压缩 API 支持。

Figure 4

5. In order to better access the Windows subsystem, it is recommended to use Windows Terminal as a command line tool. Open the Microsoft store, search for the keyword Windows Terminal, and click Install in the search results. as shown in Figure 5
为了更好地访问 Windows 的子系统,推荐使用 Windows Terminal 作为命令行工具。打开微软商店,搜索关键字 Windows Terminal ,在搜索结果中点击安装即可。

Figure 5

6. Download and install the subsystem: Ubuntu. Open the Microsoft store, search for ubuntu, the first and second can be, select the second one: ubuntu 20.04 LTS. as shown in Figure 6
下载和安装子系统:Ubuntu 。打开微软商店,搜索关键词 Ubuntu,第一和第二个都可以,选择第二个:Ubuntu 20.04 LTS。

Figure 6

7. Prompt to create a user of the Ubuntu system, enter the user name, and then enter the password to complete the installation of the Ubuntu subsystem. This Ubuntu is a subsystem of the current Windows system, and our Docker will run based on this system. as shown in Figure 7
提示创建一个 Ubuntu 系统的用户,输入用户名,接下来输入密码即可完成 Ubuntu 子系统的安装。这个 Ubuntu 为当前 Windows 系统的子系统,接下来我们的 Docker 会基于此系统运行。

Figure 7

8. Go to Docker official website to download Docker Desktop: https://hub.docker.com/editions/community/docker-ce-desktop-windows After the download is complete, click the installation package to install, and you can go all the way. 9. Tips: WSL 2 Installation is incomplete. WSL 2 installation is incomplete. as shown in Figure 8
提示:WSL 2 installation is incomplete. WSL 2 安装不完整。

8



WSL 2 installation is incomplete.
The WSL 2 Linux kernel is now installed using a separate MSI update package. Please click the link and follow the instructions to install the kernel update:https://aka.ms/wsl2kernel

Press restart after installing the Linux kernel


10. Click the link and follow the instructions to install the kernel update: https://aka.ms/wsl2kernel . Download and install the Linux kernel update package. as shown in Figure 9
点击链接并按照说明安装内核更新:https://aka.ms/wsl2kernel 。下载并安装 Linux 内核更新包。

Figure 9

11. Restart the computer, open Docker Desktop again, and report an error: Docker failed to initialize. Ignore it for now. As shown in Figure 10
重启电脑,再次打开 Docker Desktop,报错:Docker failed to initialize。暂时不用理会。

Figure 10

12. After restarting the computer again. Open Docker Desktop, no errors are reported again. Go to the configuration page – General, Use the WSL 2 based engine is checked by default, and enable WSL2 mode. as shown in Figure 11
再次重启电脑后。打开 Docker Desktop,未再报错。进入配置页面 - General,默认已勾选 Use the WSL 2 based engine,开启 WSL2 模式。

Figure 11

13. Configuration – Resources – WSL Integration, select the Ubuntu system we installed in the previous step, but the Ubuntu option does not exist. as shown in Figure 12
配置 - Resources - WSL Integration,选择我们上一步安装的 Ubuntu 系统,但是不存在 ubuntu 选项。

Figure 12

14. Reference URL: https://learnku.com/articles/54890. Open: Windows Terminal, convert to WSL 2. as shown in Figure 13
参考网址:https://learnku.com/articles/54890 。打开:Windows Terminal,转换为 WSL 2。

Figure 13



PS C:\Users\Lenovo> wsl --list --verbose
  NAME                   STATE           VERSION
* Ubuntu-20.04           Running         1
  docker-desktop-data    Running         2
  docker-desktop         Running         2
PS C:\Users\Lenovo> wsl --set-version Ubuntu-20.04 2
正在进行转换,这可能需要几分钟时间...
有关与 WSL 2 的主要区别的信息,请访问 https://aka.ms/wsl2
转换完成。
PS C:\Users\Lenovo>


15. Click the button Refresh, the option ubuntu-20.04 has appeared, turn on. Figure 14
点击按钮 Refresh,选项 Ubuntu-20.04 已经出现,开启。

Figure 14

16. Create a test project, open the Windows Terminal command line, and follow the instructions below to enter the Ubuntu system. as shown in Figure 15
创建测试项目,打开 Windows Terminal 命令行,按照以下指示进入 Ubuntu 系统。

Figure 15

17. Ubuntu, as a Windows subsystem, can access the hard disk under the main system. In order to facilitate the management code, I have already created the wwwroot directory under the E drive. After entering this directory, I use the following command to create a test Laravel project. as shown in Figure 16
Ubuntu 作为 Windows 子系统,可以访问到主系统下的硬盘。为了方便管理代码,我在 E 盘下早已创建了 wwwroot 目录,进入此目录后,使用以下命令进行创建一个测试的 Laravel 项目。

Figure 16



wangqiang@DESKTOP-QLPK8QM:/mnt/c/Users/Lenovo$ cd /mnt/e
wangqiang@DESKTOP-QLPK8QM:/mnt/e$ ls
'$RECYCLE.BIN'  'System Volume Information'   cms   pagefile.sys    phpuploadtmp
 Develop         c                            css   phpsessiontmp   wwwroot
wangqiang@DESKTOP-QLPK8QM:/mnt/e$ cd wwwroot/
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot$ curl -s https://laravel.build/example-app | bash
Unable to find image 'laravelsail/php81-composer:latest' locally
latest: Pulling from laravelsail/php81-composer
eff15d958d66: Pull complete
933427dc39f7: Pull complete
35bb08dc7ee2: Pull complete
58a3f26800d7: Pull complete
28803bfad74c: Pull complete
341a482d0bd3: Pull complete
03c4148389b1: Pull complete
fa3a9bfc7793: Pull complete
024907232600: Pull complete
df5987d70de6: Pull complete
e2a72a518bd8: Pull complete
b1ba689993c8: Pull complete
3bd142ab0b85: Pull complete
872fe34989f0: Pull complete
Digest: sha256:b27920b769ad8dc036a9ede3ae36f51a280d370ec7d125e77ca1924c9fa21dbb
Status: Downloaded newer image for laravelsail/php81-composer:latest

 _                               _
| |                             | |
| |     __ _ _ __ __ ___   _____| |
| |    / _` | '__/ _` \ \ / / _ \ |
| |___| (_| | | | (_| |\ V /  __/ |
|______\__,_|_|  \__,_| \_/ \___|_|

Warning: TTY mode requires /dev/tty to be read/writable.
    Creating a "laravel/laravel" project at "./example-app"
    Installing laravel/laravel (v8.6.9)
      - Downloading laravel/laravel (v8.6.9)
      - Installing laravel/laravel (v8.6.9): Extracting archive
    Created project in /opt/example-app
    > @php -r "file_exists('.env') || copy('.env.example', '.env');"
    Loading composer repositories with package information
    Updating dependencies
    Lock file operations: 110 installs, 0 updates, 0 removals
      - Locking asm89/stack-cors (v2.0.3)
  - Locking brick/math (0.9.3)
      - Locking dflydev/dot-access-data (v3.0.1)
  - Locking doctrine/inflector (2.0.4)
      - Locking doctrine/instantiator (1.4.0)
      - Locking doctrine/lexer (1.2.1)
  - Locking dragonmantank/cron-expression (v3.1.0)
      - Locking egulias/email-validator (2.1.25)
      - Locking facade/flare-client-php (1.9.1)
      - Locking facade/ignition (2.17.2)
      - Locking facade/ignition-contracts (1.0.2)
      - Locking fakerphp/faker (v1.17.0)
      - Locking filp/whoops (2.14.4)
      - Locking fruitcake/laravel-cors (v2.0.4)
      - Locking graham-campbell/result-type (v1.0.4)
  - Locking guzzlehttp/guzzle (7.4.1)
  - Locking guzzlehttp/promises (1.5.1)
  - Locking guzzlehttp/psr7 (2.1.0)
      - Locking hamcrest/hamcrest-php (v2.0.1)
  - Locking laravel/framework (v8.76.2)
  - Locking laravel/sail (v1.12.12)
  - Locking laravel/sanctum (v2.13.0)
  - Locking laravel/serializable-closure (v1.0.5)
      - Locking laravel/tinker (v2.6.3)
  - Locking league/commonmark (2.1.0)
  - Locking league/config (v1.1.1)
  - Locking league/flysystem (1.1.9)
  - Locking league/mime-type-detection (1.9.0)
      - Locking mockery/mockery (1.4.4)
  - Locking monolog/monolog (2.3.5)
      - Locking myclabs/deep-copy (1.10.2)
  - Locking nesbot/carbon (2.55.2)
      - Locking nette/schema (v1.2.2)
      - Locking nette/utils (v3.2.6)
      - Locking nikic/php-parser (v4.13.2)
      - Locking nunomaduro/collision (v5.10.0)
      - Locking opis/closure (3.6.2)
      - Locking phar-io/manifest (2.0.3)
      - Locking phar-io/version (3.1.0)
      - Locking phpdocumentor/reflection-common (2.2.0)
      - Locking phpdocumentor/reflection-docblock (5.3.0)
      - Locking phpdocumentor/type-resolver (1.5.1)
      - Locking phpoption/phpoption (1.8.1)
  - Locking phpspec/prophecy (v1.15.0)
      - Locking phpunit/php-code-coverage (9.2.10)
  - Locking phpunit/php-file-iterator (3.0.6)
      - Locking phpunit/php-invoker (3.1.1)
  - Locking phpunit/php-text-template (2.0.4)
      - Locking phpunit/php-timer (5.0.3)
  - Locking phpunit/phpunit (9.5.10)
      - Locking psr/container (1.1.2)
      - Locking psr/event-dispatcher (1.0.0)
      - Locking psr/http-client (1.0.1)
      - Locking psr/http-factory (1.0.1)
  - Locking psr/http-message (1.0.1)
  - Locking psr/log (2.0.0)
  - Locking psr/simple-cache (1.0.1)
      - Locking psy/psysh (v0.10.12)
  - Locking ralouphie/getallheaders (3.0.3)
      - Locking ramsey/collection (1.2.2)
      - Locking ramsey/uuid (4.2.3)
  - Locking sebastian/cli-parser (1.0.1)
      - Locking sebastian/code-unit (1.0.8)
      - Locking sebastian/code-unit-reverse-lookup (2.0.3)
  - Locking sebastian/comparator (4.0.6)
  - Locking sebastian/complexity (2.0.2)
      - Locking sebastian/diff (4.0.4)
      - Locking sebastian/environment (5.1.3)
  - Locking sebastian/exporter (4.0.4)
      - Locking sebastian/global-state (5.0.3)
  - Locking sebastian/lines-of-code (1.0.3)
      - Locking sebastian/object-enumerator (4.0.4)
  - Locking sebastian/object-reflector (2.0.4)
      - Locking sebastian/recursion-context (4.0.4)
      - Locking sebastian/resource-operations (3.0.3)
      - Locking sebastian/type (2.3.4)
      - Locking sebastian/version (3.0.2)
      - Locking swiftmailer/swiftmailer (v6.3.0)
      - Locking symfony/console (v5.4.1)
      - Locking symfony/css-selector (v6.0.1)
  - Locking symfony/deprecation-contracts (v3.0.0)
      - Locking symfony/error-handler (v5.4.1)
      - Locking symfony/event-dispatcher (v6.0.1)
      - Locking symfony/event-dispatcher-contracts (v3.0.0)
      - Locking symfony/finder (v5.4.0)
  - Locking symfony/http-foundation (v5.4.1)
      - Locking symfony/http-kernel (v5.4.1)
  - Locking symfony/mime (v5.4.0)
      - Locking symfony/polyfill-ctype (v1.23.0)
      - Locking symfony/polyfill-iconv (v1.23.0)
      - Locking symfony/polyfill-intl-grapheme (v1.23.1)
  - Locking symfony/polyfill-intl-idn (v1.23.0)
      - Locking symfony/polyfill-intl-normalizer (v1.23.0)
      - Locking symfony/polyfill-mbstring (v1.23.1)
  - Locking symfony/polyfill-php72 (v1.23.0)
      - Locking symfony/polyfill-php73 (v1.23.0)
      - Locking symfony/polyfill-php80 (v1.23.1)
      - Locking symfony/polyfill-php81 (v1.23.0)
      - Locking symfony/process (v5.4.0)
      - Locking symfony/routing (v5.4.0)
      - Locking symfony/service-contracts (v2.4.1)
      - Locking symfony/string (v6.0.1)
  - Locking symfony/translation (v6.0.1)
      - Locking symfony/translation-contracts (v3.0.0)
      - Locking symfony/var-dumper (v5.4.1)
      - Locking theseer/tokenizer (1.2.1)
      - Locking tijsverkoyen/css-to-inline-styles (2.2.4)
      - Locking vlucas/phpdotenv (v5.4.1)
      - Locking voku/portable-ascii (1.5.6)
  - Locking webmozart/assert (1.10.0)
    Writing lock file
    Installing dependencies from lock file (including require-dev)
    Package operations: 110 installs, 0 updates, 0 removals
      - Downloading doctrine/inflector (2.0.4)
      - Downloading doctrine/lexer (1.2.1)
      - Downloading dragonmantank/cron-expression (v3.1.0)
      - Downloading symfony/var-dumper (v5.4.1)
      - Downloading symfony/string (v6.0.1)
      - Downloading psr/container (1.1.2)
      - Downloading symfony/service-contracts (v2.4.1)
      - Downloading symfony/console (v5.4.1)
      - Downloading psr/log (2.0.0)
      - Downloading monolog/monolog (2.3.5)
      - Downloading voku/portable-ascii (1.5.6)
      - Downloading phpoption/phpoption (1.8.1)
      - Downloading graham-campbell/result-type (v1.0.4)
      - Downloading vlucas/phpdotenv (v5.4.1)
      - Downloading symfony/css-selector (v6.0.1)
      - Downloading tijsverkoyen/css-to-inline-styles (2.2.4)
      - Downloading symfony/routing (v5.4.0)
      - Downloading symfony/polyfill-php72 (v1.23.0)
      - Downloading symfony/polyfill-intl-idn (v1.23.0)
      - Downloading symfony/mime (v5.4.0)
      - Downloading symfony/http-foundation (v5.4.1)
      - Downloading psr/event-dispatcher (1.0.0)
      - Downloading symfony/event-dispatcher-contracts (v3.0.0)
      - Downloading symfony/event-dispatcher (v6.0.1)
      - Downloading symfony/error-handler (v5.4.1)
      - Downloading symfony/http-kernel (v5.4.1)
      - Downloading symfony/finder (v5.4.0)
      - Downloading symfony/polyfill-iconv (v1.23.0)
      - Downloading egulias/email-validator (2.1.25)
      - Downloading swiftmailer/swiftmailer (v6.3.0)
      - Downloading symfony/polyfill-php81 (v1.23.0)
      - Downloading ramsey/collection (1.2.2)
      - Downloading brick/math (0.9.3)
      - Downloading ramsey/uuid (4.2.3)
      - Downloading psr/simple-cache (1.0.1)
      - Downloading opis/closure (3.6.2)
      - Downloading symfony/translation-contracts (v3.0.0)
      - Downloading symfony/translation (v6.0.1)
      - Downloading nesbot/carbon (2.55.2)
      - Downloading league/mime-type-detection (1.9.0)
      - Downloading league/flysystem (1.1.9)
      - Downloading nette/utils (v3.2.6)
      - Downloading nette/schema (v1.2.2)
      - Downloading dflydev/dot-access-data (v3.0.1)
      - Downloading league/config (v1.1.1)
      - Downloading league/commonmark (2.1.0)
      - Downloading laravel/serializable-closure (v1.0.5)
      - Downloading laravel/framework (v8.76.2)
      - Downloading facade/ignition-contracts (1.0.2)
      - Downloading facade/flare-client-php (1.9.1)
      - Downloading facade/ignition (2.17.2)
      - Downloading fakerphp/faker (v1.17.0)
      - Downloading asm89/stack-cors (v2.0.3)
      - Downloading fruitcake/laravel-cors (v2.0.4)
      - Downloading psr/http-message (1.0.1)
      - Downloading psr/http-client (1.0.1)
      - Downloading ralouphie/getallheaders (3.0.3)
      - Downloading psr/http-factory (1.0.1)
      - Downloading guzzlehttp/psr7 (2.1.0)
      - Downloading guzzlehttp/promises (1.5.1)
      - Downloading guzzlehttp/guzzle (7.4.1)
      - Downloading laravel/sail (v1.12.12)
      - Downloading laravel/sanctum (v2.13.0)
      - Downloading nikic/php-parser (v4.13.2)
      - Downloading psy/psysh (v0.10.12)
      - Downloading laravel/tinker (v2.6.3)
      - Downloading hamcrest/hamcrest-php (v2.0.1)
      - Downloading mockery/mockery (1.4.4)
      - Downloading filp/whoops (2.14.4)
      - Downloading nunomaduro/collision (v5.10.0)
      - Downloading phpunit/php-file-iterator (3.0.6)
      - Downloading phpunit/php-code-coverage (9.2.10)
      - Downloading phpspec/prophecy (v1.15.0)
      - Installing doctrine/inflector (2.0.4): Extracting archive
      - Installing doctrine/lexer (1.2.1): Extracting archive
      - Installing symfony/polyfill-ctype (v1.23.0): Extracting archive
      - Installing webmozart/assert (1.10.0): Extracting archive
      - Installing dragonmantank/cron-expression (v3.1.0): Extracting archive
      - Installing symfony/polyfill-php80 (v1.23.1): Extracting archive
      - Installing symfony/polyfill-mbstring (v1.23.1): Extracting archive
      - Installing symfony/var-dumper (v5.4.1): Extracting archive
      - Installing symfony/polyfill-intl-normalizer (v1.23.0): Extracting archive
      - Installing symfony/polyfill-intl-grapheme (v1.23.1): Extracting archive
      - Installing symfony/string (v6.0.1): Extracting archive
      - Installing psr/container (1.1.2): Extracting archive
      - Installing symfony/service-contracts (v2.4.1): Extracting archive
      - Installing symfony/polyfill-php73 (v1.23.0): Extracting archive
      - Installing symfony/deprecation-contracts (v3.0.0): Extracting archive
      - Installing symfony/console (v5.4.1): Extracting archive
      - Installing psr/log (2.0.0): Extracting archive
      - Installing monolog/monolog (2.3.5): Extracting archive
      - Installing voku/portable-ascii (1.5.6): Extracting archive
      - Installing phpoption/phpoption (1.8.1): Extracting archive
      - Installing graham-campbell/result-type (v1.0.4): Extracting archive
      - Installing vlucas/phpdotenv (v5.4.1): Extracting archive
      - Installing symfony/css-selector (v6.0.1): Extracting archive
      - Installing tijsverkoyen/css-to-inline-styles (2.2.4): Extracting archive
      - Installing symfony/routing (v5.4.0): Extracting archive
      - Installing symfony/process (v5.4.0): Extracting archive
      - Installing symfony/polyfill-php72 (v1.23.0): Extracting archive
      - Installing symfony/polyfill-intl-idn (v1.23.0): Extracting archive
      - Installing symfony/mime (v5.4.0): Extracting archive
      - Installing symfony/http-foundation (v5.4.1): Extracting archive
      - Installing psr/event-dispatcher (1.0.0): Extracting archive
      - Installing symfony/event-dispatcher-contracts (v3.0.0): Extracting archive
      - Installing symfony/event-dispatcher (v6.0.1): Extracting archive
      - Installing symfony/error-handler (v5.4.1): Extracting archive
      - Installing symfony/http-kernel (v5.4.1): Extracting archive
      - Installing symfony/finder (v5.4.0): Extracting archive
      - Installing symfony/polyfill-iconv (v1.23.0): Extracting archive
      - Installing egulias/email-validator (2.1.25): Extracting archive
      - Installing swiftmailer/swiftmailer (v6.3.0): Extracting archive
      - Installing symfony/polyfill-php81 (v1.23.0): Extracting archive
      - Installing ramsey/collection (1.2.2): Extracting archive
      - Installing brick/math (0.9.3): Extracting archive
      - Installing ramsey/uuid (4.2.3): Extracting archive
      - Installing psr/simple-cache (1.0.1): Extracting archive
      - Installing opis/closure (3.6.2): Extracting archive
      - Installing symfony/translation-contracts (v3.0.0): Extracting archive
      - Installing symfony/translation (v6.0.1): Extracting archive
      - Installing nesbot/carbon (2.55.2): Extracting archive
      - Installing league/mime-type-detection (1.9.0): Extracting archive
      - Installing league/flysystem (1.1.9): Extracting archive
      - Installing nette/utils (v3.2.6): Extracting archive
      - Installing nette/schema (v1.2.2): Extracting archive
      - Installing dflydev/dot-access-data (v3.0.1): Extracting archive
      - Installing league/config (v1.1.1): Extracting archive
      - Installing league/commonmark (2.1.0): Extracting archive
      - Installing laravel/serializable-closure (v1.0.5): Extracting archive
      - Installing laravel/framework (v8.76.2): Extracting archive
      - Installing facade/ignition-contracts (1.0.2): Extracting archive
      - Installing facade/flare-client-php (1.9.1): Extracting archive
      - Installing facade/ignition (2.17.2): Extracting archive
      - Installing fakerphp/faker (v1.17.0): Extracting archive
      - Installing asm89/stack-cors (v2.0.3): Extracting archive
      - Installing fruitcake/laravel-cors (v2.0.4): Extracting archive
      - Installing psr/http-message (1.0.1): Extracting archive
      - Installing psr/http-client (1.0.1): Extracting archive
      - Installing ralouphie/getallheaders (3.0.3): Extracting archive
      - Installing psr/http-factory (1.0.1): Extracting archive
      - Installing guzzlehttp/psr7 (2.1.0): Extracting archive
      - Installing guzzlehttp/promises (1.5.1): Extracting archive
      - Installing guzzlehttp/guzzle (7.4.1): Extracting archive
      - Installing laravel/sail (v1.12.12): Extracting archive
      - Installing laravel/sanctum (v2.13.0): Extracting archive
      - Installing nikic/php-parser (v4.13.2): Extracting archive
      - Installing psy/psysh (v0.10.12): Extracting archive
      - Installing laravel/tinker (v2.6.3): Extracting archive
      - Installing hamcrest/hamcrest-php (v2.0.1): Extracting archive
      - Installing mockery/mockery (1.4.4): Extracting archive
      - Installing filp/whoops (2.14.4): Extracting archive
      - Installing nunomaduro/collision (v5.10.0): Extracting archive
      - Installing phpdocumentor/reflection-common (2.2.0): Extracting archive
      - Installing phpdocumentor/type-resolver (1.5.1): Extracting archive
      - Installing phpdocumentor/reflection-docblock (5.3.0): Extracting archive
      - Installing sebastian/version (3.0.2): Extracting archive
      - Installing sebastian/type (2.3.4): Extracting archive
      - Installing sebastian/resource-operations (3.0.3): Extracting archive
      - Installing sebastian/recursion-context (4.0.4): Extracting archive
      - Installing sebastian/object-reflector (2.0.4): Extracting archive
      - Installing sebastian/object-enumerator (4.0.4): Extracting archive
      - Installing sebastian/global-state (5.0.3): Extracting archive
      - Installing sebastian/exporter (4.0.4): Extracting archive
      - Installing sebastian/environment (5.1.3): Extracting archive
      - Installing sebastian/diff (4.0.4): Extracting archive
      - Installing sebastian/comparator (4.0.6): Extracting archive
      - Installing sebastian/code-unit (1.0.8): Extracting archive
      - Installing sebastian/cli-parser (1.0.1): Extracting archive
      - Installing phpunit/php-timer (5.0.3): Extracting archive
      - Installing phpunit/php-text-template (2.0.4): Extracting archive
      - Installing phpunit/php-invoker (3.1.1): Extracting archive
      - Installing phpunit/php-file-iterator (3.0.6): Extracting archive
      - Installing theseer/tokenizer (1.2.1): Extracting archive
      - Installing sebastian/lines-of-code (1.0.3): Extracting archive
      - Installing sebastian/complexity (2.0.2): Extracting archive
      - Installing sebastian/code-unit-reverse-lookup (2.0.3): Extracting archive
      - Installing phpunit/php-code-coverage (9.2.10): Extracting archive
      - Installing doctrine/instantiator (1.4.0): Extracting archive
      - Installing phpspec/prophecy (v1.15.0): Extracting archive
      - Installing phar-io/version (3.1.0): Extracting archive
      - Installing phar-io/manifest (2.0.3): Extracting archive
      - Installing myclabs/deep-copy (1.10.2): Extracting archive
      - Installing phpunit/phpunit (9.5.10): Extracting archive
    76 package suggestions were added by new dependencies, use `composer suggest` to see details.
    Package swiftmailer/swiftmailer is abandoned, you should avoid using it. Use symfony/mailer instead.
Generating optimized autoload files
    > Illuminate\Foundation\ComposerScripts::postAutoloadDump
    > @php artisan package:discover --ansi
    Discovered Package: facade/ignition
Discovered Package: fruitcake/laravel-cors
Discovered Package: laravel/sail
Discovered Package: laravel/sanctum
    Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
    Discovered Package: nunomaduro/collision
    Package manifest generated successfully.
    77 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
    > @php artisan vendor:publish --tag=laravel-assets --ansi --force
    No publishable resources for tag [laravel-assets].
Publishing complete.
    > @php artisan key:generate --ansi
    Application key set successfully.

Application ready! Build something amazing.
Sail scaffolding installed successfully.

Please provide your password so we can make some final adjustments to your application's permissions.

[sudo] password for wangqiang:

Thank you! We hope you build something incredible. Dive in with: cd example-app && ./vendor/bin/sail up
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot$


18. Finally create a successful interface. as shown in Figure 17
最终创建成功的界面。

Figure 17

19. Open the E:\wwwroot\example-app directory. as shown in Figure 18
打开 E:\wwwroot\example-app 目录。

18

20. To view the Dockerfile file, Laravel 8 uses the Dockerfile under the vendor/Laravel/sail/runtimes/8.0 directory by default. as shown in Figure 19
查看 Dockerfile 文件,Laravel 8 默认用的是 vendor/laravel/sail/runtimes/8.0 目录下的 Dockerfile。

Figure 19

21. Run the container, and in the root directory of the project, execute the following command: ./vendor/bin/sail up. The first time it runs, the container is initialized. It is recommended to turn over the wall. I generally don’t tend to use domestic mirrors. report an error. As shown in Figure 20
运行容器,在项目的根目录下,执行以下命令:./vendor/bin/sail up。第一次运行的时候,会初始化容器。建议翻墙。我一般不倾向于使用国内的镜像。报错。

Figure 20



ERROR: for mysql  Cannot start service mysql: Ports are not available: listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/network address/port) is normally permitted.
ERROR: Encountered errors while bringing up the project.


22. The reason should be that the local MySQL database has used port 3306, and it is decided to first modify the port of the local MySQL database to 3307. Open the directory C:\ProgramData\MySQL\MySQL Server 5.7, and edit the my.ini file.


[client]

# pipe
# socket=0.0
port=3307


[mysqld]

# The next three options are mutually exclusive to SERVER_PORT below.
# skip-networking

# enable-named-pipe

# shared-memory

# shared-memory-base-name=MYSQL

# The Pipe the MySQL Server will use
# socket=MYSQL

# The TCP/IP Port the MySQL Server will listen on
port=3307


23. After restarting the computer, the connection to the local MySQL database is successful based on port 3307. as shown in Figure 21
重启电脑后,基于端口 3307 连接本地 mysql 数据库成功。

Figure 21

24. Run the command again: ./vendor/bin/sail up. It will start running from MySQL, and the total time it takes 20 minutes. After the Sail up command runs successfully, the real-time log interface of the software will always be displayed. Figure 22
再次运行命令:./vendor/bin/sail up。会从 mysql 处开始运行,总计耗费时长:。sail up 命令运行成功后,会一直显示软件的实时日志界面。

Figure 22

25. At this time, you can run Ctrl+C interrupts. When running again, you can use the -d parameter to make the Sail up command run in the background. Figure 23
此时你可以 ctrl+c 中断运行,再次运行时,可以使用 -d 参数让 sail up 命令在后台运行。

Figure 23



meilisearch_1   | [2021-12-21T03:09:36Z INFO  actix_web::middleware::logger] 127.0.0.1:51806 "GET /health HTTP/1.1" 200 22 "-" "Wget" 0.000297
^CGracefully stopping... (press Ctrl+C again to force)
Stopping example-app_laravel.test_1 ... done
Stopping example-app_mailhog_1      ... done
Stopping example-app_mysql_1        ... done
Stopping example-app_selenium_1     ... done
Stopping example-app_redis_1        ... done
Stopping example-app_meilisearch_1  ... done
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/example-app$ ./vendor/bin/sail up -d
example-app_laravel.test_1   start-container                  Exit 137
Shutting down old Sail processes...
Creating network "example-app_sail" with driver "bridge"
Creating example-app_redis_1       ... done
Creating example-app_mailhog_1     ... done
Creating example-app_meilisearch_1 ... done
Creating example-app_selenium_1    ... done
Creating example-app_mysql_1       ... done
Creating example-app_laravel.test_1 ... done
wangqiang@DESKTOP-QLPK8QM:/mnt/e/wwwroot/example-app$


26. Open Docker Desktop, there is a container in the container list: example-app, and the status is running. Figure 24
打开 Docker Desktop,容器列表中存在容器:example-app,状态为运行中。

Figure 24

27. Open the URL in the browser: http://localhost/ , and the response is 200. Laravel v8.76.2 (PHP v8.1.0). The development environment is successfully deployed. as shown in Figure 25
在浏览器中打开网址:http://localhost/ ,响应 200 。Laravel v8.76.2 (PHP v8.1.0)。开发环境部署成功。

Figure 25

28. In response to the problem of port 3306 being occupied, there is another solution, that is, the port of modifying the container is 43306. The local MySQL database still uses port 3306. The plan is subsequently implemented based on Nginx Proxy Manager. 29. Edit the C:/Windows/System32/drivers/etc/hosts file, and specify the mapping relationship between IP and domain name.


127.0.0.1 example-app.test


30. Open the URL in the browser: http://example-app.test/ . Response 200. Figure 26
在浏览器中打开网址:http://example-app.test/ 。响应 200。

Figure 26

]]>
https://www.shuijingwanwq.com/en/2021/12/23/9949/feed/ 0