抖声项目搭建本地Docker测试环境 | 青训营

146 阅读6分钟

之前项目开发一直是在1024code上面进行,1024code还是非常方便,集成了git、数据库(包括MySQL,Redis,PostgreSQL)、可远程访问的服务器地址、以及一个可以多人在线协作的网页IDE编辑器、等等等等方便快捷的功能。

当然,这个IDE肯定不如GoLand或者VS Code那么强大,对于像我这样的Golang新手来说还是有点不太友好。

一番挣扎之后,还是决定尝试利用Docker搭建一个本地的测试环境。得益于Docker优秀的跨平台无障碍的特性,如果我能够成功地搭建起这个测试环境,那么我的小伙伴们也可以直接使用了。

写个笔记记录一下搭建和测试的过程。

前置工作

前置工作当然是确保本地已经安装好了Docker。

Windows: docs.docker.com/desktop/ins…

MacOS: docs.docker.com/desktop/ins…

环境搭建

想法是用docker-compose部署两个服务:dbbackend。分别对应MySQL数据库和我们的Golang后端的项目代码。db服务的容器可以直接从Docker Hub的官方镜像拉取,而backend服务对应的容器则需要我们自己写一个Dockerfile来构建它。

配置docker-compose.yaml

在项目的根目录新建一个文件:docker-compose.yaml

version: '3'

services:
  db:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: rootpassword
      MYSQL_DATABASE: mysql
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_TEST_DATABASE: gotest
    volumes:
      - db_data:/var/lib/mysql
    ports:
      - "3306:3306"
    command: '--default-authentication-plugin=mysql_native_password'

  backend:
    build: .
    volumes:
      - .:/app
    ports:
      - "8080:8080"
    depends_on:
      - db
    environment:
      MYSQL_USER: user
      MYSQL_PASSWORD: password
      MYSQL_HOST: db
      MYSQL_PORT: 3306
    command: ["/app/wait-for-it.sh", "db:3306", "--", "go", "run", "."]

volumes:
  db_data:

可以看到我们在配置文件中定义了上面所说的两个服务dbbackend

我们来简单解释一下。

db 服务

从官方的MySQL镜像拉取,设置了几个环境变量:MYSQL_ROOT_PASSWORDMYSQL_DATABASEMYSQL_USERMYSQL_PASSWORDMYSQL_TEST_DATABASE。用来在容器中创建对应的数据库、用户、密码等等。

然后我们定义了一个volume - db_data,用于持久存储数据库数据。这样即使我们删除了容器,数据也不会丢失。

我们将容器内部的3306端口映射出来,这样我们的后端服务才能访问到数据库。

backend 服务

build . 命令告诉Docker compose去当前目前下查找Dockerfile文件来构建容器。

同时我们也做了一个卷的映射,将当前目录映射到容器内的app文件夹,这样我们在本地开发的时候,任何修改都会同步到容器内部,避免了每次做完一点点修改都要重新build docker compose。

类似地,我们将容器内部的8080端口映射到外部,这样我们才能访问后端服务器。

我们声明了depends_on,告诉docker compose要在backend服务启动之前启动db服务。当然后来我们发现这样也不能确保db服务就能在backend服务启动之前完全初始化,等一下会将解决办法。

我们给backend服务也设置了一些环境变量,用来给Golang程序获取数据库的信息。

最后我们定义了两个启动命令:

  1. /app/wait-for-it.sh db:3306 -- ,因为刚才提到了我们不能保证db服务就能在backend服务启动之前完全初始化,这种情况下我们的后端服务去连接数据库就会报错,然后backend服务就退出了。因此我们利用了一个程序wait-for-it(开源仓库github.com/vishnubob/w…
  2. 等数据库服务完全初始化后,我们就用命令go run .来启动后端服务。

Dockerfile

以上就是我们docker compose配置文件的大致流程。现在我们来看一下Dockerfile

FROM golang:1.20
WORKDIR /app
COPY wait-for-it.sh /app/wait-for-it.sh
RUN chmod +x /app/wait-for-it.sh
COPY . .
CMD ["go", "run", "."]

这个容器基于golang 1.20的镜像,默认的工作路径是/app

然后我们把wait-for-it.sh文件拷贝到工作路径下,并且在容器内赋予它可执行的权限。

然后把当前目录(项目根目录)复制到容器内的默认路径,也就是刚才声明的/app下(不确定这步是否必要,因为我们之前在docker compose里面已经映射了这两个目录,但是至少经过测试是可以达到预期的运行效果的)。

最后定义容器的初始运行命令为go run .

启动docker compose并测试

命令:

docker compose up

可选参数:

-d: 在后台运行,不在前台输出运行日志 --build: 强制重新构建容器,不加这个参数就是默认按照上次构建的容器来运行。首次启动的时候会自动构建。

如果一切正常,就可以看到类似这样的命令行输出:

>docker-compose up        
[+] Running 2/0
 ✔ Container dousheng-db-1       Created            0.0s 
 ✔ Container dousheng-backend-1  Created            0.0s 
Attaching to dousheng-backend-1, dousheng-db-1

然后我们就可以进行API的测试了。我一般用两种测试方式。

Postman

用Postman(或者类似的API测试工具)发送HTTP请求到我们的服务器,这里的基础URL就填http://locahost:8080就好了。

比如我尝试发送一个获取视频流的请求:http://locahost:8080/douyin/feed/?latest_time=1693106942567

得到:

dousheng-backend-1  | [GIN-debug] redirecting request 301: /douyin/feed/ --> /douyin/feed/?latest_time=1693106942567
dousheng-backend-1  | [GIN] 2023/08/27 - 04:00:33 | 200 |    1.119112ms |      172.19.0.1 | GET      "/douyin/feed/?latest_time=1693106942567"

抖声APP

因为我们希望最终我们的后端服务器可以正确的处理来自抖声APP的请求,所以使用它来测试我们的后端服务器也是必不可少的。

如果是用安卓手机的同学,可以直接在上面安装官方给的抖声APP的apk包。这种情况下我们要确保我们本机的8080端口是开放给局域网的其它设备的,然后找到我们本机在局域网里的IP地址。假设我们的IP地址是192.168.0.2,那么就在抖声APP的“高级设置”(双击右下角的“我”呼出)中填写BaseUrlhttp://192.168.0.2:8080/。然后就可以正常访问我们的后端了。

如果是非安卓手机用户,或者说觉得开放本地端口的操作比较麻烦,也可以选择在本地电脑上装一个安卓模拟器,在那里面安装抖声APP。这种情况下我们的电脑跟安卓模拟器组成的网络下,我们的电脑的IP地址是什么。Windows电脑用ipconfig命令,MacOS用ip addr show命令。类似地,假设找到的IP地址是172.19.64.1,就在BaseUrl中填写http://172.19.64.1:8080/

后续开发

在后续的开发过程中,每当我们想要测试一下刚才新增的代码改动,只需要先将docker compose停止:

docker compose down

然后再重新运行:

docker compose up

这个过程通常就几秒钟,不用每次都重复build,非常方便。