feat: We now have daily backups, and somewhat sane environment variable configuration now. No more need to hack around the docker-compose file.
Some checks are pending
CI/CD / build-and-test (push) Waiting to run

This commit is contained in:
Felipe Cotti 2024-12-05 00:46:55 -03:00
parent 2aaad4cf96
commit 8f44b25d44
6 changed files with 73 additions and 44 deletions

3
.gitignore vendored
View file

@ -11,4 +11,5 @@ artifacts/
*.sln.ide
build/docker-compose.yml
build/mongodb/mongodata/
src/Guestbooky/.vs/
src/Guestbooky/.vs/
/build/.env

View file

@ -34,6 +34,7 @@
- [🚀 Deployment ](#-deployment-)
- [Backend](#backend-1)
- [Admin Panel](#admin-panel-1)
- [Backup](#backup)
- [⛏️ Built Using ](#-built-using-)
- [✍️ Authors ](#-authors-)
@ -65,20 +66,7 @@ For running it locally:
- A Cloudflare turnstile secret key for the captcha
- Not forgetting to set up environment variables
You will be able to see in `build/docker-compose.public.yml` that the application makes heavy usage of them.
```
- ASPNETCORE_ENVIRONMENT=Production
- CORS_ORIGINS=https://guestbook.example.com,http://localhost:5008,http://localhost:8080
- ACCESS_USERNAME=user
- ACCESS_PASSWORD=pass
- ACCESS_TOKENKEY=pleaseinsertafairlylargetokenkeyherewillyou
- ACCESS_ISSUER=https://guestbook.example.com/api
- ACCESS_AUDIENCE=https://guestbook.example.com
- CLOUDFLARE_SECRET=0x000000000000000000000000000000000
- MONGODB_CONNECTIONSTRING=mongodb://mongouser:mongopass@mongo:27017/Guestbooky
- MONGODB_DATABASENAME=Guestbooky
- LOG_LEVEL=Debug
```
There's a `.env.template` file with all environment variables used throughout the compose file.
> [!IMPORTANT]
You will need to set them up either by hand or by using your IDE's capabilities. On Visual Studio, that can be done via the Debug Properties of Guestbooky.API.
@ -89,10 +77,10 @@ You will be able to see in `build/docker-compose.public.yml` that the applicatio
|**CLOUDFLARE_SECRET**|The turnstile secret, used in the server portion of the captcha check.|
|**MONGODB_\***|Related to the connection to MongoDB. Yeah.|
|**LOG_\***|Logging.|
|**GUESTBOOKY_**|Related to accessing the main document collection, which uses its own user.|
> [!TIP]
> For local usage of the backend, you can use `docker-compose.local.yml` and edit the fields you need.
> For local usage of the backend, you can use `docker-compose.local.yml` which provides just what you need to run the backend yourself.
### Admin panel
@ -112,12 +100,16 @@ For development, it should be enough to run `vite` in Guestbooky-admin's `src` f
### Backend
Use `docker-compose.public.yml` as a basis. it should create the image for you and start running.
Use `docker-compose.public.yml` as a basis, and remember to have a `.env` file ready. it should create the image for you and start running.
### Admin Panel
In order to create a live version, adjust the **API_URL** path in `Guestbooky-admin/src/environment/constants.js`, and execute `vite build`. The application will be prepared and sent to `src/Guestbooky-admin/dist`. Send to your hosting solution and you should be good.
### Backup
Mongodump is run as a cron job daily. The behavior is customizable in `docker-compose.yml`
## ⛏️ Built Using <a name = "built_using"></a>
- [MongoDB](https://www.mongodb.com/) - Database

View file

@ -5,8 +5,8 @@ services:
container_name: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: mongo
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
volumes:
- ./mongodb/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
- ./mongodb/mongod.conf:/etc/mongod.conf:ro
@ -19,15 +19,15 @@ services:
image: mongo-express
container_name: mongo-express
restart: always
ports:
- 8082:8081
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: mongo
ME_CONFIG_MONGODB_URL: mongodb://root:mongo@mongo:27017/
ME_CONFIG_BASICAUTH: false
ME_CONFIG_MONGODB_ADMINUSERNAME: ${MONGO_INITDB_ROOT_USERNAME}
ME_CONFIG_MONGODB_ADMINPASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
ME_CONFIG_MONGODB_URL: mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@mongo:27017/
ME_CONFIG_BASICAUTH: "true"
depends_on:
- mongo
ports:
- "8082:8081"
volumes:
mongodata:

View file

@ -6,17 +6,17 @@ services:
ports:
- "8080:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- CORS_ORIGINS=https://guestbooky.example.com
- ACCESS_USERNAME=user
- ACCESS_PASSWORD=pass
- ACCESS_TOKENKEY=youbetterbesureyouareusingatokenkey
- ACCESS_ISSUER=https://guestbooky.example.com/api
- ACCESS_AUDIENCE=https://guestbooky.example.com
- CLOUDFLARE_SECRET=0x000000000000000000000000000000000
- MONGODB_CONNECTIONSTRING=mongodb://mongouser:mongopass@mongo:27017/Guestbooky
- MONGODB_DATABASENAME=Guestbooky
- LOG_LEVEL=Debug
ASPNETCORE_ENVIRONMENT: Production
CORS_ORIGINS: ${CORS_ORIGINS}
ACCESS_USERNAME: ${ACCESS_USERNAME}
ACCESS_PASSWORD: ${ACCESS_PASSWORD}
ACCESS_TOKENKEY: ${ACCESS_TOKENKEY}
ACCESS_ISSUER: ${ACCESS_ISSUER}
ACCESS_AUDIENCE: ${ACCESS_AUDIENCE}
CLOUDFLARE_SECRET: ${CLOUDFLARE_SECRET}
MONGODB_CONNECTIONSTRING: mongodb://${GUESTBOOKY_USER}:${GUESTBOOKY_PASSWORD}@mongo:27017/${GUESTBOOKY_DB_NAME}
MONGODB_DATABASENAME: ${GUESTBOOKY_DB_NAME}
LOG_LEVEL: Debug
depends_on:
- mongo
restart: unless-stopped
@ -28,8 +28,11 @@ services:
container_name: mongo
restart: always
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: mongo
MONGO_INITDB_ROOT_USERNAME: ${MONGO_INITDB_ROOT_USERNAME}
MONGO_INITDB_ROOT_PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
GUESTBOOKY_DB_NAME: ${GUESTBOOKY_DB_NAME}
GUESTBOOKY_USER: ${GUESTBOOKY_USER}
GUESTBOOKY_PASSWORD: ${GUESTBOOKY_PASSWORD}
volumes:
- ./mongodb/mongo-init.js:/docker-entrypoint-initdb.d/mongo-init.js:ro
- ./mongodb/mongod.conf:/etc/mongod.conf:ro
@ -38,6 +41,37 @@ services:
networks:
- guestbooky
cron:
image: mcuadros/ofelia:latest
container_name: ofelia-cron
command: daemon --docker
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./docker-compose.yml:/etc/docker-compose.yml:ro
labels:
ofelia.job-run.backup: "0 0 * * * docker-compose -f /etc/docker-compose.yml run --rm backup-job"
networks:
- guestbooky
env_file:
- .env
backup-job:
container_name: mongo-backup-job
image: mongo
command: >
bash -c "mongodump
--host mongo
--db ${GUESTBOOKY_DB_NAME}
--username ${GUESTBOOKY_USER}
--password ${GUESTBOOKY_USER}
--authenticationDatabase ${GUESTBOOKY_DB_NAME}
--out /backups/guestbooky_$(date +\%Y-\%m-\%d)"
volumes:
- ./backups:/backups
depends_on:
- mongo
networks:
- guestbooky
volumes:
mongodata:

View file

@ -1,13 +1,13 @@
db = db.getSiblingDB('Guestbooky');
db = db.getSiblingDB(process.env.GUESTBOOKY_DB_NAME);
db.createUser(
{
user: "guestbookyuser",
pwd: "guestbookypassword",
user: process.env.GUESTBOOKY_USER,
pwd: process.env.GUESTBOOKY_PASSWORD,
roles: [
{
role: "readWrite",
db: "Guestbooky"
db: process.env.GUESTBOOKY_DB_NAME
}
]
}

View file

@ -43,4 +43,6 @@ ___
- There isn't much exception handling, except in the API layer. This is on purpose. Another thing that this project could really use, but is left as an exercise, is using a `Maybe<T>/Result<T>/ErrorOr<T>` type.
- Since there is so little that can go wrong with *low-stakes CRUDding*, it is a reasonable trade-off to let the API layer catch and send an internal server error.
- By default, you need to choose between good Cookie-based authentication defaults or REST-friendly authentication via the `Authorization` header. Luckily you can support both with a few small additions - it made more sense to keep *RESTy* as the main method and stick Cookie support to its tail.
- By default, you need to choose between good Cookie-based authentication defaults or REST-friendly authentication via the `Authorization` header. Luckily you can support both with a few small additions - it made more sense to keep *RESTy* as the main method and stick Cookie support to its tail
- I really, REALLY should have done a daily backup mechanism right from the start. And I should have done the `.env`-based variable configuration from the get-go, too.