Saleor 是一个 开源 Headless 电商系统 Saleor,它被用于 电子商务 等场景。Saleor 是现代堆栈上以客户为中心的电子商务。是一个无头的 GraphQL 商务平台,提供超快速、动态、个性化的购物体验。美观的在线商店,任何地方,任何设备。
1、拉取存储库
git clone https://github.com/saleor/saleor-platform.git
2、进入目录
cd saleor-platform
3、Django迁移
docker compose run --rm api python3 manage.py migrate
4、填充数据(可选)
docker compose run --rm api python3 manage.py populatedb
5、创建账户
docker compose run --rm api python3 manage.py createsuperuser
6、运行服务
docker compose up
7、测试
浏览器访问http://IP:9000。
优化目标:需要简化saleor启动,省略后续的命令,直接通过docker compose up一键启动,需要注意的是创建用户那一块需要交互式填写账户密码。
原项目在测试时出现了两个问题:
通过上面的问题,需要修改原来的docker-compose文件:
(1)将访问数据库的URL改为主机IP地址:在dashboard服务的环境变量指定数据库地址
dashboard:
...
environment:
- API_URL=http://192.168.121.14:8000/graphql/
(2)将主机IP地址加入到数据库白名单:在api服务的环境变量加上指定IP地址
api:
...
environment:
...
- ALLOWED_HOSTS=localhost,api,192.168.121.14
(3)查询官方的github页面发现,在填充数据库的时候,加上参数 --createsuperuser 会自动创建一个[email protected]/admin账户
docker compose run --rm api python3 manage.py populatedb --createsuperuser
修改完后,测试登录成功!
首先,按照常规启动流程,在 docker compose up 之前,要进行一个初始化,其中包括数据库迁移、数据填充、创建账户,创建完后删除该容器。因此我的思路是在docker-compose内再加一个init服务,用于初始化,其它服务(除开数据库)都必须等init服务启动完退出,且状态码为0时才启动。
编写init服务:
init:
image: ghcr.io/saleor/saleor:3.21
restart: "no"
depends_on:
db:
condition: service_started
redis:
condition: service_started
env_file:
- common.env
- backend.env
volumes:
- saleor-media:/app/media
command: >
sh -c '
if [ ! -f /app/media/init-completed ]; then
python3 manage.py migrate &&
python3 manage.py populatedb --createsuperuser &&
touch /app/media/init-completed &&
exit 0
else
echo "init already completed" &&
exit 0
fi'
networks:
- saleor-backend-tier
其它服务(除了db和redis)依次添加启动依赖:
api:
...
depends_on:
db:
condition: service_started
redis:
condition: service_started
jaeger:
condition: service_started
init:
condition: service_completed_successfully
...
这里需要注意的是,depends_on的格式需要统一,所以其它三个容器我写上了condition的默认选项。
docker-compose.yml文件内容:
services:
init:
image: ghcr.io/saleor/saleor:3.21
restart: "no"
depends_on:
db:
condition: service_started
redis:
condition: service_started
env_file:
- common.env
- backend.env
volumes:
- saleor-media:/app/media
command: >
sh -c '
if [ ! -f /app/media/init-completed ]; then
python3 manage.py migrate &&
python3 manage.py populatedb --createsuperuser &&
touch /app/media/init-completed &&
exit 0
else
echo "init already completed" &&
exit 0
fi'
networks:
- saleor-backend-tier
api:
image: ghcr.io/saleor/saleor:3.21
ports:
- 8000:8000
restart: unless-stopped
networks:
- saleor-backend-tier
stdin_open: true
tty: true
depends_on:
db:
condition: service_started
redis:
condition: service_started
jaeger:
condition: service_started
init:
condition: service_completed_successfully
volumes:
# shared volume between worker and api for media
- saleor-media:/app/media
env_file:
- common.env
- backend.env
environment:
- DASHBOARD_URL=http://localhost:9000/
- ALLOWED_HOSTS=localhost,api,*
dashboard:
image: ghcr.io/saleor/saleor-dashboard:latest
ports:
- 9000:80
restart: unless-stopped
depends_on:
init:
condition: service_completed_successfully
environment:
- API_URL=http://192.168.121.14:8000/graphql/
db:
image: library/postgres:15-alpine
restart: unless-stopped
networks:
- saleor-backend-tier
volumes:
- saleor-db:/var/lib/postgresql/data
- ./replica_user.sql:/docker-entrypoint-initdb.d/replica_user.sql:ro,z
environment:
- POSTGRES_USER=saleor
- POSTGRES_PASSWORD=saleor
redis:
image: library/redis:7.0-alpine
restart: unless-stopped
networks:
- saleor-backend-tier
volumes:
- saleor-redis:/data
worker:
image: ghcr.io/saleor/saleor:3.21
command: celery -A saleor --app=saleor.celeryconf:app worker --loglevel=info -B
restart: unless-stopped
networks:
- saleor-backend-tier
env_file:
- common.env
- backend.env
depends_on:
redis:
condition: service_started
mailpit:
condition: service_started
init:
condition: service_completed_successfully
volumes:
# shared volume between worker and api for media
- saleor-media:/app/media
jaeger:
image: jaegertracing/jaeger
ports:
- "16686:16686"
- "4317:4317"
- "4318:4318"
restart: unless-stopped
depends_on:
init:
condition: service_completed_successfully
networks:
- saleor-backend-tier
volumes:
- type: tmpfs
target: /tmp
mailpit:
image: axllent/mailpit
ports:
- 1025:1025 # smtp server
- 8025:8025 # web ui. Visit http://localhost:8025/ to check emails
restart: unless-stopped
depends_on:
init:
condition: service_completed_successfully
networks:
- saleor-backend-tier
volumes:
saleor-db:
driver: local
saleor-redis:
driver: local
saleor-media:
networks:
saleor-backend-tier:
driver: bridge
[root@openEuler-4 saleor-platform]# docker compose up -d
...
[root@openEuler-4 saleor-platform]# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
saleor-platform-api-1 ghcr.io/saleor/saleor:3.21 "uvicorn saleor.asgi…" api About an hour ago Up About an hour 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp
saleor-platform-dashboard-1 ghcr.io/saleor/saleor-dashboard:latest "/docker-entrypoint.…" dashboard About an hour ago Up About an hour 0.0.0.0:9000->80/tcp, :::9000->80/tcp
saleor-platform-db-1 library/postgres:15-alpine "docker-entrypoint.s…" db About an hour ago Up About an hour 5432/tcp
saleor-platform-jaeger-1 jaegertracing/jaeger "/cmd/jaeger/jaeger-…" jaeger About an hour ago Up About an hour 5778-5779/tcp, 9411/tcp, 13132-13133/tcp, 14250/tcp, 0.0.0.0:4317-4318->4317-4318/tcp, :::4317-4318->4317-4318/tcp, 0.0.0.0:16686->16686/tcp, :::16686->16686/tcp, 14268/tcp
saleor-platform-mailpit-1 axllent/mailpit "/mailpit" mailpit About an hour ago Up About an hour (healthy) 0.0.0.0:1025->1025/tcp, :::1025->1025/tcp, 0.0.0.0:8025->8025/tcp, :::8025->8025/tcp, 1110/tcp
saleor-platform-redis-1 library/redis:7.0-alpine "docker-entrypoint.s…" redis About an hour ago Up About an hour 6379/tcp
saleor-platform-worker-1 ghcr.io/saleor/saleor:3.21 "celery -A saleor --…" worker About an hour ago Up About an hour 8000/tcp
其中初始化部分等待时间比较久。
再次重启服务:
[root@openEuler-4 saleor-platform]# docker compose down
[+] Running 10/10
✔ Container saleor-platform-worker-1 Removed 7.3s
✔ Container saleor-platform-api-1 Removed 6.6s
✔ Container saleor-platform-dashboard-1 Removed 1.9s
✔ Container saleor-platform-jaeger-1 Removed 1.0s
✔ Container saleor-platform-mailpit-1 Removed 0.9s
✔ Container saleor-platform-init-1 Removed 0.0s
✔ Container saleor-platform-db-1 Removed 0.6s
✔ Container saleor-platform-redis-1 Removed 0.6s
✔ Network saleor-platform_default Removed 0.1s
✔ Network saleor-platform_saleor-backend-tier Removed 0.3s
[root@openEuler-4 saleor-platform]# docker compose up -d
[+] Running 10/10
✔ Network saleor-platform_default Created 0.2s
✔ Network saleor-platform_saleor-backend-tier Created 0.2s
✔ Container saleor-platform-redis-1 Started 1.5s
✔ Container saleor-platform-db-1 Started 1.5s
✔ Container saleor-platform-init-1 Exited 4.2s
✔ Container saleor-platform-dashboard-1 Started 3.3s
✔ Container saleor-platform-jaeger-1 Started 3.8s
✔ Container saleor-platform-mailpit-1 Started 3.6s
✔ Container saleor-platform-worker-1 Started 4.7s
✔ Container saleor-platform-api-1 Started 4.9s
[root@openEuler-4 saleor-platform]#
可以看到第二次启动时,init服务不再执行脚本了。