嗨:)希望你做得很好!
我尝试在 Postgres docker 容器和 FastAPI 容器之间启用 SSL 通信,但是正如您从标题中可以看出的那样,有些东西不起作用:/
我阅读了文档,据说我已经相应地设置了所有内容。例如:
我创建了根 CA,然后使用根 CA 为 postgres 服务器创建了密钥和签名证书。
我已经以这种方式配置了postgresql.conf文件:
... defaults
# - SSL -
ssl = on
ssl_ca_file = '/var/lib/postgresql/data/root.crt'
ssl_cert_file = '/var/lib/postgresql/data/server.crt'
ssl_key_file = '/var/lib/postgresql/data/server.key'
#ssl_crl_file = ''
#ssl_crl_dir = ''
#ssl_ciphers = 'HIGH:MEDIUM:+3DES:!aNULL' # allowed SSL ciphers
#ssl_prefer_server_ciphers = on
#ssl_ecdh_curve = 'prime256v1'
#ssl_min_protocol_version = 'TLSv1.2'
#ssl_max_protocol_version = ''
#ssl_dh_params_file = ''
#ssl_passphrase_command = ''
#ssl_passphrase_command_supports_reload = off
... defaults
这就是我的树的样子:
.
├── docker-compose.yaml
├── Dockerfile
├── main.py
├── postgresql.conf
├── README.md
├── ssl-client
│ ├── root.crt
│ ├── root.csr
│ ├── root.key
│ ├── server.crt
│ ├── server.csr
│ └── server.key
└── ssl-server
├── pgdata [error opening dir] -> because it is using its own user (999)
├── root.crt
├── root.csr
├── root.key
├── server.crt
├── server.csr
└── server.key
这就是我将所有内容传递到容器的方式:
version: '3.8'
services:
app:
container_name: python-app
build:
context: .
dockerfile: Dockerfile
ports:
- '8000:80'
depends_on:
- postgres
networks:
- postgres-ssl
postgres:
container_name: postgres
image: postgres:latest
environment:
POSTGRES_USER: username
POSTGRES_PASSWORD: password
POSTGRES_DB: database
PGDATA: /var/lib/postgresql/data/pgdata
volumes:
- ./postgresql.conf:/etc/postgresql/postgresql.conf
- ./ssl-server:/var/lib/postgresql/data/
ports:
- '5432:5432'
networks:
- postgres-ssl
networks:
postgres-ssl:
name: postgres-ssl
最后,这是我的 python 代码,尽管这里一切都按预期工作,因为我收到了上面的错误:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from typing import List
app = FastAPI()
DATABASE_URL = "postgresql+psycopg2://username:password@postgres/database?sslmode=require"
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
class Student(Base):
__tablename__ = 'students'
id = Column(Integer, primary_key=True, nullable=False)
name = Column(String, nullable=False)
class StudentRequest(BaseModel):
name: str
class Config:
orm_mode = True
class StudentCreate(BaseModel):
name :str
@app.post("/items/", response_model=StudentRequest)
def create_item(item: StudentCreate):
db = SessionLocal()
db_item = Student(**item.dict())
db.add(db_item)
db.commit()
db.refresh(db_item)
db.close()
return db_item
@app.get("/items/", response_model=List[StudentRequest])
def get_items():
db = SessionLocal()
items = db.query(Student).all()
db.close()
return items
@app.get("/")
async def read_root():
return {"message": "Hello, FastAPI with PostgreSQL using SSL!"}
我在这里遗漏了什么吗?为什么这没有设置 SSL 连接? :/
老实说我很困惑,如果你能在这里帮助我,我将非常非常感激!
预先感谢您,祝您有美好的一天!
如果 PGDATA 设置为 /var/lib/postgresql/data/pgdata,那么将自定义配置文件放入 /etc/postgresql/ 不会执行任何操作。它会忽略它并使用默认值。
此外,证书和其他内容需要位于 PGDATA 内部,而不是它的兄弟姐妹。