Compare commits
No commits in common. "main" and "backup-main" have entirely different histories.
main
...
backup-mai
@ -12,7 +12,7 @@ steps:
|
||||
auto_tag: true
|
||||
registry: git.autonomic.zone
|
||||
dockerfile: ./Dockerfile
|
||||
repo: git.autonomic.zone/autonomic-cooperative/nextload
|
||||
repo: git.autonomic.zone/autonomic-cooperative/nextjs
|
||||
|
||||
- name: deploy stack
|
||||
image: git.coopcloud.tech/coop-cloud/stack-ssh-deploy:latest
|
||||
@ -29,4 +29,4 @@ steps:
|
||||
SECRET_MONGO_PASSWORD_VERSION: v1
|
||||
REPOSITORY: "autonomic-cooperative/nextload"
|
||||
depends_on:
|
||||
- publish nextjs container
|
||||
- publish nextjs container
|
@ -44,6 +44,5 @@ ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
COPY docker-entrypoint.sh /docker-entrypoint.sh
|
||||
RUN chmod +x /docker-entrypoint.sh
|
||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||
CMD ["pnpm", "start:standalone"]
|
||||
|
49
Makefile
49
Makefile
@ -1,49 +0,0 @@
|
||||
.PHONY: sync_db
|
||||
|
||||
# Define variables
|
||||
REMOTE_USER=tma
|
||||
REMOTE_SERVER=swarm-demo.autonomic.zone
|
||||
REMOTE_PORT=222
|
||||
REMOTE_CONTAINER_PATH=/data/db/mongodump
|
||||
LOCAL_PATH=/tmp/mongodump
|
||||
LOCAL_DB=test
|
||||
LOCAL_CONTAINER_NAME=nextload-mongo-1
|
||||
REMOTE_VOLUME_NAME = nextload-demo_autonomic_zone_payload_uploads
|
||||
LOCAL_VOLUME_NAME = nextload_payload_uploads
|
||||
ENV_FILE=.env
|
||||
|
||||
include $(ENV_FILE)
|
||||
|
||||
sync_db:
|
||||
@echo "Step 1: Dump the database on production"
|
||||
docker --context swarm-demo.autonomic.zone exec -it $$(docker --context swarm-demo.autonomic.zone ps -q -f name=nextload-demo_autonomic_zone_mongo) \
|
||||
bash -c 'rm -rf $(REMOTE_CONTAINER_PATH) && mongodump -u mongo -p "$$(cat /run/secrets/mongo_password)" -o $(REMOTE_CONTAINER_PATH) && ls -l $(REMOTE_CONTAINER_PATH)'
|
||||
|
||||
@echo "Step 2: Copy the dump from the remote MongoDB container to the local machine"
|
||||
rm -rf $(LOCAL_PATH)
|
||||
mkdir -p $(LOCAL_PATH) # Create the target directory if it doesn't exist
|
||||
ssh -p $(REMOTE_PORT) $(REMOTE_USER)@$(REMOTE_SERVER) \
|
||||
"docker exec $$(docker --context swarm-demo.autonomic.zone ps -q -f name=nextload-demo_autonomic_zone_mongo) \
|
||||
tar -cC $(REMOTE_CONTAINER_PATH) ." | tar -xC $(LOCAL_PATH)
|
||||
|
||||
@echo "Step 3: Copy the dump from local machine to MongoDB container"
|
||||
docker cp $(LOCAL_PATH)/ $(LOCAL_CONTAINER_NAME):/tmp/mongodump
|
||||
|
||||
@echo "Step 4: Drop the existing local database and restore the dump"
|
||||
docker exec -it $(LOCAL_CONTAINER_NAME) mongorestore --drop --username $(MONGO_USER) --password $(MONGO_PASSWORD) --authenticationDatabase admin --db $(LOCAL_DB) /tmp/mongodump/$(LOCAL_DB)
|
||||
|
||||
sync_media:
|
||||
@echo "Step 1: Create a tar archive of the remote Docker volume"
|
||||
rm -rf /tmp/$(REMOTE_VOLUME_NAME)
|
||||
mkdir -p /tmp/$(REMOTE_VOLUME_NAME)
|
||||
ssh -p $(REMOTE_PORT) $(REMOTE_USER)@$(REMOTE_SERVER) \
|
||||
"docker run --rm -v $(REMOTE_VOLUME_NAME):/volume -v /tmp:/backup alpine tar -czf /backup/$(REMOTE_VOLUME_NAME).tar.gz -C /volume ."
|
||||
|
||||
@echo "Step 2: Copy the media from remote volume to local volume"
|
||||
scp -P $(REMOTE_PORT) $(REMOTE_USER)@$(REMOTE_SERVER):/tmp/$(REMOTE_VOLUME_NAME).tar.gz /tmp/$(REMOTE_VOLUME_NAME).tar.gz
|
||||
docker run --rm -v /tmp:/volume -v $(LOCAL_VOLUME_NAME):/backup alpine tar -xzf /volume/$(REMOTE_VOLUME_NAME).tar.gz -C /backup
|
||||
|
||||
@echo "Step 3: Cleanup temporary files"
|
||||
rm /tmp/$(REMOTE_VOLUME_NAME).tar.gz
|
||||
|
||||
@echo "Media synchronization complete."
|
@ -40,4 +40,4 @@ You'll see that Payload requires a few files to be present in your `/app` folder
|
||||
You'll see in the Next.js config that we have a `withPayload` function installed. This function is required for Payload to operate, and it ensures compatibility with packages that Payload needs such as `drizzle-kit`, `sharp`, `pino`, and `mongodb`.
|
||||
|
||||
**Using a TypeScript alias to point to your Payload config**
|
||||
In the `tsconfig.json` within this repo, you'll see that we have `paths` set up to point `@payload-config` to the Payload config, which is located in the root. You can put your config wherever you want. By default, the `page.tsx` files and `route.ts` files within the `/app` folder use this alias. In the future, we might make it optional to use `paths` - and by default, we might just hard-code relative path imports to the config. We would like to hear your feedback on this part. What do you prefer? Use `paths` or just use relative imports?
|
||||
In the `tsconfig.json` within this repo, you'll see that we have `paths` set up to point `@payload-config` to the Payload config, which is located in the root. You can put your config wherever you want. By default, the `page.tsx` files and `route.ts` files within the `/app` folder use this alias. In the future, we might make it optional to use `paths` - and by default, we might just hard-code relative path imports to the config. We would like to hear your feedback on this part. What do you prefer? Use `paths` or just use relative imports?
|
@ -4,7 +4,6 @@ version: "3.8"
|
||||
services:
|
||||
nextjs:
|
||||
image: git.autonomic.zone/autonomic-cooperative/nextload:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- "NAME=${STACK_NAME}"
|
||||
- "PAYLOAD_SECRET_FILE=/run/secrets/payload_secret"
|
||||
@ -20,7 +19,7 @@ services:
|
||||
- mongo_password
|
||||
- payload_secret
|
||||
volumes:
|
||||
- payload_uploads:/prod/.next/standalone/media
|
||||
- payload_uploads:/runner/.next/standalone/.next/media
|
||||
networks:
|
||||
- proxy
|
||||
- internal
|
||||
|
@ -18,7 +18,7 @@ services:
|
||||
- "HOSTNAME=0.0.0.0"
|
||||
- "MONGODB_URI=mongodb://${MONGO_USER}:${MONGO_PASSWORD}@mongo:27017"
|
||||
volumes:
|
||||
- payload_uploads:/base/media
|
||||
- /base/media
|
||||
- ./:/base
|
||||
networks:
|
||||
- internal
|
||||
|
@ -11,7 +11,7 @@ const nextConfig = {
|
||||
HOSTNAME: process.env.HOSTNAME,
|
||||
},
|
||||
// Disable minification & chunking for debugging
|
||||
webpack(config, { dev }) {
|
||||
/* webpack(config, { dev }) {
|
||||
config.optimization.minimize = false
|
||||
config.optimization.splitChunks = {
|
||||
cacheGroups: {
|
||||
@ -20,7 +20,7 @@ const nextConfig = {
|
||||
}
|
||||
config.optimization.runtimeChunk = false
|
||||
return config
|
||||
},
|
||||
}, */
|
||||
}
|
||||
|
||||
export default withPayload(nextConfig)
|
||||
|
@ -37,7 +37,7 @@ export default buildConfig({
|
||||
collections: [Users, Posts, Authors, Media, Pages],
|
||||
admin: {
|
||||
autoLogin: {
|
||||
email: 'admin@nextload.test',
|
||||
email: 'dev@payloadcms.com',
|
||||
password: 'test',
|
||||
prefillOnly: true,
|
||||
},
|
||||
@ -60,14 +60,14 @@ export default buildConfig({
|
||||
async onInit(payload) {
|
||||
const existingUsers = await payload.find({
|
||||
collection: 'users',
|
||||
limit: 2,
|
||||
limit: 1,
|
||||
})
|
||||
|
||||
if (existingUsers.docs.length === 0 || existingUsers.docs.length === 1) {
|
||||
if (existingUsers.docs.length === 0) {
|
||||
await payload.create({
|
||||
collection: 'users',
|
||||
data: {
|
||||
email: 'admin@nextload.test',
|
||||
email: 'dev@payloadcms.com',
|
||||
password: 'test',
|
||||
roles: ['admin'],
|
||||
},
|
||||
|
@ -7,7 +7,8 @@ import { notFound } from 'next/navigation'
|
||||
|
||||
const PreviewCatchAllPage = async ({ params }: { params: { path: string[] } }) => {
|
||||
noStore()
|
||||
const [page] = await Promise.all([
|
||||
const [user, page] = await Promise.all([
|
||||
getCurrentUser(),
|
||||
getDocument({
|
||||
collection: COLLECTION_SLUG_PAGE,
|
||||
path: params.path,
|
||||
@ -15,8 +16,7 @@ const PreviewCatchAllPage = async ({ params }: { params: { path: string[] } }) =
|
||||
cache: false,
|
||||
}),
|
||||
])
|
||||
if (!page) notFound()
|
||||
|
||||
if (!user || !page) notFound()
|
||||
return <PreviewBlocks initialData={page} locale="" url={process.env.BASE_URL || ''} />
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,8 @@ import PreviewPostPage from '@/components/PreviewPostPage'
|
||||
|
||||
const PreviewCatchAllPage = async ({ params }: { params: { path: string[] } }) => {
|
||||
noStore()
|
||||
const [page] = await Promise.all([
|
||||
const [user, page] = await Promise.all([
|
||||
getCurrentUser(),
|
||||
getDocument({
|
||||
collection: COLLECTION_SLUG_POST,
|
||||
path: params.path,
|
||||
@ -16,7 +17,7 @@ const PreviewCatchAllPage = async ({ params }: { params: { path: string[] } }) =
|
||||
cache: false,
|
||||
}),
|
||||
])
|
||||
if (!page) notFound()
|
||||
if (!user || !page) notFound()
|
||||
|
||||
return <PreviewPostPage initialData={page} locale="" url={process.env.BASE_URL || ''} />
|
||||
}
|
||||
|
@ -2,11 +2,7 @@ import { Access } from 'payload/types'
|
||||
import type { User } from 'types/payload-types'
|
||||
|
||||
export const isAdmin = ({ req: { user } }: any) => {
|
||||
if (!user || !user.roles) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (user.roles?.includes('admin')) {
|
||||
if (user && user.roles?.includes('admin')) {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -14,11 +10,7 @@ export const isAdmin = ({ req: { user } }: any) => {
|
||||
}
|
||||
|
||||
export const isAdminOrCreatedBy = ({ req: { user } }: any) => {
|
||||
if (!user || !user.roles) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (user.roles?.includes('admin')) {
|
||||
if (user && user.role === 'admin') {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -34,27 +26,24 @@ export const isAdminOrCreatedBy = ({ req: { user } }: any) => {
|
||||
}
|
||||
|
||||
export const isAdminOrSelf = ({ req: { user } }: any) => {
|
||||
if (!user || !user.roles) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (user.roles?.includes('admin')) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Non-admin: can only access themselves
|
||||
return {
|
||||
id: {
|
||||
equals: user.id,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const isAdminOrPublished = ({ req: { user } }: any) => {
|
||||
if (user && user.roles) {
|
||||
if (user) {
|
||||
if (user.roles?.includes('admin')) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Non-admin: can only access themselves
|
||||
return {
|
||||
id: {
|
||||
equals: user.id,
|
||||
},
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
export const isAdminOrPublished = ({ req: { user } }: any) => {
|
||||
if (user && user?.role === 'admin') {
|
||||
return true
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -2,11 +2,7 @@ import { Access, FieldAccess } from 'payload/types'
|
||||
import type { User } from 'types/payload-types'
|
||||
|
||||
export const isEditor = ({ req: { user } }: any) => {
|
||||
if (!user || !user.roles) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (user?.roles?.some((role: string) => ['editor', 'admin'].includes(role))) {
|
||||
if (user && user?.roles?.some((role: string) => ['editor', 'admin'].includes(role))) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -2,11 +2,7 @@ import { Access, FieldAccess } from 'payload/types'
|
||||
import type { User } from 'types/payload-types'
|
||||
|
||||
export const isUser = ({ req: { user } }: any) => {
|
||||
if (!user || !user.roles) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (user?.roles?.some((role: string) => ['user', 'editor', 'admin'].includes(role))) {
|
||||
if (user && user?.roles?.some((role: string) => ['user', 'editor', 'admin'].includes(role))) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
14
src/app/my-route/route.ts
Normal file
14
src/app/my-route/route.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { getPayloadHMR } from '@payloadcms/next/utilities'
|
||||
import configPromise from '@payload-config'
|
||||
|
||||
export const GET = async () => {
|
||||
const payload = await getPayloadHMR({
|
||||
config: configPromise,
|
||||
})
|
||||
|
||||
const data = await payload.find({
|
||||
collection: 'users',
|
||||
})
|
||||
|
||||
return Response.json(data)
|
||||
}
|
Loading…
Reference in New Issue
Block a user